updated plugin `WP Mail SMTP` version 2.0.0

This commit is contained in:
KawaiiPunk 2020-05-04 15:57:12 +00:00 committed by Gitium
parent 6a7ce488aa
commit 57b2d39b8f
321 changed files with 18242 additions and 5880 deletions

File diff suppressed because one or more lines are too long

View File

@ -1 +1 @@
<svg viewBox="0 0 37 28" xmlns="http://www.w3.org/2000/svg" fill-rule="evenodd" clip-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="1.414"><path d="M12.29 26.462c.328.375.75.562 1.266.562s.937-.187 1.266-.562L35.563 5.79c.329-.328.493-.75.493-1.265 0-.516-.164-.938-.493-1.266L32.962.728a1.567 1.567 0 0 0-1.23-.563c-.493 0-.926.188-1.301.563L13.556 17.603 5.681 9.728c-.375-.375-.808-.563-1.301-.563-.492 0-.902.188-1.23.563L.548 12.259c-.328.328-.492.75-.492 1.265 0 .516.164.938.492 1.266L12.29 26.462z" fill="#6ab255" fill-rule="nonzero"/></svg> <svg viewBox="0 0 37 28" xmlns="http://www.w3.org/2000/svg" fill-rule="evenodd" clip-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="1.414"><path d="M12.29 26.462c.328.375.75.562 1.266.562s.937-.187 1.266-.562L35.563 5.79c.329-.328.493-.75.493-1.265 0-.516-.164-.938-.493-1.266L32.962.728a1.567 1.567 0 00-1.23-.563c-.493 0-.926.188-1.301.563L13.556 17.603 5.681 9.728c-.375-.375-.808-.563-1.301-.563-.492 0-.902.188-1.23.563L.548 12.259c-.328.328-.492.75-.492 1.265 0 .516.164.938.492 1.266L12.29 26.462z" fill="#6ab255" fill-rule="nonzero"/></svg>

Before

Width:  |  Height:  |  Size: 560 B

After

Width:  |  Height:  |  Size: 559 B

View File

@ -1 +1 @@
<svg viewBox="0 0 33 33" xmlns="http://www.w3.org/2000/svg" fill-rule="evenodd" clip-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="1.414"><path d="M27.592 32.359a1.928 1.928 0 0 1-1.417.583 1.928 1.928 0 0 1-1.416-.583l-8.084-8.084-8.083 8.084a1.928 1.928 0 0 1-1.417.583 1.93 1.93 0 0 1-1.417-.583l-4.5-4.5a1.932 1.932 0 0 1-.583-1.417c0-.555.195-1.028.583-1.417l8.084-8.083-8.084-8.084a1.931 1.931 0 0 1-.583-1.416c0-.556.195-1.028.583-1.417l4.5-4.5A1.93 1.93 0 0 1 7.175.942c.556 0 1.028.194 1.417.583l8.083 8.083 8.084-8.083a1.928 1.928 0 0 1 1.416-.583c.556 0 1.028.194 1.417.583l4.5 4.5c.389.389.583.861.583 1.417 0 .555-.194 1.027-.583 1.416l-8.083 8.084 8.083 8.083c.389.389.583.862.583 1.417 0 .556-.194 1.028-.583 1.417l-4.5 4.5z" fill="#d83638" fill-rule="nonzero"/></svg> <svg viewBox="0 0 33 33" xmlns="http://www.w3.org/2000/svg" fill-rule="evenodd" clip-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="1.414"><path d="M27.592 32.359a1.928 1.928 0 01-1.417.583 1.928 1.928 0 01-1.416-.583l-8.084-8.084-8.083 8.084a1.928 1.928 0 01-1.417.583 1.93 1.93 0 01-1.417-.583l-4.5-4.5a1.932 1.932 0 01-.583-1.417c0-.555.195-1.028.583-1.417l8.084-8.083-8.084-8.084a1.931 1.931 0 01-.583-1.416c0-.556.195-1.028.583-1.417l4.5-4.5A1.93 1.93 0 017.175.942c.556 0 1.028.194 1.417.583l8.083 8.083 8.084-8.083a1.928 1.928 0 011.416-.583c.556 0 1.028.194 1.417.583l4.5 4.5c.389.389.583.861.583 1.417 0 .555-.194 1.027-.583 1.416l-8.083 8.084 8.083 8.083c.389.389.583.862.583 1.417 0 .556-.194 1.028-.583 1.417l-4.5 4.5z" fill="#d83638" fill-rule="nonzero"/></svg>

Before

Width:  |  Height:  |  Size: 795 B

After

Width:  |  Height:  |  Size: 785 B

View File

@ -1 +1 @@
<svg viewBox="0 0 53 53" xmlns="http://www.w3.org/2000/svg" fill-rule="evenodd" clip-rule="evenodd" stroke-miterlimit="10"><path d="M37.592 42.359a1.928 1.928 0 0 1-1.417.583 1.928 1.928 0 0 1-1.416-.583l-8.084-8.084-8.083 8.084a1.928 1.928 0 0 1-1.417.583 1.93 1.93 0 0 1-1.417-.583l-4.5-4.5a1.932 1.932 0 0 1-.583-1.417c0-.556.195-1.028.583-1.417l8.084-8.083-8.084-8.084a1.93 1.93 0 0 1-.583-1.416c0-.556.195-1.028.583-1.417l4.5-4.5a1.93 1.93 0 0 1 1.417-.584 1.93 1.93 0 0 1 1.417.584l8.083 8.083 8.084-8.083a1.928 1.928 0 0 1 1.416-.584 1.93 1.93 0 0 1 1.417.584l4.5 4.5c.389.389.583.861.583 1.417 0 .555-.194 1.028-.583 1.416l-8.083 8.084 8.083 8.083c.389.389.583.861.583 1.417s-.194 1.028-.583 1.417l-4.5 4.5z" fill="none" stroke="#d83638" stroke-width="2" stroke-dasharray="4,2"/></svg> <svg viewBox="0 0 53 53" xmlns="http://www.w3.org/2000/svg" fill-rule="evenodd" clip-rule="evenodd" stroke-miterlimit="10"><path d="M37.592 42.359a1.928 1.928 0 01-1.417.583 1.928 1.928 0 01-1.416-.583l-8.084-8.084-8.083 8.084a1.928 1.928 0 01-1.417.583 1.93 1.93 0 01-1.417-.583l-4.5-4.5a1.932 1.932 0 01-.583-1.417c0-.556.195-1.028.583-1.417l8.084-8.083-8.084-8.084a1.93 1.93 0 01-.583-1.416c0-.556.195-1.028.583-1.417l4.5-4.5a1.93 1.93 0 011.417-.584 1.93 1.93 0 011.417.584l8.083 8.083 8.084-8.083a1.928 1.928 0 011.416-.584 1.93 1.93 0 011.417.584l4.5 4.5c.389.389.583.861.583 1.417 0 .555-.194 1.028-.583 1.416l-8.083 8.084 8.083 8.083c.389.389.583.861.583 1.417s-.194 1.028-.583 1.417l-4.5 4.5z" fill="none" stroke="#d83638" stroke-width="2" stroke-dasharray="4,2"/></svg>

Before

Width:  |  Height:  |  Size: 793 B

After

Width:  |  Height:  |  Size: 779 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.5 KiB

View File

@ -0,0 +1 @@
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" x="0" y="0" viewBox="0 0 232.7 60" xml:space="preserve"><style>.st1{fill:none}.st8,.st9{fill-rule:evenodd;clip-rule:evenodd;fill:#86a196}.st9{fill:#fff}</style><path d="M69.1 21.4l-4.4 12.4h-.1l-1.9-6.6-2-6.1h-3.1v.4l6 17.9h1.7l4.4-11.7h.1l4.4 11.7h1.6l6.1-17.9v-.4h-3.2l-1.9 6.1-1.8 6.5h-.1l-4.3-12.4h-1.5zm18.6 17.9h-3V21.1h7.5c3.4-.1 6.3 2.5 6.4 5.9v.5c.1 3.4-2.6 6.2-6 6.3h-5l.1 5.5zm-.1-8.1h4.6c2 0 3.5-1.6 3.5-3.6v-.2c.1-1.9-1.3-3.6-3.3-3.7h-4.8v7.5zm29-.7l-7.4-9.4h-1.1v18.2h3V27.9l5.3 6.7h.4l5.2-6.7v11.4h3.1V21.1H124l-7.4 9.4zm24.1-2.8v7.9c0 1.1 0 1.9 1.4 1.7v1.9c-1.8.3-3.6.1-3.6-2v-.5c-.7 1.7-2.5 2.8-4.3 2.7-3.8 0-5.7-3.1-5.7-6.6.1-4.2 3.1-6.4 7.1-6.4 1.8.1 3.5.5 5.1 1.3zM138 33v-3.7c-.8-.4-1.7-.5-2.6-.5-2.4 0-4 1.4-4.1 4.1 0 2.3 1.1 4.1 3.4 4.1 2.2 0 3.2-1.7 3.3-4zm6.6-10.1c0 .9.7 1.7 1.6 1.7h.1c.9 0 1.6-.6 1.7-1.5v-.2c-.1-.9-.9-1.6-1.8-1.6-.9.1-1.5.8-1.6 1.6zm3.1 4h-2.8v12.4h2.8V26.9zm3.6-6.6v14.5c0 4.2 1.8 5.2 5.6 4.5l-.1-2.2c-2.1.3-2.7-.3-2.7-2.4V20.3h-2.8zm13.5 13.9c.1 3.8 3.8 5.6 7.4 5.5 3.4 0 7.2-1.5 7.2-5.5 0-4.2-3.4-4.9-7.1-5.3-2.1-.3-4.2-.5-4.2-2.6s2.2-2.7 3.8-2.7 3.9.6 4 2.6h2.9c-.1-3.7-3.4-5.3-6.8-5.3s-6.8 1.8-6.8 5.5 3.3 4.7 6.6 5c2.1.2 4.6.4 4.6 2.8S174 37 172.1 37s-4.2-.8-4.4-2.8h-2.9zm26.4-3.7l-7.4-9.4h-1.1v18.2h3V27.9l5.3 6.7h.4l5.2-6.7v11.4h3V21.1h-1.1l-7.3 9.4zm16.6-6.7v15.5h3V23.8h5.2v-2.7h-13.5v2.7h5.3zm14 15.5h-3V21.1h7.5c3.4-.1 6.3 2.5 6.4 5.9v.5c.1 3.4-2.6 6.2-6 6.3h-5l.1 5.5zm0-8.1h4.6c2 0 3.5-1.6 3.5-3.6v-.2c.1-1.9-1.3-3.6-3.3-3.7h-4.8v7.5z" fill-rule="evenodd" clip-rule="evenodd" fill="#23282c"/><path class="st1" d="M-6.2 0h60v60h-60z"/><path d="M16.7 8.1c-4 2.1-6.9 5.8-7.9 10.2-10 8.3-11.4 23.1-3.1 33.1s23.1 11.4 33.1 3.1 11.4-23.1 3.1-33.1c-.9-1.1-2-2.2-3.1-3.1-1.2-4.9-4.7-9-9.4-10.8-.2-1.2-1-2.2-2.1-2.7C27.2 2.2 25 .3 22.5.4c-1.8.1-3.3 1.1-4 2.8-.8 1.5-1.4 3.2-1.8 4.9z" fill-rule="evenodd" clip-rule="evenodd" fill="#395360"/><path fill="#fbaa6f" d="M18 26h12v14H18z"/><path d="M25.9 33.2l-.1-.1c-.6-.5-.8-1.3-.3-2 .5-.6 1.3-.8 2-.3-.5.1-.9.4-1.2.8-.4.5-.6 1-.4 1.6zm-4.5 0c.1-.5 0-1.1-.4-1.5-.3-.4-.7-.7-1.2-.8.6-.5 1.5-.3 2 .3.4.6.3 1.5-.4 2 0-.1 0 0 0 0zm7.2-3.2h.5L28 34.8l-2.1 6.4h-4.3l-3.2-5.4 1.1-3.2c1.1 1.4 1.8 2.3 2.1 2.7.5.5 2.7.5 3.8-.5 1.2-1.5 2.3-3.1 3.2-4.8z" fill-rule="evenodd" clip-rule="evenodd" fill="#dc7f3c"/><path d="M9.7 29H15v-9h-4.1c.6-4.4 3.5-8.2 7.5-10 .8-3.3 1.7-5.6 2.7-6.8l.2-.2h.1c.3-.2.7-.4 1.1-.5 1.3-.2 2.5.7 2.7 1.9.1.7-.1 1.3-.5 1.8h-.1l-.3.3c-.5.5-.9 1-1.3 1.6.8-.8 1.9-1.4 3-1.5.2 0 .5.1.7.2.6.4.9 1.2.5 1.8l-.6.6c5.4 1.2 9.4 5.6 10.1 11l.1.9H33v8h4.8l1.8 13.4c-4.2 2.6-9.5 3.9-15.9 3.9s-11.5-1.3-15.7-4L9.7 29zm15.2 9.4c2.6-4.3 3.9-6.8 3.9-7.6 0-2.2-3.2-4.1-4.9-4.1S19 28.5 19 30.8c0 .8 1.3 3.4 3.8 7.6.2.4.6.6 1.1.6.4 0 .8-.2 1-.6z" fill-rule="evenodd" clip-rule="evenodd" fill="#bdcfc8"/><path class="st1" d="M19 31.1h9.6l-1.6 16h-6.4z"/><path d="M39.8 48.8c-6.6 8.9-19.1 10.7-28 4.1-1.6-1.2-2.9-2.5-4.1-4.1l.8-6.1c.3.1.7.2 1 .2 1.4 0 2.6-1 2.8-2.4v1.2c0 1.6 1.3 2.8 2.8 2.8s2.8-1.3 2.8-2.8v1.6c.1 1.6 1.4 2.8 3 2.7 1.4-.1 2.6-1.2 2.7-2.7 0 1.6 1.3 2.8 2.8 2.8s2.8-1.3 2.8-2.8v-1.6c0 1.6 1.3 2.8 2.8 2.8s2.8-1.3 2.8-2.8v-1.2C35.3 42 36.5 43 38 43c.3 0 .7-.1 1-.2l.8 6z" fill-rule="evenodd" clip-rule="evenodd" fill="#809eb0"/><path d="M8.3 44.7l.3-1.9c.3.1.7.2 1 .2 1.4 0 2.6-1 2.8-2.4v1.2c0 1.6 1.3 2.8 2.8 2.8s2.8-1.3 2.8-2.8v1.6c.1 1.6 1.4 2.8 3 2.7 1.4-.1 2.6-1.2 2.7-2.7 0 1.6 1.3 2.8 2.8 2.8s2.8-1.3 2.8-2.8v-1.6c0 1.6 1.3 2.8 2.8 2.8s2.8-1.3 2.8-2.8v-1.2C35.3 42 36.5 43 38 43c.3 0 .7-.1 1-.2l.2 1.9c-1.4.7-3.1.1-3.8-1.3-.1-.3-.2-.5-.3-.8v1.2c0 1.6-1.3 2.8-2.8 2.8s-2.8-1.3-2.8-2.8v1.6c0 1.6-1.3 2.8-2.8 2.8s-2.8-1.3-2.8-2.8c-.1 1.6-1.4 2.8-3 2.7-1.4-.1-2.6-1.2-2.7-2.7v-1.7c0 1.6-1.3 2.8-2.8 2.8s-2.8-1.3-2.8-2.8v-1.2C12.3 44 11 45 9.6 45c-.5 0-.9-.1-1.3-.3z" fill-rule="evenodd" clip-rule="evenodd" fill="#738e9e"/><path class="st8" d="M37.8 22.4c-1-2.9-3-4.7-4.7-4.5-2.2.2-2.7 3.8-2.3 8s1.7 7.6 3.9 7.3 4-3.9 3.7-8c-.1 1.2-.5 2.3-1.4 2.4-1.1.1-1.4-1.2-1.6-2.8s-.1-3 1-3.1c.5-.1 1.1.2 1.4.7z"/><path class="st9" d="M37 21.8c-.6-1.2-1.5-2-2.4-1.9-1.5.1-1.9 2.6-1.6 5.5s1.2 5.2 2.7 5c1.1-.1 1.9-1.5 2.2-3.4-.2.3-.5.5-.9.6-1.1.1-1.4-1.2-1.6-2.8s-.1-3 1-3.1c.2 0 .4 0 .6.1z"/><path class="st8" d="M9.6 22.4c1-2.9 3-4.7 4.7-4.5 2.2.2 2.7 3.8 2.3 8s-1.7 7.6-3.9 7.3-4-3.9-3.7-8c.1 1.2.5 2.3 1.4 2.4 1.1.1 1.4-1.2 1.6-2.8s.1-3-1-3.1c-.6-.1-1.1.2-1.4.7z"/><path class="st9" d="M10.4 21.8c.6-1.2 1.5-2 2.4-1.9 1.5.1 1.9 2.6 1.6 5.5s-1.2 5.2-2.7 5c-1.1-.1-1.9-1.5-2.2-3.4.2.3.5.5.9.6 1.1.1 1.4-1.2 1.6-2.8s.1-3-1-3.1c-.2-.1-.5 0-.6.1z"/><path d="M19 28.6v-.7c0-2.5 1.2-5.3 4.9-5.3s4.9 2.8 4.9 5.3c0 .3 0 .7-.1 1-.8-1.4-2.3-2.2-4.8-2.2-2.5.1-4 .8-4.9 1.9z" fill-rule="evenodd" clip-rule="evenodd" fill="#f4f8ff"/><path class="st8" d="M26.5 9.2L23.3 9l3.9-1.2c.1.6-.2 1.1-.7 1.4zM23 8.1l-1.3 1c.8-1.2 1.5-2.4 2-3.7.3-.8.4-1.7.3-2.6.8.4 1.3 1.3 1.2 2.2-.1.6-.3 1.1-.8 1.5-.5.5-1 1.1-1.4 1.6z"/></svg>

After

Width:  |  Height:  |  Size: 4.9 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 68 KiB

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 88 KiB

After

Width:  |  Height:  |  Size: 55 KiB

View File

@ -1 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" fill="#9ea3a8" width="64" height="64" viewBox="0 0 43 34"><path d="M.007 3.585v16.836q0 3.586 3.751 3.585L20 24v-5h10v-4.986l.991-1L34 13V3.585Q34 0 30.249 0H3.758Q.007 0 .007 3.585zm3.517 2.572a1.49 1.49 0 0 1-.508-.935 1.581 1.581 0 0 1 .274-1.208 1.449 1.449 0 0 1 1.094-.663 1.756 1.756 0 0 1 1.25.312l11.409 7.716 11.331-7.716a1.96 1.96 0 0 1 1.289-.312 1.546 1.546 0 0 1 1.094.663 1.4 1.4 0 0 1 .273 1.208 1.67 1.67 0 0 1-.547.935l-13.44 11.068z"/><path d="M22 28h10l-.009 4.624a1.126 1.126 0 0 0 1.922.8l8.25-8.236a1.126 1.126 0 0 0 0-1.594l-8.25-8.241a1.126 1.126 0 0 0-1.922.8v4.866L22 21v7z"/></svg> <svg xmlns="http://www.w3.org/2000/svg" fill="#9ea3a8" width="64" height="64" viewBox="0 0 43 34"><path d="M.007 3.585v16.836q0 3.586 3.751 3.585L20 24v-5h10v-4.986l.991-1L34 13V3.585Q34 0 30.249 0H3.758Q.007 0 .007 3.585zm3.517 2.572a1.49 1.49 0 01-.508-.935 1.581 1.581 0 01.274-1.208 1.449 1.449 0 011.094-.663 1.756 1.756 0 011.25.312l11.409 7.716 11.331-7.716a1.96 1.96 0 011.289-.312 1.546 1.546 0 011.094.663 1.4 1.4 0 01.273 1.208 1.67 1.67 0 01-.547.935l-13.44 11.068z"/><path d="M22 28h10l-.009 4.624a1.126 1.126 0 001.922.8l8.25-8.236a1.126 1.126 0 000-1.594l-8.25-8.241a1.126 1.126 0 00-1.922.8v4.866L22 21v7z"/></svg>

Before

Width:  |  Height:  |  Size: 649 B

After

Width:  |  Height:  |  Size: 630 B

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 6.2 KiB

After

Width:  |  Height:  |  Size: 6.2 KiB

View File

@ -1 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="152" height="80"><path d="M77.5 0C118.645 0 152 17.909 152 40s-33.355 40-74.5 40S0 62.091 0 40 36.355 0 77.5 0z" fill-rule="evenodd" fill="#777bb3"/><path d="M32.331 21.353h15.952q7.023.059 10.178 4.044t2.083 10.884a20.864 20.864 0 0 1-1.844 6.186 18.385 18.385 0 0 1-3.809 5.472 13.3 13.3 0 0 1-6.369 3.925 29.343 29.343 0 0 1-7.022.836h-7.145L32.093 64H23.82l8.511-42.643m6.964 6.78l-3.571 17.839a4.38 4.38 0 0 0 .714.059h.833a31.319 31.319 0 0 0 9.523-1.13q3.809-1.249 5.119-8.683 1.071-6.245-2.143-7.2a26.728 26.728 0 0 0-7.916-.892q-.714.059-1.369.059h-1.25l.06-.059M69.968 9.994h8.214l-2.321 11.36h7.38q6.071.12 9.047 2.5 3.036 2.378 1.786 9.04L90.086 52.7h-8.333l3.809-18.913q.595-2.974-.357-4.223T81.1 28.312l-6.607-.059L69.611 52.7H61.4L69.971 10M102.9 21.353h15.951q7.023.059 10.178 4.044t2.083 10.884a20.861 20.861 0 0 1-1.845 6.185 18.389 18.389 0 0 1-3.809 5.472 13.3 13.3 0 0 1-6.369 3.925 29.341 29.341 0 0 1-7.023.833h-7.143L102.656 64h-8.273l8.517-42.647m6.963 6.78l-3.571 17.842a4.376 4.376 0 0 0 .714.059h.834a31.317 31.317 0 0 0 9.523-1.13q3.809-1.249 5.119-8.683 1.071-6.245-2.143-7.2a26.724 26.724 0 0 0-7.916-.892q-.714.059-1.369.059H109.8l.059-.059" fill="#fff" fill-rule="evenodd"/></svg> <svg xmlns="http://www.w3.org/2000/svg" width="152" height="80"><path d="M77.5 0C118.645 0 152 17.909 152 40s-33.355 40-74.5 40S0 62.091 0 40 36.355 0 77.5 0z" fill-rule="evenodd" fill="#777bb3"/><path d="M32.331 21.353h15.952q7.023.059 10.178 4.044t2.083 10.884a20.864 20.864 0 01-1.844 6.186 18.385 18.385 0 01-3.809 5.472 13.3 13.3 0 01-6.369 3.925 29.343 29.343 0 01-7.022.836h-7.145L32.093 64H23.82l8.511-42.643m6.964 6.78l-3.571 17.839a4.38 4.38 0 00.714.059h.833a31.319 31.319 0 009.523-1.13q3.809-1.249 5.119-8.683 1.071-6.245-2.143-7.2a26.728 26.728 0 00-7.916-.892q-.714.059-1.369.059h-1.25l.06-.059M69.968 9.994h8.214l-2.321 11.36h7.38q6.071.12 9.047 2.5 3.036 2.378 1.786 9.04L90.086 52.7h-8.333l3.809-18.913q.595-2.974-.357-4.223T81.1 28.312l-6.607-.059L69.611 52.7H61.4L69.971 10M102.9 21.353h15.951q7.023.059 10.178 4.044t2.083 10.884a20.861 20.861 0 01-1.845 6.185 18.389 18.389 0 01-3.809 5.472 13.3 13.3 0 01-6.369 3.925 29.341 29.341 0 01-7.023.833h-7.143L102.656 64h-8.273l8.517-42.647m6.963 6.78l-3.571 17.842a4.376 4.376 0 00.714.059h.834a31.317 31.317 0 009.523-1.13q3.809-1.249 5.119-8.683 1.071-6.245-2.143-7.2a26.724 26.724 0 00-7.916-.892q-.714.059-1.369.059H109.8l.059-.059" fill="#fff" fill-rule="evenodd"/></svg>

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 403.52 76.84"><g data-name="Layer 2"><g data-name="Layer 1"><path d="M0 0h105.69v76.64a16.45 16.45 0 01-1.87.2H1.49c-.5 0-1-.07-1.49-.11zm102.57 73.68V4.57l-96 69a11.22 11.22 0 001.25.22h35.2a5.15 5.15 0 002.67-1c4.22-2.94 8.37-6 12.55-9l18.5-13.24L78.52 53 49.81 73.68zM3.19 4.5v67.8l47.39-34.09zM7.5 3.22a6 6 0 00.71.78Q30.1 19.59 52 35.17c1.39 1 2.2.44 3.23-.31L96.8 4.6c.48-.35.89-.77 1.59-1.38zm198.33 22.6v49.81h-15V1.82c.83-.05 1.7-.14 2.57-.14 4.66 0 9.32.09 14-.05a3.6 3.6 0 013.94 2.42c5.66 12.09 11.46 24.12 17.24 36.17.38.78.81 1.53 1.45 2.74.7-1.32 1.18-2.16 1.6-3 5.87-12 11.76-24 17.55-36a3.32 3.32 0 013.55-2.27c5.55.13 11.11.05 16.82.05v74h-15V26.11l-.66-.22c-.4.71-.84 1.4-1.22 2.13-5.43 10.29-10.89 20.56-16.24 30.89a3.14 3.14 0 01-3.44 2c-2.64-.17-5.84.75-7.81-.43s-2.71-4.35-3.94-6.68q-6.87-13-13.7-26.07c-.37-.71-.8-1.39-1.2-2.09zM361.6 75.7h-15.27V1.92a6.68 6.68 0 011.24-.23c10.73.08 21.47.05 32.19.33a28 28 0 018.24 1.7c10.57 3.63 16.21 12.49 15.43 23.84-.69 10.1-7.94 18.11-18.73 20.38a55.82 55.82 0 01-9.4 1c-4.48.17-9 0-13.72 0zm.06-38.19h13.52a22.85 22.85 0 004.2-.44c5.13-1 8.41-5 8.82-10.55.43-5.82-2.39-11-7.36-12.4-6.3-1.83-12.78-.58-19.18-.85zM175.1 5.57c-1.28 4.34-2.5 8.43-3.78 12.76-1.7-.78-3.23-1.5-4.78-2.19a37.39 37.39 0 00-19.67-3.25c-5.5.6-8.76 4-8.57 8.78a7.46 7.46 0 004.56 6.62c3.95 1.87 8.15 3.22 12.19 4.9 5 2.06 10.18 3.73 14.72 6.49 7.78 4.74 10.75 13.14 8.51 21.69a17.84 17.84 0 01-8.47 10.86 30.75 30.75 0 01-13.91 4.34c-11.79.89-23.22-.65-34-5.74-.3-.14-.57-.32-1-.59 1-4.21 2-8.43 3.06-12.94a42.71 42.71 0 0018.7 6.76 77.58 77.58 0 0012.66.24c3.62-.22 6.87-1.67 8-5.61s-.36-7.63-4.31-9.91c-3-1.76-6.48-2.87-9.76-4.23-5.27-2.19-10.74-4-15.78-6.62s-8.92-6.92-10-12.86c-1.5-7.95 1.27-14.28 7.84-18.94a30.51 30.51 0 0116-5.33 59.25 59.25 0 0127.79 4.77zm125.25 7.69h-21.48c0-3.62-.07-7 .09-10.47 0-.4 1.28-1 2-1.06 3.9-.11 7.82-.05 11.73-.05h44.48v11.51h-21.5v62.42h-15.32z"/><path d="M7.5 3.22h90.89c-.7.61-1.11 1-1.59 1.38L55.19 34.86c-1 .75-1.84 1.31-3.23.31Q30.13 19.54 8.21 4a6 6 0 01-.71-.78z" fill="#21b193"/><path d="M361.66 37.51V13.25c6.4.27 12.88-1 19.18.85 5 1.44 7.79 6.58 7.36 12.4-.41 5.54-3.69 9.51-8.82 10.55a22.85 22.85 0 01-4.2.44c-4.47.05-8.93.02-13.52.02z" fill="#fff"/></g></g></svg>

After

Width:  |  Height:  |  Size: 2.3 KiB

View File

@ -1 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="181" height="60"><defs><style>.cls-1{fill:#ccc;fill-rule:evenodd}</style></defs><path id="Rounded_Rectangle_1" data-name="Rounded Rectangle 1" class="cls-1" d="M47.124 46.084h34.292a4.277 4.277 0 1 1 0 8.555H47.124a4.277 4.277 0 1 1 0-8.555z"/><path id="Rounded_Rectangle_1-2" data-name="Rounded Rectangle 1" class="cls-1" d="M25.707 26.777h55.7a4.284 4.284 0 0 1 4.284 4.284v.016a4.284 4.284 0 0 1-4.284 4.284h-55.7a4.284 4.284 0 0 1-4.284-4.284v-.016a4.284 4.284 0 0 1 4.284-4.284z"/><path id="Rounded_Rectangle_1-3" data-name="Rounded Rectangle 1" class="cls-1" d="M4.284 6.416H81.41a4.284 4.284 0 0 1 4.284 4.284v.016A4.284 4.284 0 0 1 81.41 15H4.284A4.284 4.284 0 0 1 0 10.716V10.7a4.284 4.284 0 0 1 4.284-4.284z"/><path id="_" data-name="" d="M178.878 57.783a6.911 6.911 0 0 1-5.186 2.2h-68.954a6.9 6.9 0 0 1-5.186-2.2 7.317 7.317 0 0 1-2.113-5.261V8.516a7.327 7.327 0 0 1 2.113-5.261 6.914 6.914 0 0 1 5.186-2.2h68.954a6.922 6.922 0 0 1 5.186 2.2 7.338 7.338 0 0 1 2.113 5.261v44.005a7.328 7.328 0 0 1-2.113 5.262zm-8.835-49.458l-30.732 24.681L108.58 8.325q-2.693-2.3-4.8-.383a2.672 2.672 0 0 0-.768 2.2 3.334 3.334 0 0 0 .96 1.818l19.976 18.367-19.208 19.9a1.743 1.743 0 0 0-.192 2.487 1.392 1.392 0 0 0 1.249.574 2.532 2.532 0 0 0 1.44-.383l21.512-18.176 10.562 9.371 10.372-9.375L171.2 52.9a2.536 2.536 0 0 0 1.441.383 1.958 1.958 0 0 0 1.44-.574q.96-1.148-.384-2.487l-19.207-19.9 19.971-18.362a4.023 4.023 0 0 0 1.056-1.818 2.274 2.274 0 0 0-.864-2.2q-1.923-1.91-4.61.383z" fill="#819eaf" fill-rule="evenodd"/></svg> <svg xmlns="http://www.w3.org/2000/svg" width="181" height="60"><defs><style>.cls-1{fill:#ccc;fill-rule:evenodd}</style></defs><path id="Rounded_Rectangle_1" data-name="Rounded Rectangle 1" class="cls-1" d="M47.124 46.084h34.292a4.277 4.277 0 110 8.555H47.124a4.277 4.277 0 110-8.555z"/><path id="Rounded_Rectangle_1-2" data-name="Rounded Rectangle 1" class="cls-1" d="M25.707 26.777h55.7a4.284 4.284 0 014.284 4.284v.016a4.284 4.284 0 01-4.284 4.284h-55.7a4.284 4.284 0 01-4.284-4.284v-.016a4.284 4.284 0 014.284-4.284z"/><path id="Rounded_Rectangle_1-3" data-name="Rounded Rectangle 1" class="cls-1" d="M4.284 6.416H81.41a4.284 4.284 0 014.284 4.284v.016A4.284 4.284 0 0181.41 15H4.284A4.284 4.284 0 010 10.716V10.7a4.284 4.284 0 014.284-4.284z"/><path id="_" data-name="" d="M178.878 57.783a6.911 6.911 0 01-5.186 2.2h-68.954a6.9 6.9 0 01-5.186-2.2 7.317 7.317 0 01-2.113-5.261V8.516a7.327 7.327 0 012.113-5.261 6.914 6.914 0 015.186-2.2h68.954a6.922 6.922 0 015.186 2.2 7.338 7.338 0 012.113 5.261v44.005a7.328 7.328 0 01-2.113 5.262zm-8.835-49.458l-30.732 24.681L108.58 8.325q-2.693-2.3-4.8-.383a2.672 2.672 0 00-.768 2.2 3.334 3.334 0 00.96 1.818l19.976 18.367-19.208 19.9a1.743 1.743 0 00-.192 2.487 1.392 1.392 0 001.249.574 2.532 2.532 0 001.44-.383l21.512-18.176 10.562 9.371 10.372-9.375L171.2 52.9a2.536 2.536 0 001.441.383 1.958 1.958 0 001.44-.574q.96-1.148-.384-2.487l-19.207-19.9 19.971-18.362a4.023 4.023 0 001.056-1.818 2.274 2.274 0 00-.864-2.2q-1.923-1.91-4.61.383z" fill="#819eaf" fill-rule="evenodd"/></svg>

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

@ -1 +1 @@
<svg id="recommended_-_orange_overlay" data-name="recommended - orange overlay" xmlns="http://www.w3.org/2000/svg" width="159" height="22"><defs><style>.cls-2{fill:#fff;fill-rule:evenodd}</style></defs><path id="reocmmended_bg" data-name="reocmmended bg" d="M0 0h155a4 4 0 0 1 4 4v18H4a4 4 0 0 1-4-4V0z" fill="#fb963c"/><path id="recommended" class="cls-2" d="M1524.28 1519.89a3.713 3.713 0 0 1 2.55.8 2.721 2.721 0 0 1 .92 2.19 3.405 3.405 0 0 1-.47 1.82 2.434 2.434 0 0 1-1.51 1.08v.03a1.994 1.994 0 0 1 .81.32 1.891 1.891 0 0 1 .49.53 2.042 2.042 0 0 1 .27.7 6.668 6.668 0 0 1 .14.8c.02.28.04.56.05.85a7.893 7.893 0 0 0 .08.85 5.045 5.045 0 0 0 .18.79 1.922 1.922 0 0 0 .36.66h-1.69a.973.973 0 0 1-.22-.48 4.45 4.45 0 0 1-.07-.68q-.015-.375-.03-.81a5.839 5.839 0 0 0-.1-.84c-.04-.28-.1-.55-.16-.8a1.693 1.693 0 0 0-.3-.65 1.437 1.437 0 0 0-.55-.45 2.013 2.013 0 0 0-.89-.17h-3.72v4.88h-1.52v-11.42h5.38zm.32 5.18a2.22 2.22 0 0 0 .84-.31 1.732 1.732 0 0 0 .58-.62 2.176 2.176 0 0 0 .21-1.02 2.043 2.043 0 0 0-.48-1.41 1.968 1.968 0 0 0-1.55-.54h-3.78v3.98h3.17a5.512 5.512 0 0 0 1.01-.08zm13.55-5.18v1.28h-6.37v3.63h5.94v1.28h-5.94v3.95h6.42v1.28h-7.94v-11.42h7.89zm9.19 1.61a3.555 3.555 0 0 0-2.07-.6 3.676 3.676 0 0 0-1.75.38 3.618 3.618 0 0 0-1.2 1.03 4.6 4.6 0 0 0-.7 1.48 7.07 7.07 0 0 0-.22 1.73 7.879 7.879 0 0 0 .22 1.85 4.521 4.521 0 0 0 .7 1.52 3.557 3.557 0 0 0 1.21 1.03 3.717 3.717 0 0 0 1.76.38 3.431 3.431 0 0 0 1.33-.24 3.08 3.08 0 0 0 1.68-1.74 4.308 4.308 0 0 0 .28-1.31h1.52a5.151 5.151 0 0 1-1.48 3.36 4.839 4.839 0 0 1-3.46 1.2 5.428 5.428 0 0 1-2.32-.46 4.576 4.576 0 0 1-1.65-1.25 5.658 5.658 0 0 1-.98-1.89 8.07 8.07 0 0 1-.33-2.34 7.745 7.745 0 0 1 .35-2.34 5.756 5.756 0 0 1 1.03-1.91 4.743 4.743 0 0 1 1.7-1.29 5.389 5.389 0 0 1 2.33-.47 5.8 5.8 0 0 1 1.69.24 4.54 4.54 0 0 1 1.43.7 4.145 4.145 0 0 1 1.04 1.16 4.09 4.09 0 0 1 .54 1.61h-1.52a2.819 2.819 0 0 0-1.13-1.83zm6.16 5.8a4.694 4.694 0 0 0 .7 1.52 3.781 3.781 0 0 0 1.23 1.08 4.228 4.228 0 0 0 3.59 0 3.781 3.781 0 0 0 1.23-1.08 4.694 4.694 0 0 0 .7-1.52 6.4 6.4 0 0 0 0-3.4 4.694 4.694 0 0 0-.7-1.52 3.781 3.781 0 0 0-1.23-1.08 4.228 4.228 0 0 0-3.59 0 3.781 3.781 0 0 0-1.23 1.08 4.694 4.694 0 0 0-.7 1.52 6.4 6.4 0 0 0 0 3.4zm-1.4-3.95a5.6 5.6 0 0 1 1.03-1.91 5.124 5.124 0 0 1 1.71-1.33 6.049 6.049 0 0 1 4.77 0 5.124 5.124 0 0 1 1.71 1.33 5.6 5.6 0 0 1 1.03 1.91 7.407 7.407 0 0 1 0 4.5 5.6 5.6 0 0 1-1.03 1.91 5.1 5.1 0 0 1-1.71 1.32 6.049 6.049 0 0 1-4.77 0 5.1 5.1 0 0 1-1.71-1.32 5.6 5.6 0 0 1-1.03-1.91 7.407 7.407 0 0 1 0-4.5zm14.96-3.46l3.6 9.6 3.62-9.6h2.08v11.42h-1.44v-9.5h-.03l-3.57 9.5h-1.3l-3.56-9.5h-.04v9.5h-1.44v-11.42h2.08zm14.34 0l3.6 9.6 3.62-9.6h2.08v11.42h-1.44v-9.5h-.04l-3.56 9.5h-1.3l-3.57-9.5h-.03v9.5h-1.44v-11.42h2.08zm20.11 0v1.28h-6.37v3.63h5.94v1.28h-5.94v3.95h6.42v1.28h-7.94v-11.42h7.89zm3.89 0l6.02 9.26h.03v-9.26h1.44v11.42h-1.67l-5.96-9.17h-.04v9.17h-1.44v-11.42h1.62zm14.4 10.14a5.574 5.574 0 0 0 .64-.04 3.326 3.326 0 0 0 .82-.19 3.832 3.832 0 0 0 .85-.44 2.832 2.832 0 0 0 .76-.78 4.181 4.181 0 0 0 .55-1.24 6.328 6.328 0 0 0 .22-1.8 7.855 7.855 0 0 0-.2-1.84 3.432 3.432 0 0 0-.66-1.37 2.86 2.86 0 0 0-1.17-.87 4.839 4.839 0 0 0-1.78-.29h-2.56v8.86h2.53zm-.13-10.14a5.738 5.738 0 0 1 4.07 1.34 5.385 5.385 0 0 1 1.42 4.1 9.354 9.354 0 0 1-.32 2.55 4.655 4.655 0 0 1-.99 1.87 4.228 4.228 0 0 1-1.71 1.16 6.842 6.842 0 0 1-2.47.4h-3.92v-11.42h3.92zm15.63 0v1.28h-6.36v3.63h5.93v1.28h-5.93v3.95h6.41v1.28h-7.93v-11.42h7.88zm6.34 10.14a5.574 5.574 0 0 0 .64-.04 3.326 3.326 0 0 0 .82-.19 3.832 3.832 0 0 0 .85-.44 2.832 2.832 0 0 0 .76-.78 4.181 4.181 0 0 0 .55-1.24 6.328 6.328 0 0 0 .22-1.8 7.855 7.855 0 0 0-.2-1.84 3.432 3.432 0 0 0-.66-1.37 2.86 2.86 0 0 0-1.17-.87 4.839 4.839 0 0 0-1.78-.29h-2.56v8.86h2.53zm-.13-10.14a5.738 5.738 0 0 1 4.07 1.34 5.385 5.385 0 0 1 1.42 4.1 9.354 9.354 0 0 1-.32 2.55 4.655 4.655 0 0 1-.99 1.87 4.228 4.228 0 0 1-1.71 1.16 6.842 6.842 0 0 1-2.47.4h-3.92v-11.42h3.92z" transform="translate(-1493 -1514)"/><path id="star" class="cls-2" d="M1504.56 1518.67l-1.78 3.62-4 .58a.872.872 0 0 0-.48 1.49l2.89 2.82-.69 3.98a.875.875 0 0 0 1.27.92l3.58-1.88 3.57 1.88a.877.877 0 0 0 1.27-.92l-.69-3.98 2.89-2.82a.872.872 0 0 0-.48-1.49l-3.99-.58-1.79-3.62a.876.876 0 0 0-1.57 0z" transform="translate(-1493 -1514)"/></svg> <svg id="recommended_-_orange_overlay" data-name="recommended - orange overlay" xmlns="http://www.w3.org/2000/svg" width="159" height="22"><defs><style>.cls-2{fill:#fff;fill-rule:evenodd}</style></defs><path id="reocmmended_bg" data-name="reocmmended bg" d="M0 0h155a4 4 0 014 4v18H4a4 4 0 01-4-4V0z" fill="#fb963c"/><path id="recommended" class="cls-2" d="M1524.28 1519.89a3.713 3.713 0 012.55.8 2.721 2.721 0 01.92 2.19 3.405 3.405 0 01-.47 1.82 2.434 2.434 0 01-1.51 1.08v.03a1.994 1.994 0 01.81.32 1.891 1.891 0 01.49.53 2.042 2.042 0 01.27.7 6.668 6.668 0 01.14.8c.02.28.04.56.05.85a7.893 7.893 0 00.08.85 5.045 5.045 0 00.18.79 1.922 1.922 0 00.36.66h-1.69a.973.973 0 01-.22-.48 4.45 4.45 0 01-.07-.68q-.015-.375-.03-.81a5.839 5.839 0 00-.1-.84c-.04-.28-.1-.55-.16-.8a1.693 1.693 0 00-.3-.65 1.437 1.437 0 00-.55-.45 2.013 2.013 0 00-.89-.17h-3.72v4.88h-1.52v-11.42h5.38zm.32 5.18a2.22 2.22 0 00.84-.31 1.732 1.732 0 00.58-.62 2.176 2.176 0 00.21-1.02 2.043 2.043 0 00-.48-1.41 1.968 1.968 0 00-1.55-.54h-3.78v3.98h3.17a5.512 5.512 0 001.01-.08zm13.55-5.18v1.28h-6.37v3.63h5.94v1.28h-5.94v3.95h6.42v1.28h-7.94v-11.42h7.89zm9.19 1.61a3.555 3.555 0 00-2.07-.6 3.676 3.676 0 00-1.75.38 3.618 3.618 0 00-1.2 1.03 4.6 4.6 0 00-.7 1.48 7.07 7.07 0 00-.22 1.73 7.879 7.879 0 00.22 1.85 4.521 4.521 0 00.7 1.52 3.557 3.557 0 001.21 1.03 3.717 3.717 0 001.76.38 3.431 3.431 0 001.33-.24 3.08 3.08 0 001.68-1.74 4.308 4.308 0 00.28-1.31h1.52a5.151 5.151 0 01-1.48 3.36 4.839 4.839 0 01-3.46 1.2 5.428 5.428 0 01-2.32-.46 4.576 4.576 0 01-1.65-1.25 5.658 5.658 0 01-.98-1.89 8.07 8.07 0 01-.33-2.34 7.745 7.745 0 01.35-2.34 5.756 5.756 0 011.03-1.91 4.743 4.743 0 011.7-1.29 5.389 5.389 0 012.33-.47 5.8 5.8 0 011.69.24 4.54 4.54 0 011.43.7 4.145 4.145 0 011.04 1.16 4.09 4.09 0 01.54 1.61h-1.52a2.819 2.819 0 00-1.13-1.83zm6.16 5.8a4.694 4.694 0 00.7 1.52 3.781 3.781 0 001.23 1.08 4.228 4.228 0 003.59 0 3.781 3.781 0 001.23-1.08 4.694 4.694 0 00.7-1.52 6.4 6.4 0 000-3.4 4.694 4.694 0 00-.7-1.52 3.781 3.781 0 00-1.23-1.08 4.228 4.228 0 00-3.59 0 3.781 3.781 0 00-1.23 1.08 4.694 4.694 0 00-.7 1.52 6.4 6.4 0 000 3.4zm-1.4-3.95a5.6 5.6 0 011.03-1.91 5.124 5.124 0 011.71-1.33 6.049 6.049 0 014.77 0 5.124 5.124 0 011.71 1.33 5.6 5.6 0 011.03 1.91 7.407 7.407 0 010 4.5 5.6 5.6 0 01-1.03 1.91 5.1 5.1 0 01-1.71 1.32 6.049 6.049 0 01-4.77 0 5.1 5.1 0 01-1.71-1.32 5.6 5.6 0 01-1.03-1.91 7.407 7.407 0 010-4.5zm14.96-3.46l3.6 9.6 3.62-9.6h2.08v11.42h-1.44v-9.5h-.03l-3.57 9.5h-1.3l-3.56-9.5h-.04v9.5h-1.44v-11.42h2.08zm14.34 0l3.6 9.6 3.62-9.6h2.08v11.42h-1.44v-9.5h-.04l-3.56 9.5h-1.3l-3.57-9.5h-.03v9.5h-1.44v-11.42h2.08zm20.11 0v1.28h-6.37v3.63h5.94v1.28h-5.94v3.95h6.42v1.28h-7.94v-11.42h7.89zm3.89 0l6.02 9.26h.03v-9.26h1.44v11.42h-1.67l-5.96-9.17h-.04v9.17h-1.44v-11.42h1.62zm14.4 10.14a5.574 5.574 0 00.64-.04 3.326 3.326 0 00.82-.19 3.832 3.832 0 00.85-.44 2.832 2.832 0 00.76-.78 4.181 4.181 0 00.55-1.24 6.328 6.328 0 00.22-1.8 7.855 7.855 0 00-.2-1.84 3.432 3.432 0 00-.66-1.37 2.86 2.86 0 00-1.17-.87 4.839 4.839 0 00-1.78-.29h-2.56v8.86h2.53zm-.13-10.14a5.738 5.738 0 014.07 1.34 5.385 5.385 0 011.42 4.1 9.354 9.354 0 01-.32 2.55 4.655 4.655 0 01-.99 1.87 4.228 4.228 0 01-1.71 1.16 6.842 6.842 0 01-2.47.4h-3.92v-11.42h3.92zm15.63 0v1.28h-6.36v3.63h5.93v1.28h-5.93v3.95h6.41v1.28h-7.93v-11.42h7.88zm6.34 10.14a5.574 5.574 0 00.64-.04 3.326 3.326 0 00.82-.19 3.832 3.832 0 00.85-.44 2.832 2.832 0 00.76-.78 4.181 4.181 0 00.55-1.24 6.328 6.328 0 00.22-1.8 7.855 7.855 0 00-.2-1.84 3.432 3.432 0 00-.66-1.37 2.86 2.86 0 00-1.17-.87 4.839 4.839 0 00-1.78-.29h-2.56v8.86h2.53zm-.13-10.14a5.738 5.738 0 014.07 1.34 5.385 5.385 0 011.42 4.1 9.354 9.354 0 01-.32 2.55 4.655 4.655 0 01-.99 1.87 4.228 4.228 0 01-1.71 1.16 6.842 6.842 0 01-2.47.4h-3.92v-11.42h3.92z" transform="translate(-1493 -1514)"/><path id="star" class="cls-2" d="M1504.56 1518.67l-1.78 3.62-4 .58a.872.872 0 00-.48 1.49l2.89 2.82-.69 3.98a.875.875 0 001.27.92l3.58-1.88 3.57 1.88a.877.877 0 001.27-.92l-.69-3.98 2.89-2.82a.872.872 0 00-.48-1.49l-3.99-.58-1.79-3.62a.876.876 0 00-1.57 0z" transform="translate(-1493 -1514)"/></svg>

Before

Width:  |  Height:  |  Size: 4.2 KiB

After

Width:  |  Height:  |  Size: 4.0 KiB

View File

@ -1 +0,0 @@
!function(t){"use strict";"function"==typeof define&&define.amd?define(["jquery"],t):"undefined"!=typeof module&&module.exports?module.exports=t(require("jquery")):t(jQuery)}(function(l){function h(t){return parseFloat(t)||0}function c(t){var e=l(t),n=null,a=[];return e.each(function(){var t=l(this),e=t.offset().top-h(t.css("margin-top")),o=0<a.length?a[a.length-1]:null;null===o?a.push(t):Math.floor(Math.abs(n-e))<=1?a[a.length-1]=o.add(t):a.push(t),n=e}),a}function p(t){var e={byRow:!0,property:"height",target:null,remove:!1};return"object"==typeof t?l.extend(e,t):("boolean"==typeof t?e.byRow=t:"remove"===t&&(e.remove=!0),e)}var n=-1,a=-1,u=l.fn.matchHeight=function(t){var e=p(t);if(e.remove){var o=this;return this.css(e.property,""),l.each(u._groups,function(t,e){e.elements=e.elements.not(o)}),this}return this.length<=1&&!e.target||(u._groups.push({elements:this,options:e}),u._apply(this,e)),this};u.version="0.7.2",u._groups=[],u._throttle=80,u._maintainScroll=!1,u._beforeUpdate=null,u._afterUpdate=null,u._rows=c,u._parse=h,u._parseOptions=p,u._apply=function(t,e){var i=p(e),o=l(t),n=[o],a=l(window).scrollTop(),r=l("html").outerHeight(!0),s=o.parents().filter(":hidden");return s.each(function(){var t=l(this);t.data("style-cache",t.attr("style"))}),s.css("display","block"),i.byRow&&!i.target&&(o.each(function(){var t=l(this),e=t.css("display");"inline-block"!==e&&"flex"!==e&&"inline-flex"!==e&&(e="block"),t.data("style-cache",t.attr("style")),t.css({display:e,"padding-top":"0","padding-bottom":"0","margin-top":"0","margin-bottom":"0","border-top-width":"0","border-bottom-width":"0",height:"100px",overflow:"hidden"})}),n=c(o),o.each(function(){var t=l(this);t.attr("style",t.data("style-cache")||"")})),l.each(n,function(t,e){var o=l(e),a=0;if(i.target)a=i.target.outerHeight(!1);else{if(i.byRow&&o.length<=1)return void o.css(i.property,"");o.each(function(){var t=l(this),e=t.attr("style"),o=t.css("display");"inline-block"!==o&&"flex"!==o&&"inline-flex"!==o&&(o="block");var n={display:o};n[i.property]="",t.css(n),t.outerHeight(!1)>a&&(a=t.outerHeight(!1)),e?t.attr("style",e):t.css("display","")})}o.each(function(){var t=l(this),e=0;i.target&&t.is(i.target)||("border-box"!==t.css("box-sizing")&&(e+=h(t.css("border-top-width"))+h(t.css("border-bottom-width")),e+=h(t.css("padding-top"))+h(t.css("padding-bottom"))),t.css(i.property,a-e+"px"))})}),s.each(function(){var t=l(this);t.attr("style",t.data("style-cache")||null)}),u._maintainScroll&&l(window).scrollTop(a/r*l("html").outerHeight(!0)),this},u._applyDataApi=function(){var o={};l("[data-match-height], [data-mh]").each(function(){var t=l(this),e=t.attr("data-mh")||t.attr("data-match-height");o[e]=e in o?o[e].add(t):t}),l.each(o,function(){this.matchHeight(!0)})};function i(t){u._beforeUpdate&&u._beforeUpdate(t,u._groups),l.each(u._groups,function(){u._apply(this.elements,this.options)}),u._afterUpdate&&u._afterUpdate(t,u._groups)}u._update=function(t,e){if(e&&"resize"===e.type){var o=l(window).width();if(o===n)return;n=o}t?-1===a&&(a=setTimeout(function(){i(e),a=-1},u._throttle)):i(e)},l(u._applyDataApi);var t=l.fn.on?"on":"bind";l(window)[t]("load",function(t){u._update(!1,t)}),l(window)[t]("resize orientationchange",function(t){u._update(!0,t)})});

View File

@ -1,4 +1,6 @@
/* global WPMailSMTP, jQuery, wp_mail_smtp_about */ /* eslint-disable no-prototype-builtins */
/* global wp_mail_smtp_about */
'use strict';
var WPMailSMTP = window.WPMailSMTP || {}; var WPMailSMTP = window.WPMailSMTP || {};
WPMailSMTP.Admin = WPMailSMTP.Admin || {}; WPMailSMTP.Admin = WPMailSMTP.Admin || {};
@ -8,25 +10,14 @@ WPMailSMTP.Admin = WPMailSMTP.Admin || {};
* *
* @since 1.5.0 * @since 1.5.0
*/ */
WPMailSMTP.Admin.About = WPMailSMTP.Admin.About || (function ( document, window, $ ) { WPMailSMTP.Admin.About = WPMailSMTP.Admin.About || ( function( document, window, $ ) {
'use strict';
/**
* Private functions and properties.
*
* @since 1.5.0
*
* @type {Object}
*/
var __private = {};
/** /**
* Public functions and properties. * Public functions and properties.
* *
* @since 1.5.0 * @since 1.5.0
* *
* @type {Object} * @type {object}
*/ */
var app = { var app = {
@ -35,7 +26,7 @@ WPMailSMTP.Admin.About = WPMailSMTP.Admin.About || (function ( document, window,
* *
* @since 1.5.0 * @since 1.5.0
*/ */
init: function () { init: function() {
// Do that when DOM is ready. // Do that when DOM is ready.
$( document ).ready( app.ready ); $( document ).ready( app.ready );
@ -46,7 +37,7 @@ WPMailSMTP.Admin.About = WPMailSMTP.Admin.About || (function ( document, window,
* *
* @since 1.5.0 * @since 1.5.0
*/ */
ready: function () { ready: function() {
app.pageHolder = $( '.wp-mail-smtp-page-about' ); app.pageHolder = $( '.wp-mail-smtp-page-about' );
@ -60,12 +51,12 @@ WPMailSMTP.Admin.About = WPMailSMTP.Admin.About || (function ( document, window,
* *
* @since 1.5.0 * @since 1.5.0
*/ */
bindActions: function () { bindActions: function() {
/* /*
* Make plugins description the same height. * Make plugins description the same height.
*/ */
jQuery('.wp-mail-smtp-admin-about-plugins .plugin-item .details').matchHeight(); jQuery( '.wp-mail-smtp-admin-about-plugins .plugin-item .details' ).matchHeight();
/* /*
* Install/Active the plugins. * Install/Active the plugins.
@ -85,27 +76,26 @@ WPMailSMTP.Admin.About = WPMailSMTP.Admin.About || (function ( document, window,
cssClass, cssClass,
statusText, statusText,
buttonText, buttonText,
errorText,
successText; successText;
$btn.addClass( 'loading disabled' ); $btn.addClass( 'loading disabled' );
$btn.text( wp_mail_smtp_about.plugin_processing ); $btn.text( wp_mail_smtp_about.plugin_processing );
if ( $btn.hasClass( 'status-inactive' ) ) { if ( $btn.hasClass( 'status-inactive' ) ) {
// Activate. // Activate.
task = 'about_plugin_activate'; task = 'about_plugin_activate';
cssClass = 'status-active button button-secondary disabled'; cssClass = 'status-active button button-secondary disabled';
statusText = wp_mail_smtp_about.plugin_active; statusText = wp_mail_smtp_about.plugin_active;
buttonText = wp_mail_smtp_about.plugin_activated; buttonText = wp_mail_smtp_about.plugin_activated;
errorText = wp_mail_smtp_about.plugin_activate;
} else if ( $btn.hasClass( 'status-download' ) ) { } else if ( $btn.hasClass( 'status-download' ) ) {
// Install & Activate. // Install & Activate.
task = 'about_plugin_install'; task = 'about_plugin_install';
cssClass = 'status-active button disabled'; cssClass = 'status-active button disabled';
statusText = wp_mail_smtp_about.plugin_active; statusText = wp_mail_smtp_about.plugin_active;
buttonText = wp_mail_smtp_about.plugin_activated; buttonText = wp_mail_smtp_about.plugin_activated;
errorText = wp_mail_smtp_about.plugin_activate;
} else { } else {
return; return;
@ -120,10 +110,10 @@ WPMailSMTP.Admin.About = WPMailSMTP.Admin.About || (function ( document, window,
}; };
$.post( wp_mail_smtp_about.ajax_url, data, function( res ) { $.post( wp_mail_smtp_about.ajax_url, data, function( res ) {
var is_install_successful; var isInstallSuccessful;
if ( res.success ) { if ( res.success ) {
is_install_successful = true; isInstallSuccessful = true;
if ( 'about_plugin_install' === task ) { if ( 'about_plugin_install' === task ) {
$btn.attr( 'data-plugin', res.data.basename ); $btn.attr( 'data-plugin', res.data.basename );
successText = res.data.msg; successText = res.data.msg;
@ -135,18 +125,18 @@ WPMailSMTP.Admin.About = WPMailSMTP.Admin.About || (function ( document, window,
} else { } else {
successText = res.data; successText = res.data;
} }
$plugin.find( '.actions' ).append( '<div class="msg success">'+successText+'</div>' ); $plugin.find( '.actions' ).append( '<div class="msg success">' + successText + '</div>' );
$plugin.find( 'span.status-label' ) $plugin.find( 'span.status-label' )
.removeClass( 'status-active status-inactive status-download' ) .removeClass( 'status-active status-inactive status-download' )
.addClass( cssClass ) .addClass( cssClass )
.removeClass( 'button button-primary button-secondary disabled' ) .removeClass( 'button button-primary button-secondary disabled' )
.text( statusText ); .text( statusText );
$btn $btn
.removeClass( 'status-active status-inactive status-download' ) .removeClass( 'status-active status-inactive status-download' )
.removeClass( 'button button-primary button-secondary disabled' ) .removeClass( 'button button-primary button-secondary disabled' )
.addClass( cssClass ).html( buttonText ); .addClass( cssClass ).html( buttonText );
} else { } else {
is_install_successful = false; isInstallSuccessful = false;
if ( if (
res.hasOwnProperty( 'data' ) && res.hasOwnProperty( 'data' ) &&
@ -154,10 +144,11 @@ WPMailSMTP.Admin.About = WPMailSMTP.Admin.About || (function ( document, window,
res.data[ 0 ].hasOwnProperty( 'code' ) && res.data[ 0 ].hasOwnProperty( 'code' ) &&
res.data[ 0 ].code === 'download_failed' res.data[ 0 ].code === 'download_failed'
) { ) {
// Specific server-returned error. // Specific server-returned error.
$plugin.find( '.actions' ).append( '<div class="msg error">' + wp_mail_smtp_about.plugin_install_error + '</div>' ); $plugin.find( '.actions' ).append( '<div class="msg error">' + wp_mail_smtp_about.plugin_install_error + '</div>' );
} } else {
else {
// Generic error. // Generic error.
$plugin.find( '.actions' ).append( '<div class="msg error">' + res.data + '</div>' ); $plugin.find( '.actions' ).append( '<div class="msg error">' + res.data + '</div>' );
} }
@ -165,26 +156,26 @@ WPMailSMTP.Admin.About = WPMailSMTP.Admin.About || (function ( document, window,
$btn.html( wp_mail_smtp_about.plugin_download_btn ); $btn.html( wp_mail_smtp_about.plugin_download_btn );
} }
if ( ! is_install_successful ) { if ( ! isInstallSuccessful ) {
$btn.removeClass( 'disabled' ); $btn.removeClass( 'disabled' );
} }
$btn.removeClass( 'loading' ); $btn.removeClass( 'loading' );
// Automatically clear plugin messages after 3 seconds. // Automatically clear plugin messages after 3 seconds.
setTimeout( function () { setTimeout( function() {
$( '.plugin-item .msg' ).remove(); $( '.plugin-item .msg' ).remove();
}, 3000 ); }, 3000 );
}).fail( function( xhr ) { } ).fail( function( xhr ) {
console.log( xhr.responseText ); console.log( xhr.responseText );
}); } );
}); } );
} }
}; };
// Provide access to public functions/properties. // Provide access to public functions/properties.
return app; return app;
})( document, window, jQuery ); }( document, window, jQuery ) );
// Initialize. // Initialize.
WPMailSMTP.Admin.About.init(); WPMailSMTP.Admin.About.init();

View File

@ -1 +1 @@
var WPMailSMTP=window.WPMailSMTP||{};WPMailSMTP.Admin=WPMailSMTP.Admin||{},WPMailSMTP.Admin.About=WPMailSMTP.Admin.About||function(a,t,p){"use strict";var i={init:function(){p(a).ready(i.ready)},ready:function(){i.pageHolder=p(".wp-mail-smtp-page-about"),i.bindActions(),p(".wp-mail-smtp-page").trigger("WPMailSMTP.Admin.About.ready")},bindActions:function(){jQuery(".wp-mail-smtp-admin-about-plugins .plugin-item .details").matchHeight(),p(a).on("click",".wp-mail-smtp-admin-about-plugins .plugin-item .action-button .button",function(a){a.preventDefault();var i=p(this);if(i.hasClass("disabled")||i.hasClass("loading"))return!1;var s,n,l,e,o,u=i.closest(".plugin-item"),t=i.attr("data-plugin");if(i.addClass("loading disabled"),i.text(wp_mail_smtp_about.plugin_processing),i.hasClass("status-inactive"))s="about_plugin_activate",n="status-active button button-secondary disabled",l=wp_mail_smtp_about.plugin_active,e=wp_mail_smtp_about.plugin_activated,wp_mail_smtp_about.plugin_activate;else{if(!i.hasClass("status-download"))return;s="about_plugin_install",n="status-active button disabled",l=wp_mail_smtp_about.plugin_active,e=wp_mail_smtp_about.plugin_activated,wp_mail_smtp_about.plugin_activate}var d={action:"wp_mail_smtp_ajax",task:s,nonce:wp_mail_smtp_about.nonce,plugin:t};p.post(wp_mail_smtp_about.ajax_url,d,function(a){var t;a.success?(t=!0,"about_plugin_install"===s?(i.attr("data-plugin",a.data.basename),o=a.data.msg,a.data.is_activated||(n="button",l=wp_mail_smtp_about.plugin_inactive,e=wp_mail_smtp_about.plugin_activate)):o=a.data,u.find(".actions").append('<div class="msg success">'+o+"</div>"),u.find("span.status-label").removeClass("status-active status-inactive status-download").addClass(n).removeClass("button button-primary button-secondary disabled").text(l),i.removeClass("status-active status-inactive status-download").removeClass("button button-primary button-secondary disabled").addClass(n).html(e)):(t=!1,a.hasOwnProperty("data")&&a.data.hasOwnProperty(0)&&a.data[0].hasOwnProperty("code")&&"download_failed"===a.data[0].code?u.find(".actions").append('<div class="msg error">'+wp_mail_smtp_about.plugin_install_error+"</div>"):u.find(".actions").append('<div class="msg error">'+a.data+"</div>"),i.html(wp_mail_smtp_about.plugin_download_btn)),t||i.removeClass("disabled"),i.removeClass("loading"),setTimeout(function(){p(".plugin-item .msg").remove()},3e3)}).fail(function(a){console.log(a.responseText)})})}};return i}(document,window,jQuery),WPMailSMTP.Admin.About.init(); "use strict";var WPMailSMTP=window.WPMailSMTP||{};WPMailSMTP.Admin=WPMailSMTP.Admin||{},WPMailSMTP.Admin.About=WPMailSMTP.Admin.About||function(a,p){var t={init:function(){p(a).ready(t.ready)},ready:function(){t.pageHolder=p(".wp-mail-smtp-page-about"),t.bindActions(),p(".wp-mail-smtp-page").trigger("WPMailSMTP.Admin.About.ready")},bindActions:function(){jQuery(".wp-mail-smtp-admin-about-plugins .plugin-item .details").matchHeight(),p(a).on("click",".wp-mail-smtp-admin-about-plugins .plugin-item .action-button .button",function(a){a.preventDefault();var i=p(this);if(i.hasClass("disabled")||i.hasClass("loading"))return!1;var s,n,l,e,o,d=i.closest(".plugin-item"),t=i.attr("data-plugin");if(i.addClass("loading disabled"),i.text(wp_mail_smtp_about.plugin_processing),i.hasClass("status-inactive"))s="about_plugin_activate",n="status-active button button-secondary disabled",l=wp_mail_smtp_about.plugin_active,e=wp_mail_smtp_about.plugin_activated;else{if(!i.hasClass("status-download"))return;s="about_plugin_install",n="status-active button disabled",l=wp_mail_smtp_about.plugin_active,e=wp_mail_smtp_about.plugin_activated}var u={action:"wp_mail_smtp_ajax",task:s,nonce:wp_mail_smtp_about.nonce,plugin:t};p.post(wp_mail_smtp_about.ajax_url,u,function(a){var t;a.success?(t=!0,"about_plugin_install"===s?(i.attr("data-plugin",a.data.basename),o=a.data.msg,a.data.is_activated||(n="button",l=wp_mail_smtp_about.plugin_inactive,e=wp_mail_smtp_about.plugin_activate)):o=a.data,d.find(".actions").append('<div class="msg success">'+o+"</div>"),d.find("span.status-label").removeClass("status-active status-inactive status-download").addClass(n).removeClass("button button-primary button-secondary disabled").text(l),i.removeClass("status-active status-inactive status-download").removeClass("button button-primary button-secondary disabled").addClass(n).html(e)):(t=!1,a.hasOwnProperty("data")&&a.data.hasOwnProperty(0)&&a.data[0].hasOwnProperty("code")&&"download_failed"===a.data[0].code?d.find(".actions").append('<div class="msg error">'+wp_mail_smtp_about.plugin_install_error+"</div>"):d.find(".actions").append('<div class="msg error">'+a.data+"</div>"),i.html(wp_mail_smtp_about.plugin_download_btn)),t||i.removeClass("disabled"),i.removeClass("loading"),setTimeout(function(){p(".plugin-item .msg").remove()},3e3)}).fail(function(a){console.log(a.responseText)})})}};return t}(document,(window,jQuery)),WPMailSMTP.Admin.About.init();

View File

@ -1,4 +1,6 @@
/* globals jQuery, wp_mail_smtp */ /* globals wp_mail_smtp, ajaxurl */
'use strict';
var WPMailSMTP = window.WPMailSMTP || {}; var WPMailSMTP = window.WPMailSMTP || {};
WPMailSMTP.Admin = WPMailSMTP.Admin || {}; WPMailSMTP.Admin = WPMailSMTP.Admin || {};
@ -7,32 +9,22 @@ WPMailSMTP.Admin = WPMailSMTP.Admin || {};
* *
* @since 1.6.0 * @since 1.6.0
*/ */
WPMailSMTP.Admin.Settings = WPMailSMTP.Admin.Settings || (function ( document, window, $ ) { WPMailSMTP.Admin.Settings = WPMailSMTP.Admin.Settings || ( function( document, window, $ ) {
'use strict';
/**
* Private functions and properties.
*
* @since 1.6.0
*
* @type {Object}
*/
var __private = {};
/** /**
* Public functions and properties. * Public functions and properties.
* *
* @since 1.6.0 * @since 1.6.0
* *
* @type {Object} * @type {object}
*/ */
var app = { var app = {
/** /**
* State attribute showing if one of the plugin settings * State attribute showing if one of the plugin settings
* changed and was not yet saved. * changed and was not yet saved.
* *
* @since {VERSION} * @since 1.9.0
* *
* @type {boolean} * @type {boolean}
*/ */
@ -43,7 +35,7 @@ WPMailSMTP.Admin.Settings = WPMailSMTP.Admin.Settings || (function ( document, w
* *
* @since 1.6.0 * @since 1.6.0
*/ */
init: function () { init: function() {
// Do that when DOM is ready. // Do that when DOM is ready.
$( document ).ready( app.ready ); $( document ).ready( app.ready );
@ -54,7 +46,7 @@ WPMailSMTP.Admin.Settings = WPMailSMTP.Admin.Settings || (function ( document, w
* *
* @since 1.6.0 * @since 1.6.0
*/ */
ready: function () { ready: function() {
app.pageHolder = $( '.wp-mail-smtp-tab-settings' ); app.pageHolder = $( '.wp-mail-smtp-tab-settings' );
@ -69,17 +61,18 @@ WPMailSMTP.Admin.Settings = WPMailSMTP.Admin.Settings || (function ( document, w
* *
* @since 1.6.0 * @since 1.6.0
*/ */
bindActions: function () { bindActions: function() {
// Mailer selection. // Mailer selection.
$( '.wp-mail-smtp-mailer-image', app.pageHolder ).click( function () { $( '.wp-mail-smtp-mailer-image', app.pageHolder ).click( function() {
$( this ).parents( '.wp-mail-smtp-mailer' ).find( 'input' ).trigger( 'click' ); $( this ).parents( '.wp-mail-smtp-mailer' ).find( 'input' ).trigger( 'click' );
} ); } );
$( '.wp-mail-smtp-mailer input', app.pageHolder ).click( function () { $( '.wp-mail-smtp-mailer input', app.pageHolder ).click( function() {
var $input = $( this ); var $input = $( this );
if ( $input.prop( 'disabled' ) ) { if ( $input.prop( 'disabled' ) ) {
// Educational Popup. // Educational Popup.
if ( $input.hasClass( 'educate' ) ) { if ( $input.hasClass( 'educate' ) ) {
app.education.upgradeMailer( $input ); app.education.upgradeMailer( $input );
@ -90,6 +83,7 @@ WPMailSMTP.Admin.Settings = WPMailSMTP.Admin.Settings || (function ( document, w
// Deselect the current mailer. // Deselect the current mailer.
$( '.wp-mail-smtp-mailer', app.pageHolder ).removeClass( 'active' ); $( '.wp-mail-smtp-mailer', app.pageHolder ).removeClass( 'active' );
// Select the correct one. // Select the correct one.
$( this ).parents( '.wp-mail-smtp-mailer' ).addClass( 'active' ); $( this ).parents( '.wp-mail-smtp-mailer' ).addClass( 'active' );
@ -101,23 +95,23 @@ WPMailSMTP.Admin.Settings = WPMailSMTP.Admin.Settings || (function ( document, w
app.mailers.smtp.bindActions(); app.mailers.smtp.bindActions();
// Dismiss Pro banner at the bottom of the page. // Dismiss Pro banner at the bottom of the page.
$( '#wp-mail-smtp-pro-banner-dismiss', app.pageHolder ).on( 'click', function () { $( '#wp-mail-smtp-pro-banner-dismiss', app.pageHolder ).on( 'click', function() {
$.ajax( { $.ajax( {
url: ajaxurl, url: ajaxurl,
dataType: 'json', dataType: 'json',
type: 'POST', type: 'POST',
data: { data: {
action: 'wp_mail_smtp_ajax', action: 'wp_mail_smtp_ajax',
task: 'pro_banner_dismiss' task: 'pro_banner_dismiss'
} }
} ) } )
.always( function () { .always( function() {
$( '#wp-mail-smtp-pro-banner', app.pageHolder ).fadeOut( 'fast' ); $( '#wp-mail-smtp-pro-banner', app.pageHolder ).fadeOut( 'fast' );
} ); } );
} ); } );
// Dismis educational notices for certain mailers. // Dissmis educational notices for certain mailers.
$( '.js-wp-mail-smtp-mailer-notice-dismiss', app.pageHolder ).on( 'click', function ( e ) { $( '.js-wp-mail-smtp-mailer-notice-dismiss', app.pageHolder ).on( 'click', function( e ) {
e.preventDefault(); e.preventDefault();
var $btn = $( this ), var $btn = $( this ),
@ -128,28 +122,28 @@ WPMailSMTP.Admin.Settings = WPMailSMTP.Admin.Settings || (function ( document, w
} }
$.ajax( { $.ajax( {
url: ajaxurl, url: ajaxurl,
dataType: 'json', dataType: 'json',
type: 'POST', type: 'POST',
data: { data: {
action: 'wp_mail_smtp_ajax', action: 'wp_mail_smtp_ajax',
task: 'notice_dismiss', task: 'notice_dismiss',
notice: $notice.data( 'notice' ), notice: $notice.data( 'notice' ),
mailer: $notice.data( 'mailer' ) mailer: $notice.data( 'mailer' )
}, },
beforeSend: function () { beforeSend: function() {
$btn.addClass( 'disabled' ); $btn.addClass( 'disabled' );
} }
} ) } )
.always( function () { .always( function() {
$notice.fadeOut( 'fast', function () { $notice.fadeOut( 'fast', function() {
$btn.removeClass( 'disabled' ); $btn.removeClass( 'disabled' );
} ); } );
} ); } );
} ); } );
// Show/hide debug output. // Show/hide debug output.
$( '#wp-mail-smtp-debug .error-log-toggle' ).on( 'click', function ( e ) { $( '#wp-mail-smtp-debug .error-log-toggle' ).on( 'click', function( e ) {
e.preventDefault(); e.preventDefault();
$( '#wp-mail-smtp-debug .error-log-toggle' ).find( '.dashicons' ).toggleClass( 'dashicons-arrow-right-alt2 dashicons-arrow-down-alt2' ); $( '#wp-mail-smtp-debug .error-log-toggle' ).find( '.dashicons' ).toggleClass( 'dashicons-arrow-right-alt2 dashicons-arrow-down-alt2' );
@ -158,12 +152,12 @@ WPMailSMTP.Admin.Settings = WPMailSMTP.Admin.Settings || (function ( document, w
} ); } );
// Remove mailer connection. // Remove mailer connection.
$( '.js-wp-mail-smtp-provider-remove', app.pageHolder ).on( 'click', function () { $( '.js-wp-mail-smtp-provider-remove', app.pageHolder ).on( 'click', function() {
return confirm( wp_mail_smtp.text_provider_remove ); return confirm( wp_mail_smtp.text_provider_remove );
} ); } );
// Copy input text to clipboard. // Copy input text to clipboard.
$( '.wp-mail-smtp-setting-copy', app.pageHolder ).click( function ( e ) { $( '.wp-mail-smtp-setting-copy', app.pageHolder ).click( function( e ) {
e.preventDefault(); e.preventDefault();
var target = $( '#' + $( this ).data( 'source_id' ) ).get( 0 ); var target = $( '#' + $( this ).data( 'source_id' ) ).get( 0 );
@ -177,7 +171,7 @@ WPMailSMTP.Admin.Settings = WPMailSMTP.Admin.Settings || (function ( document, w
}, },
education: { education: {
upgradeMailer: function ( $input ) { upgradeMailer: function( $input ) {
$.alert( { $.alert( {
backgroundDismiss: true, backgroundDismiss: true,
@ -192,7 +186,7 @@ WPMailSMTP.Admin.Settings = WPMailSMTP.Admin.Settings || (function ( document, w
icon: '"></i>' + wp_mail_smtp.education.upgrade_icon_lock + '<i class="', icon: '"></i>' + wp_mail_smtp.education.upgrade_icon_lock + '<i class="',
content: $( '.wp-mail-smtp-mailer-options .wp-mail-smtp-mailer-option-' + $input.val() + ' .wp-mail-smtp-setting-field' ).html(), content: $( '.wp-mail-smtp-mailer-options .wp-mail-smtp-mailer-option-' + $input.val() + ' .wp-mail-smtp-setting-field' ).html(),
boxWidth: '550px', boxWidth: '550px',
onOpenBefore: function () { onOpenBefore: function() {
this.$btnc.after( '<div class="discount-note">' + wp_mail_smtp.education.upgrade_bonus + wp_mail_smtp.education.upgrade_doc + '</div>' ); this.$btnc.after( '<div class="discount-note">' + wp_mail_smtp.education.upgrade_bonus + wp_mail_smtp.education.upgrade_doc + '</div>' );
}, },
buttons: { buttons: {
@ -200,7 +194,7 @@ WPMailSMTP.Admin.Settings = WPMailSMTP.Admin.Settings || (function ( document, w
text: wp_mail_smtp.education.upgrade_button, text: wp_mail_smtp.education.upgrade_button,
btnClass: 'btn-confirm', btnClass: 'btn-confirm',
keys: [ 'enter' ], keys: [ 'enter' ],
action: function () { action: function() {
window.open( wp_mail_smtp.education.upgrade_url + '&utm_content=' + encodeURI( $input.val() ), '_blank' ); window.open( wp_mail_smtp.education.upgrade_url + '&utm_content=' + encodeURI( $input.val() ), '_blank' );
} }
} }
@ -216,15 +210,15 @@ WPMailSMTP.Admin.Settings = WPMailSMTP.Admin.Settings || (function ( document, w
*/ */
mailers: { mailers: {
smtp: { smtp: {
bindActions: function () { bindActions: function() {
// Hide SMTP-specific user/pass when Auth disabled. // Hide SMTP-specific user/pass when Auth disabled.
$( '#wp-mail-smtp-setting-smtp-auth' ).change( function () { $( '#wp-mail-smtp-setting-smtp-auth' ).change( function() {
$( '#wp-mail-smtp-setting-row-smtp-user, #wp-mail-smtp-setting-row-smtp-pass' ).toggleClass( 'inactive' ); $( '#wp-mail-smtp-setting-row-smtp-user, #wp-mail-smtp-setting-row-smtp-pass' ).toggleClass( 'inactive' );
} ); } );
// Port default values based on encryption type. // Port default values based on encryption type.
$( '#wp-mail-smtp-setting-row-smtp-encryption input' ).change( function () { $( '#wp-mail-smtp-setting-row-smtp-encryption input' ).change( function() {
var $input = $( this ), var $input = $( this ),
$smtpPort = $( '#wp-mail-smtp-setting-smtp-port', app.pageHolder ); $smtpPort = $( '#wp-mail-smtp-setting-smtp-port', app.pageHolder );
@ -232,12 +226,10 @@ WPMailSMTP.Admin.Settings = WPMailSMTP.Admin.Settings || (function ( document, w
if ( 'tls' === $input.val() ) { if ( 'tls' === $input.val() ) {
$smtpPort.val( '587' ); $smtpPort.val( '587' );
$( '#wp-mail-smtp-setting-row-smtp-autotls' ).addClass( 'inactive' ); $( '#wp-mail-smtp-setting-row-smtp-autotls' ).addClass( 'inactive' );
} } else if ( 'ssl' === $input.val() ) {
else if ( 'ssl' === $input.val() ) {
$smtpPort.val( '465' ); $smtpPort.val( '465' );
$( '#wp-mail-smtp-setting-row-smtp-autotls' ).removeClass( 'inactive' ); $( '#wp-mail-smtp-setting-row-smtp-autotls' ).removeClass( 'inactive' );
} } else {
else {
$smtpPort.val( '25' ); $smtpPort.val( '25' );
$( '#wp-mail-smtp-setting-row-smtp-autotls' ).removeClass( 'inactive' ); $( '#wp-mail-smtp-setting-row-smtp-autotls' ).removeClass( 'inactive' );
} }
@ -249,26 +241,26 @@ WPMailSMTP.Admin.Settings = WPMailSMTP.Admin.Settings || (function ( document, w
/** /**
* Exit notice JS code when plugin settings are not saved. * Exit notice JS code when plugin settings are not saved.
* *
* @since {VERSION} * @since 1.9.0
*/ */
triggerExitNotice: function () { triggerExitNotice: function() {
var $settingPages = $( '.wp-mail-smtp-page-general:not( .wp-mail-smtp-tab-test )' ); var $settingPages = $( '.wp-mail-smtp-page-general:not( .wp-mail-smtp-tab-test )' );
// Display an exit notice, if settings are not saved. // Display an exit notice, if settings are not saved.
$( window ).on( 'beforeunload', function () { $( window ).on( 'beforeunload', function() {
if ( app.pluginSettingsChanged ) { if ( app.pluginSettingsChanged ) {
return wp_mail_smtp.text_settings_not_saved; return wp_mail_smtp.text_settings_not_saved;
} }
} ); } );
// Set settings changed attribute, if any input was changed. // Set settings changed attribute, if any input was changed.
$( ':input:not( #wp-mail-smtp-setting-license-key )', $settingPages ).on( 'change', function () { $( ':input:not( #wp-mail-smtp-setting-license-key )', $settingPages ).on( 'change', function() {
app.pluginSettingsChanged = true; app.pluginSettingsChanged = true;
} ); } );
// Clear the settings changed attribute, if the settings are about to be saved. // Clear the settings changed attribute, if the settings are about to be saved.
$( 'form', $settingPages ).on( 'submit', function () { $( 'form', $settingPages ).on( 'submit', function() {
app.pluginSettingsChanged = false; app.pluginSettingsChanged = false;
} ); } );
} }
@ -276,7 +268,7 @@ WPMailSMTP.Admin.Settings = WPMailSMTP.Admin.Settings || (function ( document, w
// Provide access to public functions/properties. // Provide access to public functions/properties.
return app; return app;
})( document, window, jQuery ); }( document, window, jQuery ) );
// Initialize. // Initialize.
WPMailSMTP.Admin.Settings.init(); WPMailSMTP.Admin.Settings.init();

View File

@ -1 +1 @@
var WPMailSMTP=window.WPMailSMTP||{};WPMailSMTP.Admin=WPMailSMTP.Admin||{},WPMailSMTP.Admin.Settings=WPMailSMTP.Admin.Settings||function(i,e,a){"use strict";var n={pluginSettingsChanged:!1,init:function(){a(i).ready(n.ready)},ready:function(){n.pageHolder=a(".wp-mail-smtp-tab-settings"),a("#screen-meta-links, #screen-meta").prependTo("#wp-mail-smtp-header-temp").show(),n.bindActions()},bindActions:function(){a(".wp-mail-smtp-mailer-image",n.pageHolder).click(function(){a(this).parents(".wp-mail-smtp-mailer").find("input").trigger("click")}),a(".wp-mail-smtp-mailer input",n.pageHolder).click(function(){var t=a(this);if(t.prop("disabled"))return t.hasClass("educate")&&n.education.upgradeMailer(t),!1;a(".wp-mail-smtp-mailer",n.pageHolder).removeClass("active"),a(this).parents(".wp-mail-smtp-mailer").addClass("active"),a(".wp-mail-smtp-mailer-option",n.pageHolder).addClass("hidden").removeClass("active"),a(".wp-mail-smtp-mailer-option-"+a(this).val(),n.pageHolder).addClass("active").removeClass("hidden")}),n.mailers.smtp.bindActions(),a("#wp-mail-smtp-pro-banner-dismiss",n.pageHolder).on("click",function(){a.ajax({url:ajaxurl,dataType:"json",type:"POST",data:{action:"wp_mail_smtp_ajax",task:"pro_banner_dismiss"}}).always(function(){a("#wp-mail-smtp-pro-banner",n.pageHolder).fadeOut("fast")})}),a(".js-wp-mail-smtp-mailer-notice-dismiss",n.pageHolder).on("click",function(t){t.preventDefault();var i=a(this),e=i.parents(".inline-notice");if(i.hasClass("disabled"))return!1;a.ajax({url:ajaxurl,dataType:"json",type:"POST",data:{action:"wp_mail_smtp_ajax",task:"notice_dismiss",notice:e.data("notice"),mailer:e.data("mailer")},beforeSend:function(){i.addClass("disabled")}}).always(function(){e.fadeOut("fast",function(){i.removeClass("disabled")})})}),a("#wp-mail-smtp-debug .error-log-toggle").on("click",function(t){t.preventDefault(),a("#wp-mail-smtp-debug .error-log-toggle").find(".dashicons").toggleClass("dashicons-arrow-right-alt2 dashicons-arrow-down-alt2"),a("#wp-mail-smtp-debug .error-log").slideToggle(),a("#wp-mail-smtp-debug .error-log-note").toggle()}),a(".js-wp-mail-smtp-provider-remove",n.pageHolder).on("click",function(){return confirm(wp_mail_smtp.text_provider_remove)}),a(".wp-mail-smtp-setting-copy",n.pageHolder).click(function(t){t.preventDefault(),a("#"+a(this).data("source_id")).get(0).select(),i.execCommand("Copy")}),n.triggerExitNotice()},education:{upgradeMailer:function(t){a.alert({backgroundDismiss:!0,escapeKey:!0,animationBounce:1,theme:"modern",animateFromElement:!1,draggable:!1,closeIcon:!0,useBootstrap:!1,title:wp_mail_smtp.education.upgrade_title.replace(/%name%/g,t.siblings("label").text().trim()),icon:'"></i>'+wp_mail_smtp.education.upgrade_icon_lock+'<i class="',content:a(".wp-mail-smtp-mailer-options .wp-mail-smtp-mailer-option-"+t.val()+" .wp-mail-smtp-setting-field").html(),boxWidth:"550px",onOpenBefore:function(){this.$btnc.after('<div class="discount-note">'+wp_mail_smtp.education.upgrade_bonus+wp_mail_smtp.education.upgrade_doc+"</div>")},buttons:{confirm:{text:wp_mail_smtp.education.upgrade_button,btnClass:"btn-confirm",keys:["enter"],action:function(){e.open(wp_mail_smtp.education.upgrade_url+"&utm_content="+encodeURI(t.val()),"_blank")}}}})}},mailers:{smtp:{bindActions:function(){a("#wp-mail-smtp-setting-smtp-auth").change(function(){a("#wp-mail-smtp-setting-row-smtp-user, #wp-mail-smtp-setting-row-smtp-pass").toggleClass("inactive")}),a("#wp-mail-smtp-setting-row-smtp-encryption input").change(function(){var t=a(this),i=a("#wp-mail-smtp-setting-smtp-port",n.pageHolder);"tls"===t.val()?(i.val("587"),a("#wp-mail-smtp-setting-row-smtp-autotls").addClass("inactive")):("ssl"===t.val()?i.val("465"):i.val("25"),a("#wp-mail-smtp-setting-row-smtp-autotls").removeClass("inactive"))})}}},triggerExitNotice:function(){var t=a(".wp-mail-smtp-page-general:not( .wp-mail-smtp-tab-test )");a(e).on("beforeunload",function(){if(n.pluginSettingsChanged)return wp_mail_smtp.text_settings_not_saved}),a(":input:not( #wp-mail-smtp-setting-license-key )",t).on("change",function(){n.pluginSettingsChanged=!0}),a("form",t).on("submit",function(){n.pluginSettingsChanged=!1})}};return n}(document,window,jQuery),WPMailSMTP.Admin.Settings.init(); "use strict";var WPMailSMTP=window.WPMailSMTP||{};WPMailSMTP.Admin=WPMailSMTP.Admin||{},WPMailSMTP.Admin.Settings=WPMailSMTP.Admin.Settings||function(i,e,a){var n={pluginSettingsChanged:!1,init:function(){a(i).ready(n.ready)},ready:function(){n.pageHolder=a(".wp-mail-smtp-tab-settings"),a("#screen-meta-links, #screen-meta").prependTo("#wp-mail-smtp-header-temp").show(),n.bindActions()},bindActions:function(){a(".wp-mail-smtp-mailer-image",n.pageHolder).click(function(){a(this).parents(".wp-mail-smtp-mailer").find("input").trigger("click")}),a(".wp-mail-smtp-mailer input",n.pageHolder).click(function(){var t=a(this);if(t.prop("disabled"))return t.hasClass("educate")&&n.education.upgradeMailer(t),!1;a(".wp-mail-smtp-mailer",n.pageHolder).removeClass("active"),a(this).parents(".wp-mail-smtp-mailer").addClass("active"),a(".wp-mail-smtp-mailer-option",n.pageHolder).addClass("hidden").removeClass("active"),a(".wp-mail-smtp-mailer-option-"+a(this).val(),n.pageHolder).addClass("active").removeClass("hidden")}),n.mailers.smtp.bindActions(),a("#wp-mail-smtp-pro-banner-dismiss",n.pageHolder).on("click",function(){a.ajax({url:ajaxurl,dataType:"json",type:"POST",data:{action:"wp_mail_smtp_ajax",task:"pro_banner_dismiss"}}).always(function(){a("#wp-mail-smtp-pro-banner",n.pageHolder).fadeOut("fast")})}),a(".js-wp-mail-smtp-mailer-notice-dismiss",n.pageHolder).on("click",function(t){t.preventDefault();var i=a(this),e=i.parents(".inline-notice");if(i.hasClass("disabled"))return!1;a.ajax({url:ajaxurl,dataType:"json",type:"POST",data:{action:"wp_mail_smtp_ajax",task:"notice_dismiss",notice:e.data("notice"),mailer:e.data("mailer")},beforeSend:function(){i.addClass("disabled")}}).always(function(){e.fadeOut("fast",function(){i.removeClass("disabled")})})}),a("#wp-mail-smtp-debug .error-log-toggle").on("click",function(t){t.preventDefault(),a("#wp-mail-smtp-debug .error-log-toggle").find(".dashicons").toggleClass("dashicons-arrow-right-alt2 dashicons-arrow-down-alt2"),a("#wp-mail-smtp-debug .error-log").slideToggle(),a("#wp-mail-smtp-debug .error-log-note").toggle()}),a(".js-wp-mail-smtp-provider-remove",n.pageHolder).on("click",function(){return confirm(wp_mail_smtp.text_provider_remove)}),a(".wp-mail-smtp-setting-copy",n.pageHolder).click(function(t){t.preventDefault(),a("#"+a(this).data("source_id")).get(0).select(),i.execCommand("Copy")}),n.triggerExitNotice()},education:{upgradeMailer:function(t){a.alert({backgroundDismiss:!0,escapeKey:!0,animationBounce:1,theme:"modern",animateFromElement:!1,draggable:!1,closeIcon:!0,useBootstrap:!1,title:wp_mail_smtp.education.upgrade_title.replace(/%name%/g,t.siblings("label").text().trim()),icon:'"></i>'+wp_mail_smtp.education.upgrade_icon_lock+'<i class="',content:a(".wp-mail-smtp-mailer-options .wp-mail-smtp-mailer-option-"+t.val()+" .wp-mail-smtp-setting-field").html(),boxWidth:"550px",onOpenBefore:function(){this.$btnc.after('<div class="discount-note">'+wp_mail_smtp.education.upgrade_bonus+wp_mail_smtp.education.upgrade_doc+"</div>")},buttons:{confirm:{text:wp_mail_smtp.education.upgrade_button,btnClass:"btn-confirm",keys:["enter"],action:function(){e.open(wp_mail_smtp.education.upgrade_url+"&utm_content="+encodeURI(t.val()),"_blank")}}}})}},mailers:{smtp:{bindActions:function(){a("#wp-mail-smtp-setting-smtp-auth").change(function(){a("#wp-mail-smtp-setting-row-smtp-user, #wp-mail-smtp-setting-row-smtp-pass").toggleClass("inactive")}),a("#wp-mail-smtp-setting-row-smtp-encryption input").change(function(){var t=a(this),i=a("#wp-mail-smtp-setting-smtp-port",n.pageHolder);"tls"===t.val()?(i.val("587"),a("#wp-mail-smtp-setting-row-smtp-autotls").addClass("inactive")):("ssl"===t.val()?i.val("465"):i.val("25"),a("#wp-mail-smtp-setting-row-smtp-autotls").removeClass("inactive"))})}}},triggerExitNotice:function(){var t=a(".wp-mail-smtp-page-general:not( .wp-mail-smtp-tab-test )");a(e).on("beforeunload",function(){if(n.pluginSettingsChanged)return wp_mail_smtp.text_settings_not_saved}),a(":input:not( #wp-mail-smtp-setting-license-key )",t).on("change",function(){n.pluginSettingsChanged=!0}),a("form",t).on("submit",function(){n.pluginSettingsChanged=!1})}};return n}(document,window,jQuery),WPMailSMTP.Admin.Settings.init();

View File

@ -1,388 +1,388 @@
/** /**
* jquery-match-height 0.7.2 by @liabru * jquery-match-height 0.7.2 by @liabru
* http://brm.io/jquery-match-height/ * http://brm.io/jquery-match-height/
* License: MIT * License: MIT
*/ */
;(function(factory) { // eslint-disable-line no-extra-semi ;(function(factory) { // eslint-disable-line no-extra-semi
'use strict'; 'use strict';
if (typeof define === 'function' && define.amd) { if (typeof define === 'function' && define.amd) {
// AMD // AMD
define(['jquery'], factory); define(['jquery'], factory);
} else if (typeof module !== 'undefined' && module.exports) { } else if (typeof module !== 'undefined' && module.exports) {
// CommonJS // CommonJS
module.exports = factory(require('jquery')); module.exports = factory(require('jquery'));
} else { } else {
// Global // Global
factory(jQuery); factory(jQuery);
} }
})(function($) { })(function($) {
/* /*
* internal * internal
*/ */
var _previousResizeWidth = -1, var _previousResizeWidth = -1,
_updateTimeout = -1; _updateTimeout = -1;
/* /*
* _parse * _parse
* value parse utility function * value parse utility function
*/ */
var _parse = function(value) { var _parse = function(value) {
// parse value and convert NaN to 0 // parse value and convert NaN to 0
return parseFloat(value) || 0; return parseFloat(value) || 0;
}; };
/* /*
* _rows * _rows
* utility function returns array of jQuery selections representing each row * utility function returns array of jQuery selections representing each row
* (as displayed after float wrapping applied by browser) * (as displayed after float wrapping applied by browser)
*/ */
var _rows = function(elements) { var _rows = function(elements) {
var tolerance = 1, var tolerance = 1,
$elements = $(elements), $elements = $(elements),
lastTop = null, lastTop = null,
rows = []; rows = [];
// group elements by their top position // group elements by their top position
$elements.each(function(){ $elements.each(function(){
var $that = $(this), var $that = $(this),
top = $that.offset().top - _parse($that.css('margin-top')), top = $that.offset().top - _parse($that.css('margin-top')),
lastRow = rows.length > 0 ? rows[rows.length - 1] : null; lastRow = rows.length > 0 ? rows[rows.length - 1] : null;
if (lastRow === null) { if (lastRow === null) {
// first item on the row, so just push it // first item on the row, so just push it
rows.push($that); rows.push($that);
} else { } else {
// if the row top is the same, add to the row group // if the row top is the same, add to the row group
if (Math.floor(Math.abs(lastTop - top)) <= tolerance) { if (Math.floor(Math.abs(lastTop - top)) <= tolerance) {
rows[rows.length - 1] = lastRow.add($that); rows[rows.length - 1] = lastRow.add($that);
} else { } else {
// otherwise start a new row group // otherwise start a new row group
rows.push($that); rows.push($that);
} }
} }
// keep track of the last row top // keep track of the last row top
lastTop = top; lastTop = top;
}); });
return rows; return rows;
}; };
/* /*
* _parseOptions * _parseOptions
* handle plugin options * handle plugin options
*/ */
var _parseOptions = function(options) { var _parseOptions = function(options) {
var opts = { var opts = {
byRow: true, byRow: true,
property: 'height', property: 'height',
target: null, target: null,
remove: false remove: false
}; };
if (typeof options === 'object') { if (typeof options === 'object') {
return $.extend(opts, options); return $.extend(opts, options);
} }
if (typeof options === 'boolean') { if (typeof options === 'boolean') {
opts.byRow = options; opts.byRow = options;
} else if (options === 'remove') { } else if (options === 'remove') {
opts.remove = true; opts.remove = true;
} }
return opts; return opts;
}; };
/* /*
* matchHeight * matchHeight
* plugin definition * plugin definition
*/ */
var matchHeight = $.fn.matchHeight = function(options) { var matchHeight = $.fn.matchHeight = function(options) {
var opts = _parseOptions(options); var opts = _parseOptions(options);
// handle remove // handle remove
if (opts.remove) { if (opts.remove) {
var that = this; var that = this;
// remove fixed height from all selected elements // remove fixed height from all selected elements
this.css(opts.property, ''); this.css(opts.property, '');
// remove selected elements from all groups // remove selected elements from all groups
$.each(matchHeight._groups, function(key, group) { $.each(matchHeight._groups, function(key, group) {
group.elements = group.elements.not(that); group.elements = group.elements.not(that);
}); });
// TODO: cleanup empty groups // TODO: cleanup empty groups
return this; return this;
} }
if (this.length <= 1 && !opts.target) { if (this.length <= 1 && !opts.target) {
return this; return this;
} }
// keep track of this group so we can re-apply later on load and resize events // keep track of this group so we can re-apply later on load and resize events
matchHeight._groups.push({ matchHeight._groups.push({
elements: this, elements: this,
options: opts options: opts
}); });
// match each element's height to the tallest element in the selection // match each element's height to the tallest element in the selection
matchHeight._apply(this, opts); matchHeight._apply(this, opts);
return this; return this;
}; };
/* /*
* plugin global options * plugin global options
*/ */
matchHeight.version = '0.7.2'; matchHeight.version = '0.7.2';
matchHeight._groups = []; matchHeight._groups = [];
matchHeight._throttle = 80; matchHeight._throttle = 80;
matchHeight._maintainScroll = false; matchHeight._maintainScroll = false;
matchHeight._beforeUpdate = null; matchHeight._beforeUpdate = null;
matchHeight._afterUpdate = null; matchHeight._afterUpdate = null;
matchHeight._rows = _rows; matchHeight._rows = _rows;
matchHeight._parse = _parse; matchHeight._parse = _parse;
matchHeight._parseOptions = _parseOptions; matchHeight._parseOptions = _parseOptions;
/* /*
* matchHeight._apply * matchHeight._apply
* apply matchHeight to given elements * apply matchHeight to given elements
*/ */
matchHeight._apply = function(elements, options) { matchHeight._apply = function(elements, options) {
var opts = _parseOptions(options), var opts = _parseOptions(options),
$elements = $(elements), $elements = $(elements),
rows = [$elements]; rows = [$elements];
// take note of scroll position // take note of scroll position
var scrollTop = $(window).scrollTop(), var scrollTop = $(window).scrollTop(),
htmlHeight = $('html').outerHeight(true); htmlHeight = $('html').outerHeight(true);
// get hidden parents // get hidden parents
var $hiddenParents = $elements.parents().filter(':hidden'); var $hiddenParents = $elements.parents().filter(':hidden');
// cache the original inline style // cache the original inline style
$hiddenParents.each(function() { $hiddenParents.each(function() {
var $that = $(this); var $that = $(this);
$that.data('style-cache', $that.attr('style')); $that.data('style-cache', $that.attr('style'));
}); });
// temporarily must force hidden parents visible // temporarily must force hidden parents visible
$hiddenParents.css('display', 'block'); $hiddenParents.css('display', 'block');
// get rows if using byRow, otherwise assume one row // get rows if using byRow, otherwise assume one row
if (opts.byRow && !opts.target) { if (opts.byRow && !opts.target) {
// must first force an arbitrary equal height so floating elements break evenly // must first force an arbitrary equal height so floating elements break evenly
$elements.each(function() { $elements.each(function() {
var $that = $(this), var $that = $(this),
display = $that.css('display'); display = $that.css('display');
// temporarily force a usable display value // temporarily force a usable display value
if (display !== 'inline-block' && display !== 'flex' && display !== 'inline-flex') { if (display !== 'inline-block' && display !== 'flex' && display !== 'inline-flex') {
display = 'block'; display = 'block';
} }
// cache the original inline style // cache the original inline style
$that.data('style-cache', $that.attr('style')); $that.data('style-cache', $that.attr('style'));
$that.css({ $that.css({
'display': display, 'display': display,
'padding-top': '0', 'padding-top': '0',
'padding-bottom': '0', 'padding-bottom': '0',
'margin-top': '0', 'margin-top': '0',
'margin-bottom': '0', 'margin-bottom': '0',
'border-top-width': '0', 'border-top-width': '0',
'border-bottom-width': '0', 'border-bottom-width': '0',
'height': '100px', 'height': '100px',
'overflow': 'hidden' 'overflow': 'hidden'
}); });
}); });
// get the array of rows (based on element top position) // get the array of rows (based on element top position)
rows = _rows($elements); rows = _rows($elements);
// revert original inline styles // revert original inline styles
$elements.each(function() { $elements.each(function() {
var $that = $(this); var $that = $(this);
$that.attr('style', $that.data('style-cache') || ''); $that.attr('style', $that.data('style-cache') || '');
}); });
} }
$.each(rows, function(key, row) { $.each(rows, function(key, row) {
var $row = $(row), var $row = $(row),
targetHeight = 0; targetHeight = 0;
if (!opts.target) { if (!opts.target) {
// skip apply to rows with only one item // skip apply to rows with only one item
if (opts.byRow && $row.length <= 1) { if (opts.byRow && $row.length <= 1) {
$row.css(opts.property, ''); $row.css(opts.property, '');
return; return;
} }
// iterate the row and find the max height // iterate the row and find the max height
$row.each(function(){ $row.each(function(){
var $that = $(this), var $that = $(this),
style = $that.attr('style'), style = $that.attr('style'),
display = $that.css('display'); display = $that.css('display');
// temporarily force a usable display value // temporarily force a usable display value
if (display !== 'inline-block' && display !== 'flex' && display !== 'inline-flex') { if (display !== 'inline-block' && display !== 'flex' && display !== 'inline-flex') {
display = 'block'; display = 'block';
} }
// ensure we get the correct actual height (and not a previously set height value) // ensure we get the correct actual height (and not a previously set height value)
var css = { 'display': display }; var css = { 'display': display };
css[opts.property] = ''; css[opts.property] = '';
$that.css(css); $that.css(css);
// find the max height (including padding, but not margin) // find the max height (including padding, but not margin)
if ($that.outerHeight(false) > targetHeight) { if ($that.outerHeight(false) > targetHeight) {
targetHeight = $that.outerHeight(false); targetHeight = $that.outerHeight(false);
} }
// revert styles // revert styles
if (style) { if (style) {
$that.attr('style', style); $that.attr('style', style);
} else { } else {
$that.css('display', ''); $that.css('display', '');
} }
}); });
} else { } else {
// if target set, use the height of the target element // if target set, use the height of the target element
targetHeight = opts.target.outerHeight(false); targetHeight = opts.target.outerHeight(false);
} }
// iterate the row and apply the height to all elements // iterate the row and apply the height to all elements
$row.each(function(){ $row.each(function(){
var $that = $(this), var $that = $(this),
verticalPadding = 0; verticalPadding = 0;
// don't apply to a target // don't apply to a target
if (opts.target && $that.is(opts.target)) { if (opts.target && $that.is(opts.target)) {
return; return;
} }
// handle padding and border correctly (required when not using border-box) // handle padding and border correctly (required when not using border-box)
if ($that.css('box-sizing') !== 'border-box') { if ($that.css('box-sizing') !== 'border-box') {
verticalPadding += _parse($that.css('border-top-width')) + _parse($that.css('border-bottom-width')); verticalPadding += _parse($that.css('border-top-width')) + _parse($that.css('border-bottom-width'));
verticalPadding += _parse($that.css('padding-top')) + _parse($that.css('padding-bottom')); verticalPadding += _parse($that.css('padding-top')) + _parse($that.css('padding-bottom'));
} }
// set the height (accounting for padding and border) // set the height (accounting for padding and border)
$that.css(opts.property, (targetHeight - verticalPadding) + 'px'); $that.css(opts.property, (targetHeight - verticalPadding) + 'px');
}); });
}); });
// revert hidden parents // revert hidden parents
$hiddenParents.each(function() { $hiddenParents.each(function() {
var $that = $(this); var $that = $(this);
$that.attr('style', $that.data('style-cache') || null); $that.attr('style', $that.data('style-cache') || null);
}); });
// restore scroll position if enabled // restore scroll position if enabled
if (matchHeight._maintainScroll) { if (matchHeight._maintainScroll) {
$(window).scrollTop((scrollTop / htmlHeight) * $('html').outerHeight(true)); $(window).scrollTop((scrollTop / htmlHeight) * $('html').outerHeight(true));
} }
return this; return this;
}; };
/* /*
* matchHeight._applyDataApi * matchHeight._applyDataApi
* applies matchHeight to all elements with a data-match-height attribute * applies matchHeight to all elements with a data-match-height attribute
*/ */
matchHeight._applyDataApi = function() { matchHeight._applyDataApi = function() {
var groups = {}; var groups = {};
// generate groups by their groupId set by elements using data-match-height // generate groups by their groupId set by elements using data-match-height
$('[data-match-height], [data-mh]').each(function() { $('[data-match-height], [data-mh]').each(function() {
var $this = $(this), var $this = $(this),
groupId = $this.attr('data-mh') || $this.attr('data-match-height'); groupId = $this.attr('data-mh') || $this.attr('data-match-height');
if (groupId in groups) { if (groupId in groups) {
groups[groupId] = groups[groupId].add($this); groups[groupId] = groups[groupId].add($this);
} else { } else {
groups[groupId] = $this; groups[groupId] = $this;
} }
}); });
// apply matchHeight to each group // apply matchHeight to each group
$.each(groups, function() { $.each(groups, function() {
this.matchHeight(true); this.matchHeight(true);
}); });
}; };
/* /*
* matchHeight._update * matchHeight._update
* updates matchHeight on all current groups with their correct options * updates matchHeight on all current groups with their correct options
*/ */
var _update = function(event) { var _update = function(event) {
if (matchHeight._beforeUpdate) { if (matchHeight._beforeUpdate) {
matchHeight._beforeUpdate(event, matchHeight._groups); matchHeight._beforeUpdate(event, matchHeight._groups);
} }
$.each(matchHeight._groups, function() { $.each(matchHeight._groups, function() {
matchHeight._apply(this.elements, this.options); matchHeight._apply(this.elements, this.options);
}); });
if (matchHeight._afterUpdate) { if (matchHeight._afterUpdate) {
matchHeight._afterUpdate(event, matchHeight._groups); matchHeight._afterUpdate(event, matchHeight._groups);
} }
}; };
matchHeight._update = function(throttle, event) { matchHeight._update = function(throttle, event) {
// prevent update if fired from a resize event // prevent update if fired from a resize event
// where the viewport width hasn't actually changed // where the viewport width hasn't actually changed
// fixes an event looping bug in IE8 // fixes an event looping bug in IE8
if (event && event.type === 'resize') { if (event && event.type === 'resize') {
var windowWidth = $(window).width(); var windowWidth = $(window).width();
if (windowWidth === _previousResizeWidth) { if (windowWidth === _previousResizeWidth) {
return; return;
} }
_previousResizeWidth = windowWidth; _previousResizeWidth = windowWidth;
} }
// throttle updates // throttle updates
if (!throttle) { if (!throttle) {
_update(event); _update(event);
} else if (_updateTimeout === -1) { } else if (_updateTimeout === -1) {
_updateTimeout = setTimeout(function() { _updateTimeout = setTimeout(function() {
_update(event); _update(event);
_updateTimeout = -1; _updateTimeout = -1;
}, matchHeight._throttle); }, matchHeight._throttle);
} }
}; };
/* /*
* bind events * bind events
*/ */
// apply on DOM ready event // apply on DOM ready event
$(matchHeight._applyDataApi); $(matchHeight._applyDataApi);
// use on or bind where supported // use on or bind where supported
var on = $.fn.on ? 'on' : 'bind'; var on = $.fn.on ? 'on' : 'bind';
// update heights on load and resize events // update heights on load and resize events
$(window)[on]('load', function(event) { $(window)[on]('load', function(event) {
matchHeight._update(false, event); matchHeight._update(false, event);
}); });
// throttled update heights on resize events // throttled update heights on resize events
$(window)[on]('resize orientationchange', function(event) { $(window)[on]('resize orientationchange', function(event) {
matchHeight._update(true, event); matchHeight._update(true, event);
}); });
}); });

View File

@ -0,0 +1 @@
!function(t){"use strict";"function"==typeof define&&define.amd?define(["jquery"],t):"undefined"!=typeof module&&module.exports?module.exports=t(require("jquery")):t(jQuery)}(function(l){function c(t){return parseFloat(t)||0}function h(t){var e=l(t),n=null,a=[];return e.each(function(){var t=l(this),e=t.offset().top-c(t.css("margin-top")),o=0<a.length?a[a.length-1]:null;null!==o&&Math.floor(Math.abs(n-e))<=1?a[a.length-1]=o.add(t):a.push(t),n=e}),a}function p(t){var e={byRow:!0,property:"height",target:null,remove:!1};return"object"==typeof t?l.extend(e,t):("boolean"==typeof t?e.byRow=t:"remove"===t&&(e.remove=!0),e)}var n=-1,a=-1,d=l.fn.matchHeight=function(t){var e=p(t);if(e.remove){var o=this;return this.css(e.property,""),l.each(d._groups,function(t,e){e.elements=e.elements.not(o)}),this}return this.length<=1&&!e.target||(d._groups.push({elements:this,options:e}),d._apply(this,e)),this};d.version="0.7.2",d._groups=[],d._throttle=80,d._maintainScroll=!1,d._beforeUpdate=null,d._afterUpdate=null,d._rows=h,d._parse=c,d._parseOptions=p,d._apply=function(t,e){var i=p(e),o=l(t),n=[o],a=l(window).scrollTop(),r=l("html").outerHeight(!0),s=o.parents().filter(":hidden");return s.each(function(){var t=l(this);t.data("style-cache",t.attr("style"))}),s.css("display","block"),i.byRow&&!i.target&&(o.each(function(){var t=l(this),e=t.css("display");"inline-block"!==e&&"flex"!==e&&"inline-flex"!==e&&(e="block"),t.data("style-cache",t.attr("style")),t.css({display:e,"padding-top":"0","padding-bottom":"0","margin-top":"0","margin-bottom":"0","border-top-width":"0","border-bottom-width":"0",height:"100px",overflow:"hidden"})}),n=h(o),o.each(function(){var t=l(this);t.attr("style",t.data("style-cache")||"")})),l.each(n,function(t,e){var o=l(e),a=0;if(i.target)a=i.target.outerHeight(!1);else{if(i.byRow&&o.length<=1)return void o.css(i.property,"");o.each(function(){var t=l(this),e=t.attr("style"),o=t.css("display");"inline-block"!==o&&"flex"!==o&&"inline-flex"!==o&&(o="block");var n={display:o};n[i.property]="",t.css(n),t.outerHeight(!1)>a&&(a=t.outerHeight(!1)),e?t.attr("style",e):t.css("display","")})}o.each(function(){var t=l(this),e=0;i.target&&t.is(i.target)||("border-box"!==t.css("box-sizing")&&(e+=c(t.css("border-top-width"))+c(t.css("border-bottom-width")),e+=c(t.css("padding-top"))+c(t.css("padding-bottom"))),t.css(i.property,a-e+"px"))})}),s.each(function(){var t=l(this);t.attr("style",t.data("style-cache")||null)}),d._maintainScroll&&l(window).scrollTop(a/r*l("html").outerHeight(!0)),this},d._applyDataApi=function(){var o={};l("[data-match-height], [data-mh]").each(function(){var t=l(this),e=t.attr("data-mh")||t.attr("data-match-height");o[e]=e in o?o[e].add(t):t}),l.each(o,function(){this.matchHeight(!0)})};function i(t){d._beforeUpdate&&d._beforeUpdate(t,d._groups),l.each(d._groups,function(){d._apply(this.elements,this.options)}),d._afterUpdate&&d._afterUpdate(t,d._groups)}d._update=function(t,e){if(e&&"resize"===e.type){var o=l(window).width();if(o===n)return;n=o}t?-1===a&&(a=setTimeout(function(){i(e),a=-1},d._throttle)):i(e)},l(d._applyDataApi);var t=l.fn.on?"on":"bind";l(window)[t]("load",function(t){d._update(!1,t)}),l(window)[t]("resize orientationchange",function(t){d._update(!0,t)})});

View File

@ -1,13 +1,13 @@
msgid "" msgid ""
msgstr "" msgstr ""
"Project-Id-Version: WP Mail SMTP 1.9.0\n" "Project-Id-Version: WP Mail SMTP 2.0.0\n"
"Report-Msgid-Bugs-To: https://wordpress.org/support/plugin/wp-mail-smtp\n" "Report-Msgid-Bugs-To: https://wordpress.org/support/plugin/wp-mail-smtp\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n" "Language-Team: LANGUAGE <LL@li.org>\n"
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n" "Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"POT-Creation-Date: 2020-03-23T16:26:08+02:00\n" "POT-Creation-Date: 2020-04-27T12:51:41+03:00\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"X-Generator: WP-CLI 2.4.0\n" "X-Generator: WP-CLI 2.4.0\n"
"X-Domain: wp-mail-smtp\n" "X-Domain: wp-mail-smtp\n"
@ -61,106 +61,115 @@ msgstr ""
#: src/Admin/Area.php:197 #: src/Admin/Area.php:197
#: src/Admin/Area.php:198 #: src/Admin/Area.php:198
#: src/SiteHealth.php:40 #: src/SiteHealth.php:40
#: wp-mail-smtp-0.11.2.php:582
msgid "WP Mail SMTP" msgid "WP Mail SMTP"
msgstr "" msgstr ""
#: src/Admin/Area.php:208 #: src/Admin/Area.php:208
#: src/Admin/Area.php:209 #: src/Admin/Area.php:209
#: src/Admin/Area.php:795 #: src/Admin/Area.php:802
#: wp-mail-smtp-0.11.2.php:688
msgid "Settings" msgid "Settings"
msgstr "" msgstr ""
#: src/Admin/Area.php:216 #: src/Admin/Area.php:216
#: src/Admin/Area.php:217 #: src/Admin/Area.php:217
#: src/Admin/Area.php:796
#: src/Admin/Pages/About.php:627 #: src/Admin/Pages/About.php:627
#: src/Admin/Pages/Logs.php:40 #: src/Admin/Pages/Logs.php:40
#: src/Admin/Pages/LogsTab.php:31 #: src/Admin/Pages/LogsTab.php:31
msgid "Email Log" msgid "Email Log"
msgstr "" msgstr ""
#: src/Admin/Area.php:224 #: src/Admin/Area.php:226
#: src/Admin/Area.php:225 #: src/Admin/Area.php:227
#: src/Admin/Pages/About.php:105 #: src/Admin/Pages/About.php:105
msgid "About Us" msgid "About Us"
msgstr "" msgstr ""
#: src/Admin/Area.php:267 #: src/Admin/Area.php:270
msgid "Are you sure you want to reset the current provider connection? You will need to immediately create a new one to be able to send emails." msgid "Are you sure you want to reset the current provider connection? You will need to immediately create a new one to be able to send emails."
msgstr "" msgstr ""
#: src/Admin/Area.php:268 #: src/Admin/Area.php:271
msgid "Changes that you made to the settings are not saved!" msgid "Changes that you made to the settings are not saved!"
msgstr "" msgstr ""
#: src/Admin/Area.php:271 #: src/Admin/Area.php:274
msgid "%name% is a PRO Feature" msgid "%name% is a PRO Feature"
msgstr "" msgstr ""
#: src/Admin/Area.php:272 #: src/Admin/Area.php:275
msgid "Upgrade to Pro" msgid "Upgrade to Pro"
msgstr "" msgstr ""
#: src/Admin/Area.php:276 #: src/Admin/Area.php:279
msgid "<strong>Bonus:</strong> WP Mail SMTP users get <span>20% off</span> regular price,<br>applied at checkout." msgid "<strong>Bonus:</strong> WP Mail SMTP users get <span>$50 off</span> regular price,<br>applied at checkout."
msgstr "" msgstr ""
#: src/Admin/Area.php:285 #: src/Admin/Area.php:288
msgid "Already purchased?" msgid "Already purchased?"
msgstr "" msgstr ""
#: src/Admin/Area.php:352 #: src/Admin/Area.php:355
#: src/Admin/Area.php:359 #: src/Admin/Area.php:362
#: src/Admin/Pages/About.php:308 #: src/Admin/Pages/About.php:308
msgid "Activate" msgid "Activate"
msgstr "" msgstr ""
#: src/Admin/Area.php:353 #: src/Admin/Area.php:356
#: src/Admin/Pages/About.php:300 #: src/Admin/Pages/About.php:300
msgid "Activated" msgid "Activated"
msgstr "" msgstr ""
#: src/Admin/Area.php:354 #: src/Admin/Area.php:357
#: src/Admin/Pages/About.php:297 #: src/Admin/Pages/About.php:297
msgid "Active" msgid "Active"
msgstr "" msgstr ""
#: src/Admin/Area.php:355 #: src/Admin/Area.php:358
#: src/Admin/Pages/About.php:305 #: src/Admin/Pages/About.php:305
msgid "Inactive" msgid "Inactive"
msgstr "" msgstr ""
#: src/Admin/Area.php:356 #: src/Admin/Area.php:359
msgid "Processing..." msgid "Processing..."
msgstr "" msgstr ""
#: src/Admin/Area.php:357 #: src/Admin/Area.php:360
msgid "Could not install a plugin. Please download from WordPress.org and install manually." msgid "Could not install a plugin. Please download from WordPress.org and install manually."
msgstr "" msgstr ""
#: src/Admin/Area.php:358 #: src/Admin/Area.php:361
msgid "Install and Activate" msgid "Install and Activate"
msgstr "" msgstr ""
#: src/Admin/Area.php:360 #: src/Admin/Area.php:363
msgid "Download" msgid "Download"
msgstr "" msgstr ""
#. translators: %1$s - WP.org link; %2$s - same WP.org link. #. translators: %1$s - WP.org link; %2$s - same WP.org link.
#: src/Admin/Area.php:420 #: src/Admin/Area.php:423
msgid "Please rate <strong>WP Mail SMTP</strong> <a href=\"%1$s\" target=\"_blank\" rel=\"noopener noreferrer\">&#9733;&#9733;&#9733;&#9733;&#9733;</a> on <a href=\"%2$s\" target=\"_blank\" rel=\"noopener noreferrer\">WordPress.org</a> to help us spread the word. Thank you from the WP Mail SMTP team!" msgid "Please rate <strong>WP Mail SMTP</strong> <a href=\"%1$s\" target=\"_blank\" rel=\"noopener noreferrer\">&#9733;&#9733;&#9733;&#9733;&#9733;</a> on <a href=\"%2$s\" target=\"_blank\" rel=\"noopener noreferrer\">WordPress.org</a> to help us spread the word. Thank you from the WP Mail SMTP team!"
msgstr "" msgstr ""
#: src/Admin/Area.php:740 #: src/Admin/Area.php:743
msgid "WP Mail SMTP Pro related message was successfully dismissed." msgid "WP Mail SMTP Pro related message was successfully dismissed."
msgstr "" msgstr ""
#: src/Admin/Area.php:759 #: src/Admin/Area.php:762
msgid "Educational notice for this mailer was successfully dismissed." msgid "Educational notice for this mailer was successfully dismissed."
msgstr "" msgstr ""
#: src/Admin/Area.php:801
msgid "Go to WP Mail SMTP Settings page"
msgstr ""
#: src/Admin/Area.php:808
msgid "Go to WP Mail SMTP Lite vs Pro comparison page"
msgstr ""
#: src/Admin/Area.php:809
msgid "Premium Support"
msgstr ""
#: src/Admin/PageAbstract.php:81 #: src/Admin/PageAbstract.php:81
msgid "Save Settings" msgid "Save Settings"
msgstr "" msgstr ""
@ -297,7 +306,7 @@ msgid "Get WP Mail SMTP Pro Today and Unlock all of these Powerful Features"
msgstr "" msgstr ""
#: src/Admin/Pages/About.php:601 #: src/Admin/Pages/About.php:601
msgid "Bonus: WP Mail SMTP Lite users get <span class=\"price-off\">20% off regular price</span>, automatically applied at checkout." msgid "Bonus: WP Mail SMTP Lite users get <span class=\"price-off\">$50 off regular price</span>, automatically applied at checkout."
msgstr "" msgstr ""
#: src/Admin/Pages/About.php:628 #: src/Admin/Pages/About.php:628
@ -451,7 +460,6 @@ msgid "Test emails are allowed to be sent, regardless of this option."
msgstr "" msgstr ""
#. translators: %1$s - constant that was used; %2$s - file where it was used. #. translators: %1$s - constant that was used; %2$s - file where it was used.
#. translators: %1$s - constant name, %2$s - file name.
#: src/Admin/Pages/MiscTab.php:86 #: src/Admin/Pages/MiscTab.php:86
#: src/Providers/OptionsAbstract.php:468 #: src/Providers/OptionsAbstract.php:468
msgid "The value of this field was set using a constant %1$s most likely inside %2$s of your WordPress installation." msgid "The value of this field was set using a constant %1$s most likely inside %2$s of your WordPress installation."
@ -496,7 +504,7 @@ msgid "Check this if you would like to remove ALL WP Mail SMTP data upon plugin
msgstr "" msgstr ""
#: src/Admin/Pages/MiscTab.php:215 #: src/Admin/Pages/MiscTab.php:215
#: src/Admin/Pages/SettingsTab.php:542 #: src/Admin/Pages/SettingsTab.php:540
msgid "Settings were successfully saved." msgid "Settings were successfully saved."
msgstr "" msgstr ""
@ -521,7 +529,6 @@ msgid "Mail"
msgstr "" msgstr ""
#: src/Admin/Pages/SettingsTab.php:92 #: src/Admin/Pages/SettingsTab.php:92
#: wp-mail-smtp-0.11.2.php:246
msgid "From Email" msgid "From Email"
msgstr "" msgstr ""
@ -550,7 +557,6 @@ msgid "If checked, the From Email setting above will be used for all emails, ign
msgstr "" msgstr ""
#: src/Admin/Pages/SettingsTab.php:138 #: src/Admin/Pages/SettingsTab.php:138
#: wp-mail-smtp-0.11.2.php:265
msgid "From Name" msgid "From Name"
msgstr "" msgstr ""
@ -571,18 +577,14 @@ msgid "If checked, the From Name setting above will be used for all emails, igno
msgstr "" msgstr ""
#: src/Admin/Pages/SettingsTab.php:179 #: src/Admin/Pages/SettingsTab.php:179
#: wp-mail-smtp-0.11.2.php:321
#: wp-mail-smtp-0.11.2.php:326
msgid "Return Path" msgid "Return Path"
msgstr "" msgstr ""
#: src/Admin/Pages/SettingsTab.php:188 #: src/Admin/Pages/SettingsTab.php:188
#: wp-mail-smtp-0.11.2.php:331
msgid "Set the return-path to match the From Email" msgid "Set the return-path to match the From Email"
msgstr "" msgstr ""
#: src/Admin/Pages/SettingsTab.php:192 #: src/Admin/Pages/SettingsTab.php:192
#: wp-mail-smtp-0.11.2.php:335
msgid "Return Path indicates where non-delivery receipts - or bounce messages - are to be sent." msgid "Return Path indicates where non-delivery receipts - or bounce messages - are to be sent."
msgstr "" msgstr ""
@ -591,104 +593,105 @@ msgid "If unchecked, bounce messages may be lost. Some providers may ignore this
msgstr "" msgstr ""
#: src/Admin/Pages/SettingsTab.php:201 #: src/Admin/Pages/SettingsTab.php:201
#: wp-mail-smtp-0.11.2.php:280
#: wp-mail-smtp-0.11.2.php:285
msgid "Mailer" msgid "Mailer"
msgstr "" msgstr ""
#: src/Admin/Pages/SettingsTab.php:241 #: src/Admin/Pages/SettingsTab.php:242
#: src/Admin/Pages/SettingsTab.php:245 msgid "Don't see what you're looking for?"
msgstr ""
#: src/Admin/Pages/SettingsTab.php:244
msgid "Suggest a Mailer" msgid "Suggest a Mailer"
msgstr "" msgstr ""
#: src/Admin/Pages/SettingsTab.php:274 #: src/Admin/Pages/SettingsTab.php:272
msgid "Dismiss this notice" msgid "Dismiss this notice"
msgstr "" msgstr ""
#: src/Admin/Pages/SettingsTab.php:316 #: src/Admin/Pages/SettingsTab.php:314
msgid "You're using WP Mail SMTP Lite - no license needed. Enjoy!" msgid "You're using WP Mail SMTP Lite - no license needed. Enjoy!"
msgstr "" msgstr ""
#. translators: %s - WPMailSMTP.com upgrade URL. #. translators: %s - WPMailSMTP.com upgrade URL.
#: src/Admin/Pages/SettingsTab.php:322 #: src/Admin/Pages/SettingsTab.php:320
msgid "To unlock more features consider <strong><a href=\"%s\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"wp-mail-smtp-upgrade-modal\">upgrading to PRO</a></strong>." msgid "To unlock more features consider <strong><a href=\"%s\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"wp-mail-smtp-upgrade-modal\">upgrading to PRO</a></strong>."
msgstr "" msgstr ""
#: src/Admin/Pages/SettingsTab.php:341 #: src/Admin/Pages/SettingsTab.php:339
msgid "As a valued WP Mail SMTP Lite user you receive <strong>20% off</strong>, automatically applied at checkout!" msgid "As a valued WP Mail SMTP Lite user you receive <strong>$50 off</strong>, automatically applied at checkout!"
msgstr "" msgstr ""
#: src/Admin/Pages/SettingsTab.php:402 #: src/Admin/Pages/SettingsTab.php:400
msgid "Get WP Mail SMTP Pro and Unlock all the Powerful Features" msgid "Get WP Mail SMTP Pro and Unlock all the Powerful Features"
msgstr "" msgstr ""
#: src/Admin/Pages/SettingsTab.php:406 #: src/Admin/Pages/SettingsTab.php:404
msgid "Thanks for being a loyal WP Mail SMTP user. Upgrade to WP Mail SMTP Pro to unlock more awesome features and experience why WP Mail SMTP is the most popular SMTP plugin." msgid "Thanks for being a loyal WP Mail SMTP user. Upgrade to WP Mail SMTP Pro to unlock more awesome features and experience why WP Mail SMTP is the most popular SMTP plugin."
msgstr "" msgstr ""
#: src/Admin/Pages/SettingsTab.php:410 #: src/Admin/Pages/SettingsTab.php:408
msgid "We know that you will truly love WP Mail SMTP. It's used by over 1,000,000 websites." msgid "We know that you will truly love WP Mail SMTP. It's used by over 1,000,000 websites."
msgstr "" msgstr ""
#: src/Admin/Pages/SettingsTab.php:413 #: src/Admin/Pages/SettingsTab.php:411
msgid "Pro Features:" msgid "Pro Features:"
msgstr "" msgstr ""
#: src/Admin/Pages/SettingsTab.php:417 #: src/Admin/Pages/SettingsTab.php:415
msgid "Manage Notifications - control which emails your site sends" msgid "Manage Notifications - control which emails your site sends"
msgstr "" msgstr ""
#: src/Admin/Pages/SettingsTab.php:418 #: src/Admin/Pages/SettingsTab.php:416
msgid "Email Logging - keep track of every email sent from your site" msgid "Email Logging - keep track of every email sent from your site"
msgstr "" msgstr ""
#: src/Admin/Pages/SettingsTab.php:419 #: src/Admin/Pages/SettingsTab.php:417
msgid "Office 365 - send emails using your Office 365 account" msgid "Office 365 - send emails using your Office 365 account"
msgstr "" msgstr ""
#: src/Admin/Pages/SettingsTab.php:420 #: src/Admin/Pages/SettingsTab.php:418
msgid "Amazon SES - harness the power of AWS" msgid "Amazon SES - harness the power of AWS"
msgstr "" msgstr ""
#: src/Admin/Pages/SettingsTab.php:421 #: src/Admin/Pages/SettingsTab.php:419
msgid "Outlook.com - send emails using your Outlook.com account" msgid "Outlook.com - send emails using your Outlook.com account"
msgstr "" msgstr ""
#: src/Admin/Pages/SettingsTab.php:422 #: src/Admin/Pages/SettingsTab.php:420
msgid "Access to our world class support team" msgid "Access to our world class support team"
msgstr "" msgstr ""
#: src/Admin/Pages/SettingsTab.php:425 #: src/Admin/Pages/SettingsTab.php:423
msgid "White Glove Setup - sit back and relax while we handle everything for you" msgid "White Glove Setup - sit back and relax while we handle everything for you"
msgstr "" msgstr ""
#: src/Admin/Pages/SettingsTab.php:426 #: src/Admin/Pages/SettingsTab.php:424
msgid "Install WP Mail SMTP Pro plugin" msgid "Install WP Mail SMTP Pro plugin"
msgstr "" msgstr ""
#: src/Admin/Pages/SettingsTab.php:427 #: src/Admin/Pages/SettingsTab.php:425
msgid "Set up domain name verification (DNS)" msgid "Set up domain name verification (DNS)"
msgstr "" msgstr ""
#: src/Admin/Pages/SettingsTab.php:428 #: src/Admin/Pages/SettingsTab.php:426
msgid "Configure Mailgun service" msgid "Configure Mailgun service"
msgstr "" msgstr ""
#: src/Admin/Pages/SettingsTab.php:429 #: src/Admin/Pages/SettingsTab.php:427
msgid "Set up WP Mail SMTP Pro plugin" msgid "Set up WP Mail SMTP Pro plugin"
msgstr "" msgstr ""
#: src/Admin/Pages/SettingsTab.php:430 #: src/Admin/Pages/SettingsTab.php:428
msgid "Test and verify email delivery" msgid "Test and verify email delivery"
msgstr "" msgstr ""
#. translators: %s - WPMailSMTP.com URL. #. translators: %s - WPMailSMTP.com URL.
#: src/Admin/Pages/SettingsTab.php:438 #: src/Admin/Pages/SettingsTab.php:436
msgid "<a href=\"%s\" target=\"_blank\" rel=\"noopener noreferrer\">Get WP Mail SMTP Pro Today and Unlock all the Powerful Features &raquo;</a>" msgid "<a href=\"%s\" target=\"_blank\" rel=\"noopener noreferrer\">Get WP Mail SMTP Pro Today and Unlock all the Powerful Features &raquo;</a>"
msgstr "" msgstr ""
#: src/Admin/Pages/SettingsTab.php:456 #: src/Admin/Pages/SettingsTab.php:454
msgid "<strong>Bonus:</strong> WP Mail SMTP users get <span class=\"price-off\">20% off regular price</span>, automatically applied at checkout." msgid "<strong>Bonus:</strong> WP Mail SMTP users get <span class=\"price-off\">$50 off regular price</span>, automatically applied at checkout."
msgstr "" msgstr ""
#: src/Admin/Pages/TestTab.php:37 #: src/Admin/Pages/TestTab.php:37
@ -696,7 +699,6 @@ msgid "Email Test"
msgstr "" msgstr ""
#: src/Admin/Pages/TestTab.php:59 #: src/Admin/Pages/TestTab.php:59
#: wp-mail-smtp-0.11.2.php:528
msgid "Send a Test Email" msgid "Send a Test Email"
msgstr "" msgstr ""
@ -1086,7 +1088,7 @@ msgstr ""
msgid "Make sure that the used Client ID/Secret correspond to a proper project that has Gmail API enabled." msgid "Make sure that the used Client ID/Secret correspond to a proper project that has Gmail API enabled."
msgstr "" msgstr ""
#. translators: %s - WPForms.com tutorial URL. #. translators: %s - Gmail documentation URL.
#: src/Admin/Pages/TestTab.php:897 #: src/Admin/Pages/TestTab.php:897
msgid "Please follow our <a href=\"%s\" target=\"_blank\" rel=\"noopener noreferrer\">Gmail tutorial</a> to be sure that all the correct project and data is applied." msgid "Please follow our <a href=\"%s\" target=\"_blank\" rel=\"noopener noreferrer\">Gmail tutorial</a> to be sure that all the correct project and data is applied."
msgstr "" msgstr ""
@ -1158,7 +1160,7 @@ msgid "Additionally, you can take advantage of our White Glove Setup. Sit back a
msgstr "" msgstr ""
#: src/Admin/Pages/TestTab.php:1066 #: src/Admin/Pages/TestTab.php:1066
msgid "As a valued WP Mail SMTP user, you will get <span class=\"price-off\">20% off regular pricing</span>, automatically applied at checkout!" msgid "As a valued WP Mail SMTP user, you will get <span class=\"price-off\">$50 off regular pricing</span>, automatically applied at checkout!"
msgstr "" msgstr ""
#. translators: %1$s - WP Mail SMTP support policy URL, %2$s - WP Mail SMTP support forum URL, %3$s - WPMailSMTP.com URL. #. translators: %1$s - WP Mail SMTP support policy URL, %2$s - WP Mail SMTP support forum URL, %3$s - WPMailSMTP.com URL.
@ -1179,46 +1181,36 @@ msgstr ""
msgid "Heads up! WP Mail SMTP has detected %1$s is activated. Please deactivate %2$s to prevent conflicts." msgid "Heads up! WP Mail SMTP has detected %1$s is activated. Please deactivate %2$s to prevent conflicts."
msgstr "" msgstr ""
#. translators: %1$s - WPBeginner URL for recommended WordPress hosting. #. translators: %1$s - WP Mail SMTP plugin name; %2$s - WPMailSMTP.com URL to a related doc.
#: src/Core.php:106 #: src/Core.php:342
msgid "Your site is running an <strong>insecure version</strong> of PHP that is no longer supported. Please contact your web hosting provider to update your PHP version or switch to a <a href=\"%1$s\" target=\"_blank\" rel=\"noopener noreferrer\">recommended WordPress hosting company</a>."
msgstr ""
#. translators: %s - WPForms.com docs URL with more details.
#: src/Core.php:123
msgid "<strong>Note:</strong> WP Mail SMTP plugin is disabled on your site until you fix the issue. <a href=\"%s\" target=\"_blank\" rel=\"noopener noreferrer\">Read more for additional information.</a>"
msgstr ""
#. translators: %1$s - WP Mail SMTP plugin name; %2$s - WPForms.com URL to a related doc.
#: src/Core.php:399
msgid "Your site is running an outdated version of PHP that is no longer supported and may cause issues with %1$s. <a href=\"%2$s\" target=\"_blank\" rel=\"noopener noreferrer\">Read more</a> for additional information." msgid "Your site is running an outdated version of PHP that is no longer supported and may cause issues with %1$s. <a href=\"%2$s\" target=\"_blank\" rel=\"noopener noreferrer\">Read more</a> for additional information."
msgstr "" msgstr ""
#: src/Core.php:413 #: src/Core.php:356
msgid "<strong>Please Note:</strong> Support for PHP 5.3-5.5 will be discontinued in 2020. After this, if no further action is taken, WP Mail SMTP functionality will be disabled." msgid "<strong>Please Note:</strong> Support for PHP 5.5 will be discontinued in 2020. After this, if no further action is taken, WP Mail SMTP functionality will be disabled."
msgstr "" msgstr ""
#. translators: %s - plugin name and its version. #. translators: %s - plugin name and its version.
#: src/Core.php:447 #: src/Core.php:390
msgid "<strong>EMAILING DISABLED:</strong> The %s is currently blocking all emails from being sent." msgid "<strong>EMAILING DISABLED:</strong> The %s is currently blocking all emails from being sent."
msgstr "" msgstr ""
#. translators: %1$s - constant name; %2$s - constant value. #. translators: %1$s - constant name; %2$s - constant value.
#: src/Core.php:458 #: src/Core.php:401
msgid "To send emails, change the value of the %1$s constant to %2$s." msgid "To send emails, change the value of the %1$s constant to %2$s."
msgstr "" msgstr ""
#. translators: %s - plugin Misc settings page URL. #. translators: %s - plugin Misc settings page URL.
#: src/Core.php:469 #: src/Core.php:412
msgid "To send emails, go to plugin <a href=\"%s\">Misc settings</a> and disable the \"Do Not Send\" option." msgid "To send emails, go to plugin <a href=\"%s\">Misc settings</a> and disable the \"Do Not Send\" option."
msgstr "" msgstr ""
#. translators: %s - plugin name and its version. #. translators: %s - plugin name and its version.
#: src/Core.php:501 #: src/Core.php:444
msgid "<strong>EMAIL DELIVERY ERROR:</strong> the plugin %s logged this error during the last time it tried to send an email:" msgid "<strong>EMAIL DELIVERY ERROR:</strong> the plugin %s logged this error during the last time it tried to send an email:"
msgstr "" msgstr ""
#: src/Core.php:531 #: src/Core.php:474
msgid "Consider running an email test after fixing it." msgid "Consider running an email test after fixing it."
msgstr "" msgstr ""
@ -1314,7 +1306,7 @@ msgstr ""
#. translators: %1$s - opening link tag; %2$s - closing link tag; %3$s - opening link tag; %4$s - closing link tag. #. translators: %1$s - opening link tag; %2$s - closing link tag; %3$s - opening link tag; %4$s - closing link tag.
#: src/Providers/Mailgun/Options.php:29 #: src/Providers/Mailgun/Options.php:29
msgid "%1$sMailgun%2$s is one of the leading transactional email services trusted by over 150,000+ businesses.<br>They provide 5,000 free emails per month for 3 months, then $0.80 per 1000 emails.<br><br>Read our %3$sMailgun documentation%4$s to learn how to configure Mailgun and improve your email deliverability." msgid "%1$sMailgun%2$s is one of the leading transactional email services trusted by over 150,000+ businesses. They provide 5,000 free emails per month for 3 months.<br><br>Read our %3$sMailgun documentation%4$s to learn how to configure Mailgun and improve your email deliverability."
msgstr "" msgstr ""
#: src/Providers/Mailgun/Options.php:57 #: src/Providers/Mailgun/Options.php:57
@ -1369,15 +1361,10 @@ msgid "<a href=\"%s\" rel=\"\" target=\"_blank\">More information</a> on Mailgun
msgstr "" msgstr ""
#: src/Providers/OptionsAbstract.php:186 #: src/Providers/OptionsAbstract.php:186
#: wp-mail-smtp-0.11.2.php:355
msgid "SMTP Host" msgid "SMTP Host"
msgstr "" msgstr ""
#: src/Providers/OptionsAbstract.php:200 #: src/Providers/OptionsAbstract.php:200
#: wp-mail-smtp-0.11.2.php:370
#: wp-mail-smtp-0.11.2.php:374
#: wp-mail-smtp-0.11.2.php:489
#: wp-mail-smtp-0.11.2.php:495
msgid "Encryption" msgid "Encryption"
msgstr "" msgstr ""
@ -1398,8 +1385,6 @@ msgid "For most servers TLS is the recommended option. If your SMTP provider off
msgstr "" msgstr ""
#: src/Providers/OptionsAbstract.php:240 #: src/Providers/OptionsAbstract.php:240
#: wp-mail-smtp-0.11.2.php:363
#: wp-mail-smtp-0.11.2.php:481
msgid "SMTP Port" msgid "SMTP Port"
msgstr "" msgstr ""
@ -1412,8 +1397,6 @@ msgid "By default TLS encryption is automatically used if the server supports it
msgstr "" msgstr ""
#: src/Providers/OptionsAbstract.php:276 #: src/Providers/OptionsAbstract.php:276
#: wp-mail-smtp-0.11.2.php:397
#: wp-mail-smtp-0.11.2.php:401
msgid "Authentication" msgid "Authentication"
msgstr "" msgstr ""
@ -1477,7 +1460,7 @@ msgstr ""
#. translators: %1$s - URL to pepipost.com site. #. translators: %1$s - URL to pepipost.com site.
#: src/Providers/PepipostAPI/Options.php:31 #: src/Providers/PepipostAPI/Options.php:31
msgid "<strong><a href=\"%1$s\" target=\"_blank\" rel=\"noopener noreferrer\">Pepipost</a> is a recommended transactional email service.</strong> Every month Pepipost delivers over 8 billion emails from 20,000+ customers. Their mission is to reliably send emails in the most efficient way and at the most disruptive pricing ever. Pepipost provides users 30,000 free emails the first 30 days, then 100 emails per day." msgid "<strong><a href=\"%1$s\" target=\"_blank\" rel=\"noopener noreferrer\">Pepipost</a> is a recommended transactional email service.</strong> Every month Pepipost delivers over 8 billion emails from 20,000+ customers. Their mission is to reliably send emails in the most efficient way and at the most disruptive pricing ever. Pepipost provides users 30,000 free emails the first 30 days."
msgstr "" msgstr ""
#. translators: %1$s - URL to wpmailsmtp.com doc. #. translators: %1$s - URL to wpmailsmtp.com doc.
@ -1486,7 +1469,7 @@ msgid "Read our <a href=\"%2$s\" target=\"_blank\" rel=\"noopener noreferrer\">P
msgstr "" msgstr ""
#: src/Providers/PepipostAPI/Options.php:53 #: src/Providers/PepipostAPI/Options.php:53
msgid "Get Pepipost Now (Free)" msgid "Get Started with Pepipost"
msgstr "" msgstr ""
#: src/Providers/PepipostAPI/Options.php:61 #: src/Providers/PepipostAPI/Options.php:61
@ -1495,14 +1478,14 @@ msgstr ""
#: src/Providers/PepipostAPI/Options.php:88 #: src/Providers/PepipostAPI/Options.php:88
#: src/Providers/Sendgrid/Options.php:57 #: src/Providers/Sendgrid/Options.php:57
#: src/Providers/Sendinblue/Options.php:88 #: src/Providers/Sendinblue/Options.php:76
#: src/Providers/SMTPcom/Options.php:83
msgid "API Key" msgid "API Key"
msgstr "" msgstr ""
#. translators: %s - pepipost.com link to get an API Key. #. translators: %s - link to get an API Key.
#. translators: %s - sendinblue.com link to get an API Key.
#: src/Providers/PepipostAPI/Options.php:107 #: src/Providers/PepipostAPI/Options.php:107
#: src/Providers/Sendinblue/Options.php:107 #: src/Providers/Sendinblue/Options.php:95
msgid "Follow this link to get an API Key: %s." msgid "Follow this link to get an API Key: %s."
msgstr "" msgstr ""
@ -1533,25 +1516,21 @@ msgstr ""
msgid "To send emails you will need only a %s access level for this API key." msgid "To send emails you will need only a %s access level for this API key."
msgstr "" msgstr ""
#. translators: %1$s - URL to sendinblue.com site. #: src/Providers/Sendinblue/Options.php:33
#: src/Providers/Sendinblue/Options.php:31
msgid "<strong><a href=\"%1$s\" target=\"_blank\" rel=\"noopener noreferrer\">Sendinblue</a> is a recommended transactional email service.</strong> Founded in 2012, they serve 80,000+ growing companies around the world and send over 30 million emails each day. They understand that transactional emails are the heart of your customer relationships. Their email deliverability experts are constantly at work optimizing the reliability and speed of their SMTP infrastructure. Sendinblue provides users 300 free emails per day."
msgstr ""
#. translators: %2$s - URL to wpmailsmtp.com doc.
#: src/Providers/Sendinblue/Options.php:34
msgid "Read our <a href=\"%2$s\" target=\"_blank\" rel=\"noopener noreferrer\">Sendinblue documentation</a> to learn how to configure Sendinblue and improve your email deliverability."
msgstr ""
#: src/Providers/Sendinblue/Options.php:53
msgid "Get Sendinblue Now (Free)"
msgstr ""
#: src/Providers/Sendinblue/Options.php:61
msgid "Sendinblue" msgid "Sendinblue"
msgstr "" msgstr ""
#: src/Providers/Sendinblue/Options.php:109 #. translators: %1$s - URL to sendinblue.com site.
#: src/Providers/Sendinblue/Options.php:37
msgid "<a href=\"%1$s\" target=\"_blank\" rel=\"noopener noreferrer\">Sendinblue</a> serves 80,000+ growing companies around the world and sends over 30 million emails each day. They provide users 300 free emails per day."
msgstr ""
#. translators: %2$s - URL to wpmailsmtp.com doc.
#: src/Providers/Sendinblue/Options.php:40
msgid "Read our <a href=\"%2$s\" target=\"_blank\" rel=\"noopener noreferrer\">Sendinblue documentation</a> to learn how to configure Sendinblue and improve your email deliverability."
msgstr ""
#: src/Providers/Sendinblue/Options.php:97
msgid "Get v3 API Key" msgid "Get v3 API Key"
msgstr "" msgstr ""
@ -1559,11 +1538,59 @@ msgstr ""
msgid "Other SMTP" msgid "Other SMTP"
msgstr "" msgstr ""
#. translators: %s - URL to a related article on WPForms.com. #. translators: %s - URL to SMTP documentation.
#: src/Providers/SMTP/Options.php:29 #: src/Providers/SMTP/Options.php:29
msgid "Use the SMTP details provided by your hosting provider or email service.<br><br>To see recommended settings for the popular services as well as troubleshooting tips, check out our <a href=\"%s\" target=\"_blank\" rel=\"noopener noreferrer\">SMTP documentation</a>." msgid "Use the SMTP details provided by your hosting provider or email service.<br><br>To see recommended settings for the popular services as well as troubleshooting tips, check out our <a href=\"%s\" target=\"_blank\" rel=\"noopener noreferrer\">SMTP documentation</a>."
msgstr "" msgstr ""
#: src/Providers/SMTPcom/Mailer.php:433
msgid "Api Key:"
msgstr ""
#: src/Providers/SMTPcom/Mailer.php:435
msgid "Channel:"
msgstr ""
#. translators: %s - URL to smtp.com site.
#: src/Providers/SMTPcom/Options.php:41
msgid "<strong><a href=\"%s\" target=\"_blank\" rel=\"noopener noreferrer\">SMTP.com</a> is a recommended transactional email service.</strong> With over 22 years of email delivery expertise, SMTP.com has been around for almost as long as email itself. They are known among internet providers as one of the most reliable senders on the internet. Their easy integration process lets you start sending emails in minutes and benefit from years of experience. SMTP.com provides users 10,000 free emails the first 30 days."
msgstr ""
#. translators: %s - URL to wpmailsmtp.com doc page for stmp.com.
#: src/Providers/SMTPcom/Options.php:49
msgid "Read our <a href=\"%s\" target=\"_blank\" rel=\"noopener noreferrer\">SMTP.com documentation</a> to learn how to configure SMTP.com and improve your email deliverability."
msgstr ""
#: src/Providers/SMTPcom/Options.php:59
msgid "Get Started with SMTP.com"
msgstr ""
#: src/Providers/SMTPcom/Options.php:67
msgid "SMTP.com"
msgstr ""
#. translators: %s - API key link.
#: src/Providers/SMTPcom/Options.php:101
msgid "Follow this link to get an API Key from SMTP.com: %s."
msgstr ""
#: src/Providers/SMTPcom/Options.php:103
msgid "Get API Key"
msgstr ""
#: src/Providers/SMTPcom/Options.php:114
msgid "Sender Name"
msgstr ""
#. translators: %s - Channel/Sender Name link for smtp.com documentation.
#: src/Providers/SMTPcom/Options.php:130
msgid "Follow this link to get a Sender Name from SMTP.com: %s."
msgstr ""
#: src/Providers/SMTPcom/Options.php:132
msgid "Get Sender Name"
msgstr ""
#: src/SiteHealth.php:67 #: src/SiteHealth.php:67
msgid "Is WP Mail SMTP mailer setup complete?" msgid "Is WP Mail SMTP mailer setup complete?"
msgstr "" msgstr ""
@ -1621,151 +1648,16 @@ msgstr ""
msgid "%1$s \\a\\t %2$s" msgid "%1$s \\a\\t %2$s"
msgstr "" msgstr ""
#: wp-mail-smtp-0.11.2.php:192 #: wp_mail_smtp.php:135
#: wp-mail-smtp-0.11.2.php:546
msgid "Send Test"
msgstr ""
#. translators: %s - email address where test mail will be sent to.
#: wp-mail-smtp-0.11.2.php:201
msgid "Test mail to %s"
msgstr ""
#: wp-mail-smtp-0.11.2.php:202
msgid "This is a test email generated by the WP Mail SMTP WordPress plugin."
msgstr ""
#: wp-mail-smtp-0.11.2.php:218
msgid "Test Message Sent"
msgstr ""
#: wp-mail-smtp-0.11.2.php:219
msgid "The result was:"
msgstr ""
#: wp-mail-smtp-0.11.2.php:222
msgid "The full debugging output is shown below:"
msgstr ""
#: wp-mail-smtp-0.11.2.php:225
msgid "The SMTP debugging output is shown below:"
msgstr ""
#: wp-mail-smtp-0.11.2.php:237
#: wp-mail-smtp-0.11.2.php:582
msgid "WP Mail SMTP Settings"
msgstr ""
#: wp-mail-smtp-0.11.2.php:253
msgid "You can specify the email address that emails should be sent from. If you leave this blank, the default email will be used."
msgstr ""
#: wp-mail-smtp-0.11.2.php:256
msgid "<strong>Please Note:</strong> You appear to be using a version of WordPress prior to 2.3. Please ignore the From Name field and instead enter Name&lt;email@domain.com&gt; in this field."
msgstr ""
#: wp-mail-smtp-0.11.2.php:271
msgid "You can specify the name that emails should be sent from. If you leave this blank, the emails will be sent from WordPress."
msgstr ""
#: wp-mail-smtp-0.11.2.php:290
msgid "Send all WordPress emails via SMTP."
msgstr ""
#: wp-mail-smtp-0.11.2.php:294
msgid "Use the PHP mail() function to send emails."
msgstr ""
#: wp-mail-smtp-0.11.2.php:300
msgid "Use Pepipost SMTP to send emails."
msgstr ""
#. translators: %1$s - link start; %2$s - link end.
#: wp-mail-smtp-0.11.2.php:306
msgid "Looking for high inbox delivery? Try Pepipost with easy setup and free emails. Learn more %1$shere%2$s."
msgstr ""
#: wp-mail-smtp-0.11.2.php:343
#: wp-mail-smtp-0.11.2.php:443
#: wp-mail-smtp-0.11.2.php:519
msgid "Save Changes"
msgstr ""
#: wp-mail-smtp-0.11.2.php:348
msgid "SMTP Options"
msgstr ""
#: wp-mail-smtp-0.11.2.php:350
msgid "These options only apply if you have chosen to send mail by SMTP above."
msgstr ""
#: wp-mail-smtp-0.11.2.php:379
#: wp-mail-smtp-0.11.2.php:501
msgid "No encryption."
msgstr ""
#: wp-mail-smtp-0.11.2.php:384
#: wp-mail-smtp-0.11.2.php:506
msgid "Use SSL encryption."
msgstr ""
#: wp-mail-smtp-0.11.2.php:389
#: wp-mail-smtp-0.11.2.php:511
msgid "Use TLS encryption."
msgstr ""
#: wp-mail-smtp-0.11.2.php:392
msgid "TLS is not the same as STARTTLS. For most servers SSL is the recommended option."
msgstr ""
#: wp-mail-smtp-0.11.2.php:406
msgid "No: Do not use SMTP authentication."
msgstr ""
#: wp-mail-smtp-0.11.2.php:411
msgid "Yes: Use SMTP authentication."
msgstr ""
#: wp-mail-smtp-0.11.2.php:415
msgid "If this is set to no, the values below are ignored."
msgstr ""
#: wp-mail-smtp-0.11.2.php:422
#: wp-mail-smtp-0.11.2.php:465
msgid "Username"
msgstr ""
#: wp-mail-smtp-0.11.2.php:430
#: wp-mail-smtp-0.11.2.php:473
msgid "Password"
msgstr ""
#: wp-mail-smtp-0.11.2.php:436
msgid "This is in plain text because it must not be stored encrypted."
msgstr ""
#: wp-mail-smtp-0.11.2.php:450
msgid "Pepipost SMTP Options"
msgstr ""
#. translators: %s - Pepipost registration URL.
#: wp-mail-smtp-0.11.2.php:456
msgid "You need to signup on %s to get the SMTP username/password."
msgstr ""
#: wp-mail-smtp-0.11.2.php:536
msgid "To"
msgstr ""
#: wp-mail-smtp-0.11.2.php:540
msgid "Type an email address here and then click Send Test to generate a test email."
msgstr ""
#. translators: %1$s - WP Mail SMTP plugin name; %2$s - opening a link tag; %3$s - closing a link tag.
#: wp-mail-smtp-0.11.2.php:727
msgid "Your site is running an outdated version of PHP that is no longer supported and may cause issues with %1$s. %2$sRead more%3$s for additional information."
msgstr ""
#: wp_mail_smtp.php:131
msgid "Please deactivate the free version of the WP Mail SMTP plugin before activating WP Mail SMTP Pro." msgid "Please deactivate the free version of the WP Mail SMTP plugin before activating WP Mail SMTP Pro."
msgstr "" msgstr ""
#. translators: %1$s - WPBeginner URL for recommended WordPress hosting.
#: wp_mail_smtp.php:163
msgid "Your site is running an <strong>insecure version</strong> of PHP that is no longer supported. Please contact your web hosting provider to update your PHP version or switch to a <a href=\"%1$s\" target=\"_blank\" rel=\"noopener noreferrer\">recommended WordPress hosting company</a>."
msgstr ""
#. translators: %s - WPMailSMTP.com docs URL with more details.
#: wp_mail_smtp.php:180
msgid "<strong>WP Mail SMTP plugin is disabled</strong> on your site until you fix the issue. <a href=\"%s\" target=\"_blank\" rel=\"noopener noreferrer\">Read more for additional information.</a>"
msgstr ""

View File

@ -1,29 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<bundle name="WP Mail SMTP">
<domain name="wp-mail-smtp">
<project name="WP Mail SMTP" slug="wp-mail-smtp">
<source>
<directory>.</directory>
</source>
<target>
<directory>assets/languages</directory>
</target>
<template>
<file>assets/languages/wp-mail-smtp.pot</file>
</template>
</project>
</domain>
<domain name="wp-mail-smtp-pro">
<project name="WP Mail SMTP Pro" slug="wp-mail-smtp-pro">
<source>
<directory>.</directory>
</source>
<target>
<directory>assets/pro/languages</directory>
</target>
<template>
<file>assets/pro/languages/wp-mail-smtp-pro.pot</file>
</template>
</project>
</domain>
</bundle>

View File

@ -2,9 +2,9 @@
Contributors: wpforms, jaredatch, smub, slaFFik Contributors: wpforms, jaredatch, smub, slaFFik
Tags: smtp, wp mail smtp, wordpress smtp, gmail smtp, sendgrid smtp, mailgun smtp, mail, mailer, phpmailer, wp_mail, email, mailgun, sengrid, gmail, pepipost, sendinblue, wp smtp Tags: smtp, wp mail smtp, wordpress smtp, gmail smtp, sendgrid smtp, mailgun smtp, mail, mailer, phpmailer, wp_mail, email, mailgun, sengrid, gmail, pepipost, sendinblue, wp smtp
Requires at least: 4.9 Requires at least: 4.9
Tested up to: 5.3 Tested up to: 5.4
Stable tag: 1.9.0 Stable tag: 2.0.0
Requires PHP: 5.3 Requires PHP: 5.5.0
The most popular WordPress SMTP and PHP Mailer plugin. Trusted by over 1 million sites. The most popular WordPress SMTP and PHP Mailer plugin. Trusted by over 1 million sites.
@ -42,19 +42,30 @@ This helps you fix all WordPress not sending email issues.
WP Mail SMTP plugin includes many different SMTP setup options: WP Mail SMTP plugin includes many different SMTP setup options:
1. Pepipost SMTP <strong>(Recommended)</strong> 1. SMTP.com <strong>(Recommended)</strong>
2. Sendinblue SMTP <strong>(Recommended)</strong> 2. Pepipost SMTP <strong>(Recommended)</strong>
3. Mailgun SMTP 3. Sendinblue SMTP
4. SendGrid SMTP 4. Mailgun SMTP
5. Gmail SMTP 5. SendGrid SMTP
6. Microsoft SMTP (Outlook.com and Office 365) <a href="https://wpmailsmtp.com/?utm_source=wprepo&utm_medium=link&utm_campaign=liteversion&utm_content=readme" rel="friend">[Pro]</a> 6. Gmail SMTP
7. Amazon SES SMTP <a href="https://wpmailsmtp.com/?utm_source=wprepo&utm_medium=link&utm_campaign=liteversion&utm_content=readme" rel="friend">[Pro]</a> 7. Microsoft SMTP (Outlook.com and Office 365) <a href="https://wpmailsmtp.com/?utm_source=wprepo&utm_medium=link&utm_campaign=liteversion&utm_content=readme" rel="friend">[Pro]</a>
8. All Other SMTP 8. Amazon SES SMTP <a href="https://wpmailsmtp.com/?utm_source=wprepo&utm_medium=link&utm_campaign=liteversion&utm_content=readme" rel="friend">[Pro]</a>
9. All Other SMTP
For all options, you can specify the "from name" and "email address" for outgoing emails. For all options, you can specify the "from name" and "email address" for outgoing emails.
Instead of having users use different SMTP plugins and workflows for different SMTP providers, we decided to bring it all in one. This is what makes WP Mail SMTP, the best SMTP solution for WordPress. Instead of having users use different SMTP plugins and workflows for different SMTP providers, we decided to bring it all in one. This is what makes WP Mail SMTP, the best SMTP solution for WordPress.
= SMTP.COM =
SMTP.com is a recommended transactional email service.
With over 22 years of email delivery expertise, SMTP.com has been around for almost as long as email itself. They are known among internet providers as one of the most reliable senders on the internet.
Their easy integration process lets you start sending emails in minutes and benefit from years of experience. SMTP.com provides users 10,000 free emails the first 30 days.
Read our <a href="https://wpmailsmtp.com/docs/how-to-set-up-the-smtp-com-mailer-in-wp-mail-smtp" rel="friend">SMTP.com documentation</a> for more details.
= Pepipost SMTP = = Pepipost SMTP =
Pepipost is a recommended transactional email service. Pepipost is a recommended transactional email service.
@ -68,8 +79,6 @@ Read our <a href="https://wpmailsmtp.com/docs/how-to-set-up-the-pepipost-mailer-
= Sendinblue SMTP = = Sendinblue SMTP =
Sendinblue is a recommended transactional email service.
They serve 80,000+ growing companies around the world and send over 30 million emails each day. They serve 80,000+ growing companies around the world and send over 30 million emails each day.
Their email deliverability experts are constantly at work optimizing the reliability and speed of their SMTP infrastructure. Sendinblue provides users 300 free emails per day. Their email deliverability experts are constantly at work optimizing the reliability and speed of their SMTP infrastructure. Sendinblue provides users 300 free emails per day.
@ -154,7 +163,7 @@ You can sit back and relax while we set up everything for you. White glove setup
The WP Mail SMTP team takes security very seriously. Not only does the plugin follow all security best practices, but we have several options available to ensure your site is safe and secure. The WP Mail SMTP team takes security very seriously. Not only does the plugin follow all security best practices, but we have several options available to ensure your site is safe and secure.
- Direct SMTP mailer integrations (recommended), such as Google and Mailgun, use the official provider APIs. This means you never enter your username or password in the plugin settings and these credentials are not stored in the database. Instead, we use tokens or API keys which are much more secure. - Direct SMTP mailer integrations (recommended), such as SMTP.com, Pepipost and Mailgun, use the official provider APIs. This means you never enter your username or password in the plugin settings and these credentials are not stored in the database. Instead, we use tokens or API keys which are much more secure.
- When using Other SMTP mailer, we provide the option to insert your password in your `wp-config.php` file, so it's not visible in your WordPress settings or saved in the database. - When using Other SMTP mailer, we provide the option to insert your password in your `wp-config.php` file, so it's not visible in your WordPress settings or saved in the database.
@ -188,7 +197,7 @@ Visit <a href="http://www.wpbeginner.com/" rel="friend" title="WPBeginner">WPBeg
Yes! We have extensive documentation that covers setting up SMTP most popular email services. Yes! We have extensive documentation that covers setting up SMTP most popular email services.
<a href="https://wpforms.com/docs/how-to-set-up-smtp-using-the-wp-mail-smtp-plugin/" rel="friend">Read our docs</a> to see the correct SMTP settings for each service. <a href="https://wpmailsmtp.com/docs/a-complete-guide-to-wp-mail-smtp-mailers/" rel="friend">Read our docs</a> to see the correct SMTP settings for each service.
= Help! I need support or have an issue. = = Help! I need support or have an issue. =
@ -220,6 +229,13 @@ By all means please contact us to discuss features or options you'd like to see
== Changelog == == Changelog ==
= 2.0.0 - 2020-04-27 =
* IMPORTANT: Support for PHP 5.2-5.4 has been discontinued. If you are running one of those versions, you MUST upgrade PHP before installing or upgrading to WP Mail SMTP v2.0. Failure to do that will disable WP Mail SMTP functionality.
* Added: new mailer - SMTP.com integration.
* Changed: Plugin filters that change the FROM Name/Email in emails are now always running last.
* Fixed: `false` value of the `WPMS_SMTP_AUTH`/`WPMS_SMTP_AUTOTLS` constants was not properly handled in UI.
* Fixed: various minor code and internal links improvements.
= 1.9.0 - 2020-03-23 = = 1.9.0 - 2020-03-23 =
* Added: Add various Status tests and Info section on Tools > Site Health page. * Added: Add various Status tests and Info section on Tools > Site Health page.
* Added: Notify admin if there are unsaved changes in plugin admin area options. * Added: Notify admin if there are unsaved changes in plugin admin area options.

View File

@ -57,7 +57,7 @@ class Area {
protected function hooks() { protected function hooks() {
// Add the Settings link to a plugin on Plugins page. // Add the Settings link to a plugin on Plugins page.
add_filter( 'plugin_action_links', array( $this, 'add_plugin_action_link' ), 10, 2 ); add_filter( 'plugin_action_links_' . plugin_basename( WPMS_PLUGIN_FILE ), array( $this, 'add_plugin_action_link' ), 10, 1 );
// Add the options page. // Add the options page.
add_action( 'admin_menu', array( $this, 'add_admin_options_page' ) ); add_action( 'admin_menu', array( $this, 'add_admin_options_page' ) );
@ -219,14 +219,17 @@ class Area {
self::SLUG . '-logs', self::SLUG . '-logs',
array( $this, 'display' ) array( $this, 'display' )
); );
\add_submenu_page(
self::SLUG, if ( ! wp_mail_smtp()->is_white_labeled() ) {
\esc_html__( 'About Us', 'wp-mail-smtp' ), \add_submenu_page(
\esc_html__( 'About Us', 'wp-mail-smtp' ), self::SLUG,
'manage_options', \esc_html__( 'About Us', 'wp-mail-smtp' ),
self::SLUG . '-about', \esc_html__( 'About Us', 'wp-mail-smtp' ),
array( $this, 'display' ) 'manage_options',
); self::SLUG . '-about',
array( $this, 'display' )
);
}
} }
/** /**
@ -273,7 +276,7 @@ class Area {
'upgrade_url' => 'https://wpmailsmtp.com/lite-upgrade/?discount=SMTPLITEUPGRADE&utm_source=WordPress&utm_medium=plugin-settings&utm_campaign=liteplugin', 'upgrade_url' => 'https://wpmailsmtp.com/lite-upgrade/?discount=SMTPLITEUPGRADE&utm_source=WordPress&utm_medium=plugin-settings&utm_campaign=liteplugin',
'upgrade_bonus' => '<p>' . 'upgrade_bonus' => '<p>' .
wp_kses( wp_kses(
__( '<strong>Bonus:</strong> WP Mail SMTP users get <span>20% off</span> regular price,<br>applied at checkout.', 'wp-mail-smtp' ), __( '<strong>Bonus:</strong> WP Mail SMTP users get <span>$50 off</span> regular price,<br>applied at checkout.', 'wp-mail-smtp' ),
array( array(
'strong' => true, 'strong' => true,
'span' => true, 'span' => true,
@ -368,7 +371,7 @@ class Area {
\wp_enqueue_script( \wp_enqueue_script(
'wp-mail-smtp-admin-about-matchheight', 'wp-mail-smtp-admin-about-matchheight',
\wp_mail_smtp()->assets_url . '/js/jquery.matchHeight.min.js', \wp_mail_smtp()->assets_url . '/js/vendor/jquery.matchHeight.min.js',
array( 'wp-mail-smtp-admin' ), array( 'wp-mail-smtp-admin' ),
'0.7.2', '0.7.2',
false false
@ -394,7 +397,7 @@ class Area {
<div id="wp-mail-smtp-header-temp"></div> <div id="wp-mail-smtp-header-temp"></div>
<div id="wp-mail-smtp-header"> <div id="wp-mail-smtp-header">
<!--suppress HtmlUnknownTarget --> <!--suppress HtmlUnknownTarget -->
<img class="wp-mail-smtp-header-logo" src="<?php echo esc_url( wp_mail_smtp()->assets_url ); ?>/images/logo.svg" alt="WP Mail SMTP"/> <img class="wp-mail-smtp-header-logo" src="<?php echo esc_url( wp_mail_smtp()->assets_url ); ?>/images/logo<?php echo wp_mail_smtp()->is_white_labeled() ? '-whitelabel' : ''; ?>.svg" alt="WP Mail SMTP"/>
</div> </div>
<?php <?php
@ -775,29 +778,38 @@ class Area {
} }
/** /**
* Add a link to Settings page of a plugin on Plugins page. * Add plugin action links on Plugins page (lite version only).
* *
* @since 1.0.0 * @since 1.0.0
* @since 1.5.0 Added a link to Email Log. * @since 1.5.0 Added a link to Email Log.
* @since 2.0.0 Adjusted links. Process only the Lite plugin.
* *
* @param array $links * @param array $links Existing plugin action links.
* @param string $file
* *
* @return mixed * @return array
*/ */
public function add_plugin_action_link( $links, $file ) { public function add_plugin_action_link( $links ) {
// Will target both pro and lite version of a plugin. // Do not register lite plugin action links if on pro version.
if ( strpos( $file, 'wp-mail-smtp' ) === false ) { if ( wp_mail_smtp()->is_pro() ) {
return $links; return $links;
} }
$settings_link = '<a href="' . esc_url( $this->get_admin_page_url() ) . '">' . esc_html__( 'Settings', 'wp-mail-smtp' ) . '</a>'; $custom['settings'] = sprintf(
$logs_link = '<a href="' . esc_url( $this->get_admin_page_url( self::SLUG . '-logs' ) ) . '">' . esc_html__( 'Email Log', 'wp-mail-smtp' ) . '</a>'; '<a href="%s" aria-label="%s">%s</a>',
esc_url( $this->get_admin_page_url() ),
esc_attr__( 'Go to WP Mail SMTP Settings page', 'wp-mail-smtp' ),
esc_html__( 'Settings', 'wp-mail-smtp' )
);
array_unshift( $links, $settings_link, $logs_link ); $custom['support'] = sprintf(
'<a href="%1$s" aria-label="%2$s" style="font-weight:bold;">%3$s</a>',
esc_url( add_query_arg( 'tab','versus', $this->get_admin_page_url( Area::SLUG . '-about' ) ) ),
esc_attr__( 'Go to WP Mail SMTP Lite vs Pro comparison page', 'wp-mail-smtp' ),
esc_html__( 'Premium Support', 'wp-mail-smtp' )
);
return $links; return array_merge( $custom, (array) $links );
} }
/** /**

View File

@ -598,7 +598,7 @@ class About extends PageAbstract {
<p class="centered"> <p class="centered">
<?php <?php
echo \wp_kses( echo \wp_kses(
\__( 'Bonus: WP Mail SMTP Lite users get <span class="price-off">20% off regular price</span>, automatically applied at checkout.', 'wp-mail-smtp' ), \__( 'Bonus: WP Mail SMTP Lite users get <span class="price-off">$50 off regular price</span>, automatically applied at checkout.', 'wp-mail-smtp' ),
array( array(
'span' => array( 'span' => array(
'class' => array(), 'class' => array(),

View File

@ -234,18 +234,16 @@ class SettingsTab extends PageAbstract {
</div> </div>
<?php endforeach; ?> <?php endforeach; ?>
</div>
<!-- Suggest a mailer --> <!-- Suggest a mailer -->
<div class="wp-mail-smtp-mailer suggest-new"> <div class="wp-mail-smtp-suggest-new-mailer">
<a href="https://wpmailsmtp.com/suggest-a-mailer" class="wp-mail-smtp-mailer-image" target="_blank" rel="noopener noreferrer"> <p class="desc">
<?php esc_html_e( 'Don\'t see what you\'re looking for?', 'wp-mail-smtp' ); ?>
<a href="https://wpmailsmtp.com/suggest-a-mailer" target="_blank" rel="noopener noreferrer">
<?php esc_html_e( 'Suggest a Mailer', 'wp-mail-smtp' ); ?> <?php esc_html_e( 'Suggest a Mailer', 'wp-mail-smtp' ); ?>
</a> </a>
</p>
<div class="wp-mail-smtp-mailer-text">
<label><?php esc_html_e( 'Suggest a Mailer', 'wp-mail-smtp' ); ?></label>
</div>
</div>
</div> </div>
</div> </div>
</div> </div>
@ -338,7 +336,7 @@ class SettingsTab extends PageAbstract {
<p class="desc"> <p class="desc">
<?php <?php
echo wp_kses( echo wp_kses(
__( 'As a valued WP Mail SMTP Lite user you receive <strong>20% off</strong>, automatically applied at checkout!', 'wp-mail-smtp' ), __( 'As a valued WP Mail SMTP Lite user you receive <strong>$50 off</strong>, automatically applied at checkout!', 'wp-mail-smtp' ),
array( array(
'strong' => array(), 'strong' => array(),
'br' => array(), 'br' => array(),
@ -453,7 +451,7 @@ class SettingsTab extends PageAbstract {
<p> <p>
<?php <?php
echo wp_kses( echo wp_kses(
__( '<strong>Bonus:</strong> WP Mail SMTP users get <span class="price-off">20% off regular price</span>, automatically applied at checkout.', 'wp-mail-smtp' ), __( '<strong>Bonus:</strong> WP Mail SMTP users get <span class="price-off">$50 off regular price</span>, automatically applied at checkout.', 'wp-mail-smtp' ),
array( array(
'strong' => array(), 'strong' => array(),
'span' => array( 'span' => array(

View File

@ -253,7 +253,7 @@ class TestTab extends PageAbstract {
<!-- Header --> <!-- Header -->
<tr style="padding: 0; vertical-align: top; text-align: left;"> <tr style="padding: 0; vertical-align: top; text-align: left;">
<td align="center" valign="middle" class="header" style="word-wrap: break-word; -webkit-hyphens: auto; -moz-hyphens: auto; hyphens: auto; border-collapse: collapse !important; vertical-align: top; mso-table-lspace: 0pt; mso-table-rspace: 0pt; -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; color: #444; font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; font-weight: normal; margin: 0; Margin: 0; font-size: 14px; mso-line-height-rule: exactly; line-height: 140%; text-align: center; padding: 30px 30px 22px 30px;"> <td align="center" valign="middle" class="header" style="word-wrap: break-word; -webkit-hyphens: auto; -moz-hyphens: auto; hyphens: auto; border-collapse: collapse !important; vertical-align: top; mso-table-lspace: 0pt; mso-table-rspace: 0pt; -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; color: #444; font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; font-weight: normal; margin: 0; Margin: 0; font-size: 14px; mso-line-height-rule: exactly; line-height: 140%; text-align: center; padding: 30px 30px 22px 30px;">
<img src="<?php echo esc_url( wp_mail_smtp()->plugin_url . '/assets/images/email/wp-mail-smtp.png' ); ?>" width="250" alt="WP Mail SMTP Logo" style="outline: none; text-decoration: none; max-width: 100%; clear: both; -ms-interpolation-mode: bicubic; display: inline-block !important; width: 250px;"> <img src="<?php echo esc_url( wp_mail_smtp()->plugin_url . '/assets/images/email/wp-mail-smtp' . ( wp_mail_smtp()->is_white_labeled() ? '-whitelabel' : '' ) . '.png' ); ?>" width="250" alt="WP Mail SMTP Logo" style="outline: none; text-decoration: none; max-width: 100%; clear: both; -ms-interpolation-mode: bicubic; display: inline-block !important; width: 250px;">
</td> </td>
</tr> </tr>
<!-- Content --> <!-- Content -->
@ -296,7 +296,7 @@ class TestTab extends PageAbstract {
Access to our world class support team Access to our world class support team
</p> </p>
<p class="text-large last" style="-ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; color: #444; font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; font-weight: normal; padding: 0; mso-line-height-rule: exactly; line-height: 140%; font-size: 13px; text-align: center; margin: 0 0 0 0; Margin: 0 0 0 0;"> <p class="text-large last" style="-ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; color: #444; font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; font-weight: normal; padding: 0; mso-line-height-rule: exactly; line-height: 140%; font-size: 13px; text-align: center; margin: 0 0 0 0; Margin: 0 0 0 0;">
WP Mail SMTP users get <span style="font-weight:700;color:#218900;">20% off</span>, automatically applied at checkout WP Mail SMTP users get <span style="font-weight:700;color:#218900;">$50 off</span>, automatically applied at checkout
</p> </p>
<center style="width: 100%;"> <center style="width: 100%;">
<table class="button large expanded orange" style="border-collapse: collapse; border-spacing: 0; padding: 0; vertical-align: top; text-align: left; mso-table-lspace: 0pt; mso-table-rspace: 0pt; -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; color: #e27730; width: 100% !important;"> <table class="button large expanded orange" style="border-collapse: collapse; border-spacing: 0; padding: 0; vertical-align: top; text-align: left; mso-table-lspace: 0pt; mso-table-rspace: 0pt; -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; color: #e27730; width: 100% !important;">
@ -343,7 +343,7 @@ class TestTab extends PageAbstract {
// phpcs:disable // phpcs:disable
if ( wp_mail_smtp()->is_pro() ) { if ( wp_mail_smtp()->is_pro() ) {
// WP Mail SMTP Pro & WPForms paid installed. // WP Mail SMTP Pro paid installed.
$message = $message =
'Congrats, test email was sent successfully! 'Congrats, test email was sent successfully!
@ -705,7 +705,7 @@ Lead Developer, WP Mail SMTP';
), ),
) )
), ),
'https://wpforms.com/how-to-send-wordpress-emails-with-mailgun/' 'https://wpmailsmtp.com/docs/how-to-set-up-the-mailgun-mailer-in-wp-mail-smtp/'
), ),
esc_html__( 'Complete the steps in section "2. Verify Your Domain".', 'wp-mail-smtp' ), esc_html__( 'Complete the steps in section "2. Verify Your Domain".', 'wp-mail-smtp' ),
), ),
@ -893,7 +893,7 @@ Lead Developer, WP Mail SMTP';
esc_html__( 'Make sure that the used Client ID/Secret correspond to a proper project that has Gmail API enabled.', 'wp-mail-smtp' ), esc_html__( 'Make sure that the used Client ID/Secret correspond to a proper project that has Gmail API enabled.', 'wp-mail-smtp' ),
sprintf( sprintf(
wp_kses( wp_kses(
/* translators: %s - WPForms.com tutorial URL. */ /* translators: %s - Gmail documentation URL. */
esc_html__( 'Please follow our <a href="%s" target="_blank" rel="noopener noreferrer">Gmail tutorial</a> to be sure that all the correct project and data is applied.', 'wp-mail-smtp' ), esc_html__( 'Please follow our <a href="%s" target="_blank" rel="noopener noreferrer">Gmail tutorial</a> to be sure that all the correct project and data is applied.', 'wp-mail-smtp' ),
array( array(
'a' => array( 'a' => array(
@ -903,7 +903,7 @@ Lead Developer, WP Mail SMTP';
), ),
) )
), ),
'https://wpforms.com/how-to-securely-send-wordpress-emails-using-gmail-smtp/' 'https://wpmailsmtp.com/docs/how-to-set-up-the-gmail-mailer-in-wp-mail-smtp/'
), ),
), ),
), ),
@ -1063,7 +1063,7 @@ Lead Developer, WP Mail SMTP';
<p> <p>
<?php <?php
echo wp_kses( echo wp_kses(
__( 'As a valued WP Mail SMTP user, you will get <span class="price-off">20% off regular pricing</span>, automatically applied at checkout!', 'wp-mail-smtp' ), __( 'As a valued WP Mail SMTP user, you will get <span class="price-off">$50 off regular pricing</span>, automatically applied at checkout!', 'wp-mail-smtp' ),
array( array(
'span' => array( 'span' => array(
'class' => array(), 'class' => array(),

View File

@ -57,7 +57,7 @@ class Core {
$this->plugin_path = rtrim( plugin_dir_path( __DIR__ ), '/\\' ); $this->plugin_path = rtrim( plugin_dir_path( __DIR__ ), '/\\' );
if ( $this->is_not_loadable() ) { if ( $this->is_not_loadable() ) {
$this->do_not_load(); add_action( 'admin_notices', 'wp_mail_smtp_insecure_php_version_notice' );
return; return;
} }
@ -88,63 +88,6 @@ class Core {
return false; return false;
} }
/**
* What to do if plugin is not loaded.
*
* @since 1.5.0
*/
protected function do_not_load() {
add_action( 'admin_notices', function () {
?>
<div class="notice notice-error">
<p>
<?php
printf(
wp_kses( /* translators: %1$s - WPBeginner URL for recommended WordPress hosting. */
__( 'Your site is running an <strong>insecure version</strong> of PHP that is no longer supported. Please contact your web hosting provider to update your PHP version or switch to a <a href="%1$s" target="_blank" rel="noopener noreferrer">recommended WordPress hosting company</a>.', 'wp-mail-smtp' ),
array(
'a' => array(
'href' => array(),
'target' => array(),
'rel' => array(),
),
'strong' => array(),
)
),
'https://www.wpbeginner.com/wordpress-hosting/'
);
?>
<br><br>
<?php
printf(
wp_kses( /* translators: %s - WPForms.com docs URL with more details. */
__( '<strong>Note:</strong> WP Mail SMTP plugin is disabled on your site until you fix the issue. <a href="%s" target="_blank" rel="noopener noreferrer">Read more for additional information.</a>', 'wp-mail-smtp' ),
array(
'a' => array(
'href' => array(),
'target' => array(),
'rel' => array(),
),
'strong' => array(),
)
),
'https://wpforms.com/docs/supported-php-version/'
);
?>
</p>
</div>
<?php
// In case this is on plugin activation.
if ( isset( $_GET['activate'] ) ) { //phpcs:ignore
unset( $_GET['activate'] ); //phpcs:ignore
}
} );
}
/** /**
* Assign all hooks to proper places. * Assign all hooks to proper places.
* *
@ -153,7 +96,7 @@ class Core {
public function hooks() { public function hooks() {
// Activation hook. // Activation hook.
add_action( 'activate_plugin', array( $this, 'activate' ), 10, 2 ); register_activation_hook( WPMS_PLUGIN_FILE, array( $this, 'activate' ) );
// Redefine PHPMailer. // Redefine PHPMailer.
add_action( 'plugins_loaded', array( $this, 'get_processor' ) ); add_action( 'plugins_loaded', array( $this, 'get_processor' ) );
@ -362,7 +305,7 @@ class Core {
/** /**
* Get the plugin's WP Site Health object. * Get the plugin's WP Site Health object.
* *
* @since {VERSION} * @since 1.9.0
* *
* @return SiteHealth * @return SiteHealth
*/ */
@ -395,7 +338,7 @@ class Core {
) { ) {
WP::add_admin_notice( WP::add_admin_notice(
sprintf( sprintf(
wp_kses( /* translators: %1$s - WP Mail SMTP plugin name; %2$s - WPForms.com URL to a related doc. */ wp_kses( /* translators: %1$s - WP Mail SMTP plugin name; %2$s - WPMailSMTP.com URL to a related doc. */
__( 'Your site is running an outdated version of PHP that is no longer supported and may cause issues with %1$s. <a href="%2$s" target="_blank" rel="noopener noreferrer">Read more</a> for additional information.', 'wp-mail-smtp' ), __( 'Your site is running an outdated version of PHP that is no longer supported and may cause issues with %1$s. <a href="%2$s" target="_blank" rel="noopener noreferrer">Read more</a> for additional information.', 'wp-mail-smtp' ),
array( array(
'a' => array( 'a' => array(
@ -406,11 +349,11 @@ class Core {
) )
), ),
'<strong>WP Mail SMTP</strong>', '<strong>WP Mail SMTP</strong>',
'https://wpforms.com/docs/supported-php-version/' 'https://wpmailsmtp.com/docs/supported-php-versions-for-wp-mail-smtp/'
) . ) .
'<br><br><em>' . '<br><br><em>' .
wp_kses( wp_kses(
__( '<strong>Please Note:</strong> Support for PHP 5.3-5.5 will be discontinued in 2020. After this, if no further action is taken, WP Mail SMTP functionality will be disabled.', 'wp-mail-smtp' ), __( '<strong>Please Note:</strong> Support for PHP 5.5 will be discontinued in 2020. After this, if no further action is taken, WP Mail SMTP functionality will be disabled.', 'wp-mail-smtp' ),
array( array(
'strong' => array(), 'strong' => array(),
'em' => array(), 'em' => array(),
@ -618,12 +561,9 @@ class Core {
* What to do on plugin activation. * What to do on plugin activation.
* *
* @since 1.0.0 * @since 1.0.0
* * @since 2.0.0 Changed from general `plugin_activate` hook to this plugin specific activation hook.
* @param string $plugin Path to the plugin file relative to the plugins directory.
* @param bool $network_wide Whether to enable the plugin for all sites in the network
* or just the current site. Multisite only. Default is false.
*/ */
public function activate( $plugin, $network_wide ) { public function activate() {
// Store the plugin version when initial install occurred. // Store the plugin version when initial install occurred.
add_option( 'wp_mail_smtp_initial_version', WPMS_PLUGIN_VER, '', false ); add_option( 'wp_mail_smtp_initial_version', WPMS_PLUGIN_VER, '', false );
@ -735,4 +675,18 @@ class Core {
return (bool) Options::init()->get( 'general', 'do_not_send' ); return (bool) Options::init()->get( 'general', 'do_not_send' );
} }
/**
* Whether the white-labeling is enabled.
* White-labeling disables the plugin "About us" page, it replaces any plugin marketing texts or images with
* white label ones.
*
* @since 2.0.0
*
* @return bool
*/
public function is_white_labeled() {
return (bool) apply_filters( 'wp_mail_smtp_is_white_labeled', false );
}
} }

View File

@ -1,163 +1,164 @@
<?php <?php
namespace WPMailSMTP; namespace WPMailSMTP;
/** /**
* Class Geo to work with location, domain, IPs etc. * Class Geo to work with location, domain, IPs etc.
* *
* @since 1.5.0 * @since 1.5.0
*/ */
class Geo { class Geo {
/** /**
* Get the current site hostname. * Get the current site hostname.
* In case of CLI we don't have SERVER_NAME, so use host name instead, may be not a domain name. * In case of CLI we don't have SERVER_NAME, so use host name instead, may be not a domain name.
* Examples: example.com, localhost. * Examples: example.com, localhost.
* *
* @since 1.5.0 * @since 1.5.0
* *
* @return string * @return string
*/ */
public static function get_site_domain() { public static function get_site_domain() {
return ! empty( $_SERVER['SERVER_NAME'] ) ? wp_unslash( $_SERVER['SERVER_NAME'] ) : wp_parse_url( get_home_url( get_current_blog_id() ), PHP_URL_HOST ); return ! empty( $_SERVER['SERVER_NAME'] ) ? wp_unslash( $_SERVER['SERVER_NAME'] ) : wp_parse_url( get_home_url( get_current_blog_id() ), PHP_URL_HOST );
} }
/** /**
* Get the domain IP address. * Get the domain IP address.
* Uses gethostbyname() which is quite slow, but this is done only one time. * Uses gethostbyname() which is quite slow, but this is done only one time.
* *
* @since 1.5.0 * @since 1.5.0
* *
* @param string $domain * @param string $domain
* *
* @return string * @return string
*/ */
public static function get_ip_by_domain( $domain ) { public static function get_ip_by_domain( $domain ) {
if ( $domain === 'localhost' ) { if ( $domain === 'localhost' ) {
return '127.0.0.1'; return '127.0.0.1';
} }
return gethostbyname( $domain ); return gethostbyname( $domain );
} }
/** /**
* Get the location coordinates by IP address. * Get the location coordinates by IP address.
* We make a request to 3rd party services. * We make a request to 3rd party services.
* *
* @since 1.5.0 * @since 1.5.0
* @since 1.6.0 Added new geo API endpoint, provided by WPForms. * @since 1.6.0 Added new geo API endpoint, provided by WPForms.
* * @since 2.0.0 Updated the WPForms geo API endpoint to v3.
* @param string $ip *
* * @param string $ip
* @return array Empty array for localhost. *
*/ * @return array Empty array for localhost.
public static function get_location_by_ip( $ip ) { */
public static function get_location_by_ip( $ip ) {
// Check for a non-local IP.
if ( empty( $ip ) || in_array( $ip, array( '127.0.0.1', '::1' ), true ) ) { // Check for a non-local IP.
return array(); if ( empty( $ip ) || in_array( $ip, array( '127.0.0.1', '::1' ), true ) ) {
} return array();
}
$request = wp_remote_get( 'https://geo.wpforms.com/v2/geolocate/json/' . $ip );
$request = wp_remote_get( 'https://geo.wpforms.com/v3/geolocate/json/' . $ip );
if ( ! is_wp_error( $request ) ) {
$request = json_decode( wp_remote_retrieve_body( $request ), true ); if ( ! is_wp_error( $request ) ) {
if ( ! empty( $request['latitude'] ) && ! empty( $request['longitude'] ) ) { $request = json_decode( wp_remote_retrieve_body( $request ), true );
$data = array( if ( ! empty( $request['latitude'] ) && ! empty( $request['longitude'] ) ) {
'latitude' => sanitize_text_field( $request['latitude'] ), $data = array(
'longitude' => sanitize_text_field( $request['longitude'] ), 'latitude' => sanitize_text_field( $request['latitude'] ),
'city' => sanitize_text_field( $request['city'] ), 'longitude' => sanitize_text_field( $request['longitude'] ),
'region' => sanitize_text_field( $request['region_name'] ), 'city' => sanitize_text_field( $request['city'] ),
'country' => sanitize_text_field( $request['country_code'] ), 'region' => sanitize_text_field( $request['region_name'] ),
'postal' => sanitize_text_field( $request['zip_code'] ), 'country' => sanitize_text_field( $request['country_iso'] ),
); 'postal' => sanitize_text_field( $request['zip_code'] ),
);
return $data;
} return $data;
} }
}
$request = wp_remote_get( 'https://ipapi.co/' . $ip . '/json' );
$request = wp_remote_get( 'https://ipapi.co/' . $ip . '/json' );
if ( ! is_wp_error( $request ) ) {
if ( ! is_wp_error( $request ) ) {
$request = json_decode( wp_remote_retrieve_body( $request ), true );
$request = json_decode( wp_remote_retrieve_body( $request ), true );
if ( ! empty( $request['latitude'] ) && ! empty( $request['longitude'] ) ) {
if ( ! empty( $request['latitude'] ) && ! empty( $request['longitude'] ) ) {
$data = array(
'latitude' => sanitize_text_field( $request['latitude'] ), $data = array(
'longitude' => sanitize_text_field( $request['longitude'] ), 'latitude' => sanitize_text_field( $request['latitude'] ),
'city' => sanitize_text_field( $request['city'] ), 'longitude' => sanitize_text_field( $request['longitude'] ),
'region' => sanitize_text_field( $request['region'] ), 'city' => sanitize_text_field( $request['city'] ),
'country' => sanitize_text_field( $request['country'] ), 'region' => sanitize_text_field( $request['region'] ),
'postal' => sanitize_text_field( $request['postal'] ), 'country' => sanitize_text_field( $request['country'] ),
); 'postal' => sanitize_text_field( $request['postal'] ),
);
return $data;
} return $data;
} }
}
$request = wp_remote_get( 'https://tools.keycdn.com/geo.json?host=' . $ip );
$request = wp_remote_get( 'https://tools.keycdn.com/geo.json?host=' . $ip );
if ( ! is_wp_error( $request ) ) {
if ( ! is_wp_error( $request ) ) {
$request = json_decode( wp_remote_retrieve_body( $request ), true );
$request = json_decode( wp_remote_retrieve_body( $request ), true );
if ( ! empty( $request['data']['geo']['latitude'] ) && ! empty( $request['data']['geo']['longitude'] ) ) {
if ( ! empty( $request['data']['geo']['latitude'] ) && ! empty( $request['data']['geo']['longitude'] ) ) {
$data = array(
'latitude' => sanitize_text_field( $request['data']['geo']['latitude'] ), $data = array(
'longitude' => sanitize_text_field( $request['data']['geo']['longitude'] ), 'latitude' => sanitize_text_field( $request['data']['geo']['latitude'] ),
'city' => sanitize_text_field( $request['data']['geo']['city'] ), 'longitude' => sanitize_text_field( $request['data']['geo']['longitude'] ),
'region' => sanitize_text_field( $request['data']['geo']['region_name'] ), 'city' => sanitize_text_field( $request['data']['geo']['city'] ),
'country' => sanitize_text_field( $request['data']['geo']['country_code'] ), 'region' => sanitize_text_field( $request['data']['geo']['region_name'] ),
'postal' => sanitize_text_field( $request['data']['geo']['postal_code'] ), 'country' => sanitize_text_field( $request['data']['geo']['country_code'] ),
); 'postal' => sanitize_text_field( $request['data']['geo']['postal_code'] ),
);
return $data;
} return $data;
} }
}
return array();
} return array();
}
/**
* This routine calculates the distance between two points (given the latitude/longitude of those points). /**
* Definitions: South latitudes are negative, east longitudes are positive. * This routine calculates the distance between two points (given the latitude/longitude of those points).
* * Definitions: South latitudes are negative, east longitudes are positive.
* @see https://www.geodatasource.com/developers/php *
* * @see https://www.geodatasource.com/developers/php
* @since 1.5.0 *
* * @since 1.5.0
* @param float $lat1 Latitude of point 1 (in decimal degrees). *
* @param float $lon1 Longitude of point 1 (in decimal degrees). * @param float $lat1 Latitude of point 1 (in decimal degrees).
* @param float $lat2 Latitude of point 2 (in decimal degrees). * @param float $lon1 Longitude of point 1 (in decimal degrees).
* @param float $lon2 Longitude of point 2 (in decimal degrees). * @param float $lat2 Latitude of point 2 (in decimal degrees).
* @param string $unit Supported values: M, K, N. Miles by default. * @param float $lon2 Longitude of point 2 (in decimal degrees).
* * @param string $unit Supported values: M, K, N. Miles by default.
* @return float|int *
*/ * @return float|int
public static function get_distance_between( $lat1, $lon1, $lat2, $lon2, $unit = 'M' ) { */
public static function get_distance_between( $lat1, $lon1, $lat2, $lon2, $unit = 'M' ) {
if ( ( $lat1 === $lat2 ) && ( $lon1 === $lon2 ) ) {
return 0; if ( ( $lat1 === $lat2 ) && ( $lon1 === $lon2 ) ) {
} return 0;
}
$theta = $lon1 - $lon2;
$dist = sin( deg2rad( $lat1 ) ) * sin( deg2rad( $lat2 ) ) + cos( deg2rad( $lat1 ) ) * cos( deg2rad( $lat2 ) ) * cos( deg2rad( $theta ) ); $theta = $lon1 - $lon2;
$dist = acos( $dist ); $dist = sin( deg2rad( $lat1 ) ) * sin( deg2rad( $lat2 ) ) + cos( deg2rad( $lat1 ) ) * cos( deg2rad( $lat2 ) ) * cos( deg2rad( $theta ) );
$dist = rad2deg( $dist ); $dist = acos( $dist );
$miles = $dist * 60 * 1.1515; $dist = rad2deg( $dist );
$unit = strtoupper( $unit ); $miles = $dist * 60 * 1.1515;
$unit = strtoupper( $unit );
if ( $unit === 'K' ) {
return ( $miles * 1.609344 ); if ( $unit === 'K' ) {
} elseif ( $unit === 'N' ) { return ( $miles * 1.609344 );
return ( $miles * 0.8684 ); } elseif ( $unit === 'N' ) {
} return ( $miles * 0.8684 );
}
return $miles;
} return $miles;
} }
}

View File

@ -64,6 +64,10 @@ class Options {
'sendgrid' => array( 'sendgrid' => array(
'api_key', 'api_key',
), ),
'smtpcom' => array(
'api_key',
'channel',
),
'sendinblue' => array( 'sendinblue' => array(
'api_key', 'api_key',
), ),
@ -407,11 +411,11 @@ class Options {
break; break;
case 'auth': case 'auth':
/** @noinspection PhpUndefinedConstantInspection */ /** @noinspection PhpUndefinedConstantInspection */
$return = $this->is_const_defined( $group, $key ) ? WPMS_SMTP_AUTH : $value; $return = $this->is_const_defined( $group, $key ) ? (bool) WPMS_SMTP_AUTH : $value;
break; break;
case 'autotls': case 'autotls':
/** @noinspection PhpUndefinedConstantInspection */ /** @noinspection PhpUndefinedConstantInspection */
$return = $this->is_const_defined( $group, $key ) ? WPMS_SMTP_AUTOTLS : $value; $return = $this->is_const_defined( $group, $key ) ? (bool) WPMS_SMTP_AUTOTLS : $value;
break; break;
case 'user': case 'user':
/** @noinspection PhpUndefinedConstantInspection */ /** @noinspection PhpUndefinedConstantInspection */
@ -499,6 +503,20 @@ class Options {
break; break;
case 'smtpcom':
switch ( $key ) {
case 'api_key':
/** @noinspection PhpUndefinedConstantInspection */
$return = $this->is_const_defined( $group, $key ) ? WPMS_SMTPCOM_API_KEY : $value;
break;
case 'channel':
/** @noinspection PhpUndefinedConstantInspection */
$return = $this->is_const_defined( $group, $key ) ? WPMS_SMTPCOM_CHANNEL : $value;
break;
}
break;
case 'sendinblue': case 'sendinblue':
switch ( $key ) { switch ( $key ) {
case 'api_key': case 'api_key':
@ -626,10 +644,10 @@ class Options {
$return = defined( 'WPMS_SSL' ); $return = defined( 'WPMS_SSL' );
break; break;
case 'auth': case 'auth':
$return = defined( 'WPMS_SMTP_AUTH' ) && WPMS_SMTP_AUTH; $return = defined( 'WPMS_SMTP_AUTH' );
break; break;
case 'autotls': case 'autotls':
$return = defined( 'WPMS_SMTP_AUTOTLS' ) && ( WPMS_SMTP_AUTOTLS === 'true' || WPMS_SMTP_AUTOTLS === true ); $return = defined( 'WPMS_SMTP_AUTOTLS' );
break; break;
case 'user': case 'user':
$return = defined( 'WPMS_SMTP_USER' ) && WPMS_SMTP_USER; $return = defined( 'WPMS_SMTP_USER' ) && WPMS_SMTP_USER;
@ -704,6 +722,18 @@ class Options {
break; break;
case 'smtpcom':
switch ( $key ) {
case 'api_key':
$return = defined( 'WPMS_SMTPCOM_API_KEY' ) && WPMS_SMTPCOM_API_KEY;
break;
case 'channel':
$return = defined( 'WPMS_SMTPCOM_CHANNEL' ) && WPMS_SMTPCOM_CHANNEL;
break;
}
break;
case 'sendinblue': case 'sendinblue':
switch ( $key ) { switch ( $key ) {
case 'api_key': case 'api_key':
@ -805,7 +835,7 @@ class Options {
if ( if (
! empty( $options['mail']['mailer'] ) && ! empty( $options['mail']['mailer'] ) &&
isset( $options[ $options['mail']['mailer'] ] ) && isset( $options[ $options['mail']['mailer'] ] ) &&
in_array( $options['mail']['mailer'], array( 'pepipost', 'pepipostapi', 'smtp', 'sendgrid', 'sendinblue', 'mailgun', 'gmail', 'outlook' ), true ) in_array( $options['mail']['mailer'], array( 'pepipost', 'pepipostapi', 'smtp', 'sendgrid', 'smtpcom', 'sendinblue', 'mailgun', 'gmail', 'outlook' ), true )
) { ) {
$mailer = $options['mail']['mailer']; $mailer = $options['mail']['mailer'];
@ -833,11 +863,12 @@ class Options {
$options[ $mailer ][ $option_name ] = $this->is_const_defined( $mailer, $option_name ) ? '' : trim( (string) $option_value ); $options[ $mailer ][ $option_name ] = $this->is_const_defined( $mailer, $option_name ) ? '' : trim( (string) $option_value );
break; break;
case 'api_key': // mailgun/sendgrid/sendinblue/pepipostapi. case 'api_key': // mailgun/sendgrid/sendinblue/pepipostapi/smtpcom.
case 'domain': // mailgun. case 'domain': // mailgun.
case 'client_id': // gmail/outlook/amazonses. case 'client_id': // gmail/outlook/amazonses.
case 'client_secret': // gmail/outlook/amazonses. case 'client_secret': // gmail/outlook/amazonses.
case 'auth_code': // gmail/outlook. case 'auth_code': // gmail/outlook.
case 'channel': // smtpcom.
$options[ $mailer ][ $option_name ] = $this->is_const_defined( $mailer, $option_name ) ? '' : sanitize_text_field( $option_value ); $options[ $mailer ][ $option_name ] = $this->is_const_defined( $mailer, $option_name ) ? '' : sanitize_text_field( $option_value );
break; break;

View File

@ -27,8 +27,9 @@ class Processor {
add_action( 'phpmailer_init', array( $this, 'phpmailer_init' ) ); add_action( 'phpmailer_init', array( $this, 'phpmailer_init' ) );
add_filter( 'wp_mail_from', array( $this, 'filter_mail_from_email' ), 1000 ); // High priority number tries to ensure our plugin code executes last and respects previous hooks, if not forced.
add_filter( 'wp_mail_from_name', array( $this, 'filter_mail_from_name' ), 1000 ); add_filter( 'wp_mail_from', array( $this, 'filter_mail_from_email' ), PHP_INT_MAX );
add_filter( 'wp_mail_from_name', array( $this, 'filter_mail_from_name' ), PHP_INT_MAX );
} }
/** /**
@ -233,7 +234,7 @@ class Processor {
/** /**
* Get or create the phpmailer. * Get or create the phpmailer.
* *
* @since {VERSION} * @since 1.9.0
* *
* @return \WPMailSMTP\MailCatcher * @return \WPMailSMTP\MailCatcher
*/ */

View File

@ -24,6 +24,7 @@ class Loader {
*/ */
protected $providers = array( protected $providers = array(
'mail' => 'WPMailSMTP\Providers\Mail\\', 'mail' => 'WPMailSMTP\Providers\Mail\\',
'smtpcom' => 'WPMailSMTP\Providers\SMTPcom\\',
'pepipostapi' => 'WPMailSMTP\Providers\PepipostAPI\\', 'pepipostapi' => 'WPMailSMTP\Providers\PepipostAPI\\',
'sendinblue' => 'WPMailSMTP\Providers\Sendinblue\\', 'sendinblue' => 'WPMailSMTP\Providers\Sendinblue\\',
'mailgun' => 'WPMailSMTP\Providers\Mailgun\\', 'mailgun' => 'WPMailSMTP\Providers\Mailgun\\',

View File

@ -1,477 +1,477 @@
<?php <?php
namespace WPMailSMTP\Providers; namespace WPMailSMTP\Providers;
use WPMailSMTP\Options; use WPMailSMTP\Options;
/** /**
* Abstract Class ProviderAbstract to contain common providers functionality. * Abstract Class ProviderAbstract to contain common providers functionality.
* *
* @since 1.0.0 * @since 1.0.0
*/ */
abstract class OptionsAbstract implements OptionsInterface { abstract class OptionsAbstract implements OptionsInterface {
/** /**
* @var string * @var string
*/ */
private $logo_url = ''; private $logo_url = '';
/** /**
* @var string * @var string
*/ */
private $slug = ''; private $slug = '';
/** /**
* @var string * @var string
*/ */
private $title = ''; private $title = '';
/** /**
* @var string * @var string
*/ */
private $description = ''; private $description = '';
/** /**
* @since 1.6.0 * @since 1.6.0
* *
* @var array * @var array
*/ */
private $notices = array(); private $notices = array();
/** /**
* @since 1.6.0 * @since 1.6.0
* *
* @var bool * @var bool
*/ */
private $recommended = false; private $recommended = false;
/** /**
* @since 1.7.0 * @since 1.7.0
* *
* @var bool * @var bool
*/ */
private $disabled = false; private $disabled = false;
/** /**
* @var string * @var string
*/ */
private $php = WPMS_PHP_VER; private $php = WPMS_PHP_VER;
/** /**
* @var Options * @var Options
*/ */
protected $options; protected $options;
/** /**
* ProviderAbstract constructor. * ProviderAbstract constructor.
* *
* @since 1.0.0 * @since 1.0.0
* *
* @param array $params * @param array $params
*/ */
public function __construct( $params ) { public function __construct( $params ) {
if ( if (
empty( $params['slug'] ) || empty( $params['slug'] ) ||
empty( $params['title'] ) empty( $params['title'] )
) { ) {
return; return;
} }
$this->slug = sanitize_key( $params['slug'] ); $this->slug = sanitize_key( $params['slug'] );
$this->title = sanitize_text_field( $params['title'] ); $this->title = sanitize_text_field( $params['title'] );
if ( ! empty( $params['description'] ) ) { if ( ! empty( $params['description'] ) ) {
$this->description = wp_kses_post( $params['description'] ); $this->description = wp_kses_post( $params['description'] );
} }
if ( ! empty( $params['notices'] ) ) { if ( ! empty( $params['notices'] ) ) {
foreach ( (array) $params['notices'] as $key => $notice ) { foreach ( (array) $params['notices'] as $key => $notice ) {
$key = sanitize_key( $key ); $key = sanitize_key( $key );
if ( empty( $key ) ) { if ( empty( $key ) ) {
continue; continue;
} }
$notice = wp_kses( $notice = wp_kses(
$notice, $notice,
array( array(
'br' => true, 'br' => true,
'strong' => true, 'strong' => true,
'em' => true, 'em' => true,
'a' => array( 'a' => array(
'href' => true, 'href' => true,
'rel' => true, 'rel' => true,
'target' => true, 'target' => true,
), ),
) )
); );
if ( empty( $notice ) ) { if ( empty( $notice ) ) {
continue; continue;
} }
$this->notices[ $key ] = $notice; $this->notices[ $key ] = $notice;
} }
} }
if ( isset( $params['recommended'] ) ) { if ( isset( $params['recommended'] ) ) {
$this->recommended = (bool) $params['recommended']; $this->recommended = (bool) $params['recommended'];
} }
if ( isset( $params['disabled'] ) ) { if ( isset( $params['disabled'] ) ) {
$this->disabled = (bool) $params['disabled']; $this->disabled = (bool) $params['disabled'];
} }
if ( ! empty( $params['php'] ) ) { if ( ! empty( $params['php'] ) ) {
$this->php = sanitize_text_field( $params['php'] ); $this->php = sanitize_text_field( $params['php'] );
} }
if ( ! empty( $params['logo_url'] ) ) { if ( ! empty( $params['logo_url'] ) ) {
$this->logo_url = esc_url_raw( $params['logo_url'] ); $this->logo_url = esc_url_raw( $params['logo_url'] );
} }
$this->options = new Options(); $this->options = new Options();
} }
/** /**
* @inheritdoc * @inheritdoc
*/ */
public function get_logo_url() { public function get_logo_url() {
return apply_filters( 'wp_mail_smtp_providers_provider_get_logo_url', $this->logo_url, $this ); return apply_filters( 'wp_mail_smtp_providers_provider_get_logo_url', $this->logo_url, $this );
} }
/** /**
* @inheritdoc * @inheritdoc
*/ */
public function get_slug() { public function get_slug() {
return apply_filters( 'wp_mail_smtp_providers_provider_get_slug', $this->slug, $this ); return apply_filters( 'wp_mail_smtp_providers_provider_get_slug', $this->slug, $this );
} }
/** /**
* @inheritdoc * @inheritdoc
*/ */
public function get_title() { public function get_title() {
return apply_filters( 'wp_mail_smtp_providers_provider_get_title', $this->title, $this ); return apply_filters( 'wp_mail_smtp_providers_provider_get_title', $this->title, $this );
} }
/** /**
* @inheritdoc * @inheritdoc
*/ */
public function get_description() { public function get_description() {
return apply_filters( 'wp_mail_smtp_providers_provider_get_description', $this->description, $this ); return apply_filters( 'wp_mail_smtp_providers_provider_get_description', $this->description, $this );
} }
/** /**
* Some mailers may display a notice above its options. * Some mailers may display a notice above its options.
* *
* @since 1.6.0 * @since 1.6.0
* *
* @param string $type * @param string $type
* *
* @return string * @return string
*/ */
public function get_notice( $type ) { public function get_notice( $type ) {
$type = sanitize_key( $type ); $type = sanitize_key( $type );
return apply_filters( 'wp_mail_smtp_providers_provider_get_notice', isset( $this->notices[ $type ] ) ? $this->notices[ $type ] : '', $this ); return apply_filters( 'wp_mail_smtp_providers_provider_get_notice', isset( $this->notices[ $type ] ) ? $this->notices[ $type ] : '', $this );
} }
/** /**
* @inheritdoc * @inheritdoc
*/ */
public function get_php_version() { public function get_php_version() {
return apply_filters( 'wp_mail_smtp_providers_provider_get_php_version', $this->php, $this ); return apply_filters( 'wp_mail_smtp_providers_provider_get_php_version', $this->php, $this );
} }
/** /**
* @inheritdoc * @inheritdoc
*/ */
public function display_options() { public function display_options() {
?> ?>
<!-- SMTP Host --> <!-- SMTP Host -->
<div id="wp-mail-smtp-setting-row-<?php echo esc_attr( $this->get_slug() ); ?>-host" class="wp-mail-smtp-setting-row wp-mail-smtp-setting-row-text wp-mail-smtp-clear"> <div id="wp-mail-smtp-setting-row-<?php echo esc_attr( $this->get_slug() ); ?>-host" class="wp-mail-smtp-setting-row wp-mail-smtp-setting-row-text wp-mail-smtp-clear">
<div class="wp-mail-smtp-setting-label"> <div class="wp-mail-smtp-setting-label">
<label for="wp-mail-smtp-setting-<?php echo esc_attr( $this->get_slug() ); ?>-host"><?php esc_html_e( 'SMTP Host', 'wp-mail-smtp' ); ?></label> <label for="wp-mail-smtp-setting-<?php echo esc_attr( $this->get_slug() ); ?>-host"><?php esc_html_e( 'SMTP Host', 'wp-mail-smtp' ); ?></label>
</div> </div>
<div class="wp-mail-smtp-setting-field"> <div class="wp-mail-smtp-setting-field">
<input name="wp-mail-smtp[<?php echo esc_attr( $this->get_slug() ); ?>][host]" type="text" <input name="wp-mail-smtp[<?php echo esc_attr( $this->get_slug() ); ?>][host]" type="text"
value="<?php echo esc_attr( $this->options->get( $this->get_slug(), 'host' ) ); ?>" value="<?php echo esc_attr( $this->options->get( $this->get_slug(), 'host' ) ); ?>"
<?php echo $this->options->is_const_defined( $this->get_slug(), 'host' ) ? 'disabled' : ''; ?> <?php echo $this->options->is_const_defined( $this->get_slug(), 'host' ) ? 'disabled' : ''; ?>
id="wp-mail-smtp-setting-<?php echo esc_attr( $this->get_slug() ); ?>-host" spellcheck="false" id="wp-mail-smtp-setting-<?php echo esc_attr( $this->get_slug() ); ?>-host" spellcheck="false"
/> />
</div> </div>
</div> </div>
<!-- SMTP Encryption --> <!-- SMTP Encryption -->
<div id="wp-mail-smtp-setting-row-<?php echo esc_attr( $this->get_slug() ); ?>-encryption" class="wp-mail-smtp-setting-row wp-mail-smtp-setting-row-radio wp-mail-smtp-clear"> <div id="wp-mail-smtp-setting-row-<?php echo esc_attr( $this->get_slug() ); ?>-encryption" class="wp-mail-smtp-setting-row wp-mail-smtp-setting-row-radio wp-mail-smtp-clear">
<div class="wp-mail-smtp-setting-label"> <div class="wp-mail-smtp-setting-label">
<label><?php esc_html_e( 'Encryption', 'wp-mail-smtp' ); ?></label> <label><?php esc_html_e( 'Encryption', 'wp-mail-smtp' ); ?></label>
</div> </div>
<div class="wp-mail-smtp-setting-field"> <div class="wp-mail-smtp-setting-field">
<label for="wp-mail-smtp-setting-<?php echo esc_attr( $this->get_slug() ); ?>-enc-none"> <label for="wp-mail-smtp-setting-<?php echo esc_attr( $this->get_slug() ); ?>-enc-none">
<input type="radio" id="wp-mail-smtp-setting-<?php echo esc_attr( $this->get_slug() ); ?>-enc-none" <input type="radio" id="wp-mail-smtp-setting-<?php echo esc_attr( $this->get_slug() ); ?>-enc-none"
name="wp-mail-smtp[<?php echo esc_attr( $this->get_slug() ); ?>][encryption]" value="none" name="wp-mail-smtp[<?php echo esc_attr( $this->get_slug() ); ?>][encryption]" value="none"
<?php echo $this->options->is_const_defined( $this->get_slug(), 'encryption' ) ? 'disabled' : ''; ?> <?php echo $this->options->is_const_defined( $this->get_slug(), 'encryption' ) ? 'disabled' : ''; ?>
<?php checked( 'none', $this->options->get( $this->get_slug(), 'encryption' ) ); ?> <?php checked( 'none', $this->options->get( $this->get_slug(), 'encryption' ) ); ?>
/> />
<?php esc_html_e( 'None', 'wp-mail-smtp' ); ?> <?php esc_html_e( 'None', 'wp-mail-smtp' ); ?>
</label> </label>
<label for="wp-mail-smtp-setting-<?php echo esc_attr( $this->get_slug() ); ?>-enc-ssl"> <label for="wp-mail-smtp-setting-<?php echo esc_attr( $this->get_slug() ); ?>-enc-ssl">
<input type="radio" id="wp-mail-smtp-setting-<?php echo esc_attr( $this->get_slug() ); ?>-enc-ssl" <input type="radio" id="wp-mail-smtp-setting-<?php echo esc_attr( $this->get_slug() ); ?>-enc-ssl"
name="wp-mail-smtp[<?php echo esc_attr( $this->get_slug() ); ?>][encryption]" value="ssl" name="wp-mail-smtp[<?php echo esc_attr( $this->get_slug() ); ?>][encryption]" value="ssl"
<?php echo $this->options->is_const_defined( $this->get_slug(), 'encryption' ) ? 'disabled' : ''; ?> <?php echo $this->options->is_const_defined( $this->get_slug(), 'encryption' ) ? 'disabled' : ''; ?>
<?php checked( 'ssl', $this->options->get( $this->get_slug(), 'encryption' ) ); ?> <?php checked( 'ssl', $this->options->get( $this->get_slug(), 'encryption' ) ); ?>
/> />
<?php esc_html_e( 'SSL', 'wp-mail-smtp' ); ?> <?php esc_html_e( 'SSL', 'wp-mail-smtp' ); ?>
</label> </label>
<label for="wp-mail-smtp-setting-<?php echo esc_attr( $this->get_slug() ); ?>-enc-tls"> <label for="wp-mail-smtp-setting-<?php echo esc_attr( $this->get_slug() ); ?>-enc-tls">
<input type="radio" id="wp-mail-smtp-setting-<?php echo esc_attr( $this->get_slug() ); ?>-enc-tls" <input type="radio" id="wp-mail-smtp-setting-<?php echo esc_attr( $this->get_slug() ); ?>-enc-tls"
name="wp-mail-smtp[<?php echo esc_attr( $this->get_slug() ); ?>][encryption]" value="tls" name="wp-mail-smtp[<?php echo esc_attr( $this->get_slug() ); ?>][encryption]" value="tls"
<?php echo $this->options->is_const_defined( $this->get_slug(), 'encryption' ) ? 'disabled' : ''; ?> <?php echo $this->options->is_const_defined( $this->get_slug(), 'encryption' ) ? 'disabled' : ''; ?>
<?php checked( 'tls', $this->options->get( $this->get_slug(), 'encryption' ) ); ?> <?php checked( 'tls', $this->options->get( $this->get_slug(), 'encryption' ) ); ?>
/> />
<?php esc_html_e( 'TLS', 'wp-mail-smtp' ); ?> <?php esc_html_e( 'TLS', 'wp-mail-smtp' ); ?>
</label> </label>
<p class="desc"> <p class="desc">
<?php esc_html_e( 'For most servers TLS is the recommended option. If your SMTP provider offers both SSL and TLS options, we recommend using TLS.', 'wp-mail-smtp' ); ?> <?php esc_html_e( 'For most servers TLS is the recommended option. If your SMTP provider offers both SSL and TLS options, we recommend using TLS.', 'wp-mail-smtp' ); ?>
</p> </p>
</div> </div>
</div> </div>
<!-- SMTP Port --> <!-- SMTP Port -->
<div id="wp-mail-smtp-setting-row-<?php echo esc_attr( $this->get_slug() ); ?>-port" class="wp-mail-smtp-setting-row wp-mail-smtp-setting-row-number wp-mail-smtp-clear"> <div id="wp-mail-smtp-setting-row-<?php echo esc_attr( $this->get_slug() ); ?>-port" class="wp-mail-smtp-setting-row wp-mail-smtp-setting-row-number wp-mail-smtp-clear">
<div class="wp-mail-smtp-setting-label"> <div class="wp-mail-smtp-setting-label">
<label for="wp-mail-smtp-setting-<?php echo esc_attr( $this->get_slug() ); ?>-port"><?php esc_html_e( 'SMTP Port', 'wp-mail-smtp' ); ?></label> <label for="wp-mail-smtp-setting-<?php echo esc_attr( $this->get_slug() ); ?>-port"><?php esc_html_e( 'SMTP Port', 'wp-mail-smtp' ); ?></label>
</div> </div>
<div class="wp-mail-smtp-setting-field"> <div class="wp-mail-smtp-setting-field">
<input name="wp-mail-smtp[<?php echo esc_attr( $this->get_slug() ); ?>][port]" type="number" <input name="wp-mail-smtp[<?php echo esc_attr( $this->get_slug() ); ?>][port]" type="number"
value="<?php echo esc_attr( $this->options->get( $this->get_slug(), 'port' ) ); ?>" value="<?php echo esc_attr( $this->options->get( $this->get_slug(), 'port' ) ); ?>"
<?php echo $this->options->is_const_defined( $this->get_slug(), 'port' ) ? 'disabled' : ''; ?> <?php echo $this->options->is_const_defined( $this->get_slug(), 'port' ) ? 'disabled' : ''; ?>
id="wp-mail-smtp-setting-<?php echo esc_attr( $this->get_slug() ); ?>-port" class="small-text" spellcheck="false" id="wp-mail-smtp-setting-<?php echo esc_attr( $this->get_slug() ); ?>-port" class="small-text" spellcheck="false"
/> />
</div> </div>
</div> </div>
<!-- PHPMailer SMTPAutoTLS --> <!-- PHPMailer SMTPAutoTLS -->
<div id="wp-mail-smtp-setting-row-<?php echo esc_attr( $this->get_slug() ); ?>-autotls" class="wp-mail-smtp-setting-row wp-mail-smtp-setting-row-checkbox-toggle wp-mail-smtp-clear <?php echo $this->options->is_const_defined( $this->get_slug(), 'encryption' ) || 'tls' === $this->options->get( $this->get_slug(), 'encryption' ) ? 'inactive' : ''; ?>"> <div id="wp-mail-smtp-setting-row-<?php echo esc_attr( $this->get_slug() ); ?>-autotls" class="wp-mail-smtp-setting-row wp-mail-smtp-setting-row-checkbox-toggle wp-mail-smtp-clear <?php echo $this->options->is_const_defined( $this->get_slug(), 'encryption' ) || 'tls' === $this->options->get( $this->get_slug(), 'encryption' ) ? 'inactive' : ''; ?>">
<div class="wp-mail-smtp-setting-label"> <div class="wp-mail-smtp-setting-label">
<label for="wp-mail-smtp-setting-<?php echo esc_attr( $this->get_slug() ); ?>-autotls"><?php esc_html_e( 'Auto TLS', 'wp-mail-smtp' ); ?></label> <label for="wp-mail-smtp-setting-<?php echo esc_attr( $this->get_slug() ); ?>-autotls"><?php esc_html_e( 'Auto TLS', 'wp-mail-smtp' ); ?></label>
</div> </div>
<div class="wp-mail-smtp-setting-field"> <div class="wp-mail-smtp-setting-field">
<label for="wp-mail-smtp-setting-<?php echo esc_attr( $this->get_slug() ); ?>-autotls"> <label for="wp-mail-smtp-setting-<?php echo esc_attr( $this->get_slug() ); ?>-autotls">
<input type="checkbox" id="wp-mail-smtp-setting-<?php echo esc_attr( $this->get_slug() ); ?>-autotls" <input type="checkbox" id="wp-mail-smtp-setting-<?php echo esc_attr( $this->get_slug() ); ?>-autotls"
name="wp-mail-smtp[<?php echo esc_attr( $this->get_slug() ); ?>][autotls]" value="yes" name="wp-mail-smtp[<?php echo esc_attr( $this->get_slug() ); ?>][autotls]" value="yes"
<?php echo $this->options->is_const_defined( $this->get_slug(), 'autotls' ) ? 'disabled' : ''; ?> <?php echo $this->options->is_const_defined( $this->get_slug(), 'autotls' ) ? 'disabled' : ''; ?>
<?php checked( true, (bool) $this->options->get( $this->get_slug(), 'autotls' ) ); ?> <?php checked( true, (bool) $this->options->get( $this->get_slug(), 'autotls' ) ); ?>
/> />
<span class="wp-mail-smtp-setting-toggle-switch"></span> <span class="wp-mail-smtp-setting-toggle-switch"></span>
<span class="wp-mail-smtp-setting-toggle-checked-label"><?php esc_html_e( 'On', 'wp-mail-smtp' ); ?></span> <span class="wp-mail-smtp-setting-toggle-checked-label"><?php esc_html_e( 'On', 'wp-mail-smtp' ); ?></span>
<span class="wp-mail-smtp-setting-toggle-unchecked-label"><?php esc_html_e( 'Off', 'wp-mail-smtp' ); ?></span> <span class="wp-mail-smtp-setting-toggle-unchecked-label"><?php esc_html_e( 'Off', 'wp-mail-smtp' ); ?></span>
</label> </label>
<p class="desc"> <p class="desc">
<?php esc_html_e( 'By default TLS encryption is automatically used if the server supports it, which is recommended. In some cases, due to server misconfigurations, this can cause issues and may need to be disabled.', 'wp-mail-smtp' ); ?> <?php esc_html_e( 'By default TLS encryption is automatically used if the server supports it, which is recommended. In some cases, due to server misconfigurations, this can cause issues and may need to be disabled.', 'wp-mail-smtp' ); ?>
</p> </p>
</div> </div>
</div> </div>
<!-- SMTP Authentication --> <!-- SMTP Authentication -->
<div id="wp-mail-smtp-setting-row-<?php echo esc_attr( $this->get_slug() ); ?>-auth" class="wp-mail-smtp-setting-row wp-mail-smtp-setting-row-checkbox-toggle wp-mail-smtp-clear"> <div id="wp-mail-smtp-setting-row-<?php echo esc_attr( $this->get_slug() ); ?>-auth" class="wp-mail-smtp-setting-row wp-mail-smtp-setting-row-checkbox-toggle wp-mail-smtp-clear">
<div class="wp-mail-smtp-setting-label"> <div class="wp-mail-smtp-setting-label">
<label for="wp-mail-smtp-setting-<?php echo esc_attr( $this->get_slug() ); ?>-auth"><?php esc_html_e( 'Authentication', 'wp-mail-smtp' ); ?></label> <label for="wp-mail-smtp-setting-<?php echo esc_attr( $this->get_slug() ); ?>-auth"><?php esc_html_e( 'Authentication', 'wp-mail-smtp' ); ?></label>
</div> </div>
<div class="wp-mail-smtp-setting-field"> <div class="wp-mail-smtp-setting-field">
<label for="wp-mail-smtp-setting-<?php echo esc_attr( $this->get_slug() ); ?>-auth"> <label for="wp-mail-smtp-setting-<?php echo esc_attr( $this->get_slug() ); ?>-auth">
<input type="checkbox" id="wp-mail-smtp-setting-<?php echo esc_attr( $this->get_slug() ); ?>-auth" <input type="checkbox" id="wp-mail-smtp-setting-<?php echo esc_attr( $this->get_slug() ); ?>-auth"
name="wp-mail-smtp[<?php echo esc_attr( $this->get_slug() ); ?>][auth]" value="yes" name="wp-mail-smtp[<?php echo esc_attr( $this->get_slug() ); ?>][auth]" value="yes"
<?php echo $this->options->is_const_defined( $this->get_slug(), 'auth' ) ? 'disabled' : ''; ?> <?php echo $this->options->is_const_defined( $this->get_slug(), 'auth' ) ? 'disabled' : ''; ?>
<?php checked( true, (bool) $this->options->get( $this->get_slug(), 'auth' ) ); ?> <?php checked( true, (bool) $this->options->get( $this->get_slug(), 'auth' ) ); ?>
/> />
<span class="wp-mail-smtp-setting-toggle-switch"></span> <span class="wp-mail-smtp-setting-toggle-switch"></span>
<span class="wp-mail-smtp-setting-toggle-checked-label"><?php esc_html_e( 'On', 'wp-mail-smtp' ); ?></span> <span class="wp-mail-smtp-setting-toggle-checked-label"><?php esc_html_e( 'On', 'wp-mail-smtp' ); ?></span>
<span class="wp-mail-smtp-setting-toggle-unchecked-label"><?php esc_html_e( 'Off', 'wp-mail-smtp' ); ?></span> <span class="wp-mail-smtp-setting-toggle-unchecked-label"><?php esc_html_e( 'Off', 'wp-mail-smtp' ); ?></span>
</label> </label>
</div> </div>
</div> </div>
<!-- SMTP Username --> <!-- SMTP Username -->
<div id="wp-mail-smtp-setting-row-<?php echo esc_attr( $this->get_slug() ); ?>-user" class="wp-mail-smtp-setting-row wp-mail-smtp-setting-row-text wp-mail-smtp-clear <?php echo ! $this->options->is_const_defined( $this->get_slug(), 'auth' ) && ! $this->options->get( $this->get_slug(), 'auth' ) ? 'inactive' : ''; ?>"> <div id="wp-mail-smtp-setting-row-<?php echo esc_attr( $this->get_slug() ); ?>-user" class="wp-mail-smtp-setting-row wp-mail-smtp-setting-row-text wp-mail-smtp-clear <?php echo ! $this->options->is_const_defined( $this->get_slug(), 'auth' ) && ! $this->options->get( $this->get_slug(), 'auth' ) ? 'inactive' : ''; ?>">
<div class="wp-mail-smtp-setting-label"> <div class="wp-mail-smtp-setting-label">
<label for="wp-mail-smtp-setting-<?php echo esc_attr( $this->get_slug() ); ?>-user"><?php esc_html_e( 'SMTP Username', 'wp-mail-smtp' ); ?></label> <label for="wp-mail-smtp-setting-<?php echo esc_attr( $this->get_slug() ); ?>-user"><?php esc_html_e( 'SMTP Username', 'wp-mail-smtp' ); ?></label>
</div> </div>
<div class="wp-mail-smtp-setting-field"> <div class="wp-mail-smtp-setting-field">
<input name="wp-mail-smtp[<?php echo esc_attr( $this->get_slug() ); ?>][user]" type="text" <input name="wp-mail-smtp[<?php echo esc_attr( $this->get_slug() ); ?>][user]" type="text"
value="<?php echo esc_attr( $this->options->get( $this->get_slug(), 'user' ) ); ?>" value="<?php echo esc_attr( $this->options->get( $this->get_slug(), 'user' ) ); ?>"
<?php echo $this->options->is_const_defined( $this->get_slug(), 'user' ) ? 'disabled' : ''; ?> <?php echo $this->options->is_const_defined( $this->get_slug(), 'user' ) ? 'disabled' : ''; ?>
id="wp-mail-smtp-setting-<?php echo esc_attr( $this->get_slug() ); ?>-user" spellcheck="false" autocomplete="new-password" id="wp-mail-smtp-setting-<?php echo esc_attr( $this->get_slug() ); ?>-user" spellcheck="false" autocomplete="new-password"
/> />
</div> </div>
</div> </div>
<!-- SMTP Password --> <!-- SMTP Password -->
<div id="wp-mail-smtp-setting-row-<?php echo esc_attr( $this->get_slug() ); ?>-pass" class="wp-mail-smtp-setting-row wp-mail-smtp-setting-row-password wp-mail-smtp-clear <?php echo ! $this->options->is_const_defined( $this->get_slug(), 'auth' ) && ! $this->options->get( $this->get_slug(), 'auth' ) ? 'inactive' : ''; ?>"> <div id="wp-mail-smtp-setting-row-<?php echo esc_attr( $this->get_slug() ); ?>-pass" class="wp-mail-smtp-setting-row wp-mail-smtp-setting-row-password wp-mail-smtp-clear <?php echo ! $this->options->is_const_defined( $this->get_slug(), 'auth' ) && ! $this->options->get( $this->get_slug(), 'auth' ) ? 'inactive' : ''; ?>">
<div class="wp-mail-smtp-setting-label"> <div class="wp-mail-smtp-setting-label">
<label for="wp-mail-smtp-setting-<?php echo esc_attr( $this->get_slug() ); ?>-pass"><?php esc_html_e( 'SMTP Password', 'wp-mail-smtp' ); ?></label> <label for="wp-mail-smtp-setting-<?php echo esc_attr( $this->get_slug() ); ?>-pass"><?php esc_html_e( 'SMTP Password', 'wp-mail-smtp' ); ?></label>
</div> </div>
<div class="wp-mail-smtp-setting-field"> <div class="wp-mail-smtp-setting-field">
<?php if ( $this->options->is_const_defined( $this->get_slug(), 'pass' ) ) : ?> <?php if ( $this->options->is_const_defined( $this->get_slug(), 'pass' ) ) : ?>
<input type="text" value="*************" disabled id="wp-mail-smtp-setting-<?php echo esc_attr( $this->get_slug() ); ?>-pass"/> <input type="text" value="*************" disabled id="wp-mail-smtp-setting-<?php echo esc_attr( $this->get_slug() ); ?>-pass"/>
<?php $this->display_const_set_message( 'WPMS_SMTP_PASS' ); ?> <?php $this->display_const_set_message( 'WPMS_SMTP_PASS' ); ?>
<p class="desc"> <p class="desc">
<?php <?php
printf( printf(
/* translators: %s - constant name: WPMS_SMTP_PASS. */ /* translators: %s - constant name: WPMS_SMTP_PASS. */
esc_html__( 'To change the password you need to change the value of the constant there: %s', 'wp-mail-smtp' ), esc_html__( 'To change the password you need to change the value of the constant there: %s', 'wp-mail-smtp' ),
'<code>define( \'WPMS_SMTP_PASS\', \'your_old_password\' );</code>' '<code>define( \'WPMS_SMTP_PASS\', \'your_old_password\' );</code>'
); );
?> ?>
<br> <br>
<?php <?php
printf( printf(
/* translators: %1$s - wp-config.php file, %2$s - WPMS_ON constant name. */ /* translators: %1$s - wp-config.php file, %2$s - WPMS_ON constant name. */
esc_html__( 'If you want to disable the use of constants, find in %1$s file the constant %2$s and turn if off:', 'wp-mail-smtp' ), esc_html__( 'If you want to disable the use of constants, find in %1$s file the constant %2$s and turn if off:', 'wp-mail-smtp' ),
'<code>wp-config.php</code>', '<code>wp-config.php</code>',
'<code>WPMS_ON</code>' '<code>WPMS_ON</code>'
); );
?> ?>
</p> </p>
<pre> <pre>
define( 'WPMS_ON', false ); define( 'WPMS_ON', false );
</pre> </pre>
<p class="desc"> <p class="desc">
<?php esc_html_e( 'All the defined constants will stop working and you will be able to change all the values on this page.', 'wp-mail-smtp' ); ?> <?php esc_html_e( 'All the defined constants will stop working and you will be able to change all the values on this page.', 'wp-mail-smtp' ); ?>
</p> </p>
<?php else : ?> <?php else : ?>
<input name="wp-mail-smtp[<?php echo esc_attr( $this->get_slug() ); ?>][pass]" type="password" <input name="wp-mail-smtp[<?php echo esc_attr( $this->get_slug() ); ?>][pass]" type="password"
value="<?php echo esc_attr( $this->options->get( $this->get_slug(), 'pass' ) ); ?>" value="<?php echo esc_attr( $this->options->get( $this->get_slug(), 'pass' ) ); ?>"
id="wp-mail-smtp-setting-<?php echo esc_attr( $this->get_slug() ); ?>-pass" spellcheck="false" autocomplete="new-password" id="wp-mail-smtp-setting-<?php echo esc_attr( $this->get_slug() ); ?>-pass" spellcheck="false" autocomplete="new-password"
/> />
<p class="desc"> <p class="desc">
<?php esc_html_e( 'The password is stored in plain text. We highly recommend you set up your password in your WordPress configuration file for improved security.', 'wp-mail-smtp' ); ?> <?php esc_html_e( 'The password is stored in plain text. We highly recommend you set up your password in your WordPress configuration file for improved security.', 'wp-mail-smtp' ); ?>
<br> <br>
<?php <?php
printf( printf(
/* translators: %s - wp-config.php. */ /* translators: %s - wp-config.php. */
esc_html__( 'To do this add the lines below to your %s file:', 'wp-mail-smtp' ), esc_html__( 'To do this add the lines below to your %s file:', 'wp-mail-smtp' ),
'<code>wp-config.php</code>' '<code>wp-config.php</code>'
); );
?> ?>
</p> </p>
<pre> <pre>
define( 'WPMS_ON', true ); define( 'WPMS_ON', true );
define( 'WPMS_SMTP_PASS', 'your_password' ); define( 'WPMS_SMTP_PASS', 'your_password' );
</pre> </pre>
<?php endif; ?> <?php endif; ?>
</div> </div>
</div> </div>
<?php <?php
} }
/** /**
* Whether this mailer is recommended or not. * Whether this mailer is recommended or not.
* *
* @since 1.6.0 * @since 1.6.0
* *
* @return bool * @return bool
*/ */
public function is_recommended() { public function is_recommended() {
return (bool) apply_filters( 'wp_mail_smtp_providers_provider_is_recommended', $this->recommended, $this ); return (bool) apply_filters( 'wp_mail_smtp_providers_provider_is_recommended', $this->recommended, $this );
} }
/** /**
* Whether this mailer is disabled or not. * Whether this mailer is disabled or not.
* Used for displaying Pro mailers inside Lite plugin. * Used for displaying Pro mailers inside Lite plugin.
* *
* @since 1.7.0 * @since 1.7.0
* *
* @return bool * @return bool
*/ */
public function is_disabled() { public function is_disabled() {
return (bool) apply_filters( 'wp_mail_smtp_providers_provider_is_disabled', $this->disabled, $this ); return (bool) apply_filters( 'wp_mail_smtp_providers_provider_is_disabled', $this->disabled, $this );
} }
/** /**
* Check whether we can use this provider based on the PHP version. * Check whether we can use this provider based on the PHP version.
* Valid for those, that use SDK. * Valid for those, that use SDK.
* *
* @since 1.0.0 * @since 1.0.0
* *
* @return bool * @return bool
*/ */
public function is_php_correct() { public function is_php_correct() {
return version_compare( phpversion(), $this->php, '>=' ); return version_compare( phpversion(), $this->php, '>=' );
} }
/** /**
* Display a helpful message to those users, that are using an outdated version of PHP, * Display a helpful message to those users, that are using an outdated version of PHP,
* which is not supported by the currently selected Provider. * which is not supported by the currently selected Provider.
* *
* @since 1.0.0 * @since 1.0.0
*/ */
protected function display_php_warning() { protected function display_php_warning() {
?> ?>
<blockquote> <blockquote>
<?php <?php
printf( printf(
/* translators: %1$s - Provider name; %2$s - PHP version required by Provider; %3$s - current PHP version. */ /* translators: %1$s - Provider name; %2$s - PHP version required by Provider; %3$s - current PHP version. */
esc_html__( '%1$s requires PHP %2$s to work and does not support your current PHP version %3$s. Please contact your host and request a PHP upgrade to the latest one.', 'wp-mail-smtp' ), esc_html__( '%1$s requires PHP %2$s to work and does not support your current PHP version %3$s. Please contact your host and request a PHP upgrade to the latest one.', 'wp-mail-smtp' ),
esc_html( $this->get_title() ), esc_html( $this->get_title() ),
esc_html( $this->php ), esc_html( $this->php ),
esc_html( phpversion() ) esc_html( phpversion() )
); );
?> ?>
<br> <br>
<?php esc_html_e( 'Meanwhile you can switch to some other mailers.', 'wp-mail-smtp' ); ?> <?php esc_html_e( 'Meanwhile you can switch to some other mailers.', 'wp-mail-smtp' ); ?>
</blockquote> </blockquote>
<?php <?php
} }
/** /**
* Display a helpful message to those users, that are using an outdated version of PHP, * Display a helpful message to those users, that are using an outdated version of PHP,
* which is not supported by the currently selected Provider. * which is not supported by the currently selected Provider.
* *
* @since 1.5.0 * @since 1.5.0
*/ */
protected function display_ssl_warning() { protected function display_ssl_warning() {
?> ?>
<blockquote> <blockquote>
<?php <?php
printf( printf(
/* translators: %s - Provider name. */ /* translators: %s - Provider name. */
esc_html__( '%s requires a SSL certificate on a site to work and does not support your current installation. Please contact your host and request a SSL certificate or install a free one, like Let\'s Encrypt.', 'wp-mail-smtp' ), esc_html__( '%s requires a SSL certificate on a site to work and does not support your current installation. Please contact your host and request a SSL certificate or install a free one, like Let\'s Encrypt.', 'wp-mail-smtp' ),
esc_html( $this->get_title() ) esc_html( $this->get_title() )
); );
?> ?>
<br> <br>
<?php esc_html_e( 'Meanwhile you can switch to some other mailers.', 'wp-mail-smtp' ); ?> <?php esc_html_e( 'Meanwhile you can switch to some other mailers.', 'wp-mail-smtp' ); ?>
</blockquote> </blockquote>
<?php <?php
} }
/** /**
* Display a message of a constant that was set inside wp-config.php file. * Display a message of a constant that was set inside wp-config.php file.
* *
* @since 1.5.0 * @since 1.5.0
* *
* @param string $constant Constant name. * @param string $constant Constant name.
*/ */
protected function display_const_set_message( $constant ) { protected function display_const_set_message( $constant ) {
?> ?>
<p class="desc"> <p class="desc">
<?php <?php
printf( /* translators: %1$s - constant name, %2$s - file name. */ printf( /* translators: %1$s - constant that was used; %2$s - file where it was used. */
esc_html__( 'The value of this field was set using a constant %1$s most likely inside %2$s of your WordPress installation.', 'wp-mail-smtp' ), esc_html__( 'The value of this field was set using a constant %1$s most likely inside %2$s of your WordPress installation.', 'wp-mail-smtp' ),
'<code>' . esc_attr( $constant ) . '</code>', '<code>' . esc_attr( $constant ) . '</code>',
'<code>wp-config.php</code>' '<code>wp-config.php</code>'
); );
?> ?>
</p> </p>
<?php <?php
} }
} }

View File

@ -50,7 +50,7 @@ class Options extends OptionsAbstract {
if ( empty( $api_key ) ) { if ( empty( $api_key ) ) {
$description .= '</p><p class="buttonned"><a href="https://wpmailsmtp.com/go/pepipost/" target="_blank" rel="noopener noreferrer" class="wp-mail-smtp-btn wp-mail-smtp-btn-md wp-mail-smtp-btn-blueish">' . $description .= '</p><p class="buttonned"><a href="https://wpmailsmtp.com/go/pepipost/" target="_blank" rel="noopener noreferrer" class="wp-mail-smtp-btn wp-mail-smtp-btn-md wp-mail-smtp-btn-blueish">' .
esc_html__( 'Get Pepipost Now (Free)', 'wp-mail-smtp' ) . esc_html__( 'Get Started with Pepipost', 'wp-mail-smtp' ) .
'</a></p>'; '</a></p>';
} }
@ -103,7 +103,7 @@ class Options extends OptionsAbstract {
<p class="desc"> <p class="desc">
<?php <?php
printf( /* translators: %s - pepipost.com link to get an API Key. */ printf( /* translators: %s - link to get an API Key. */
esc_html__( 'Follow this link to get an API Key: %s.', 'wp-mail-smtp' ), esc_html__( 'Follow this link to get an API Key: %s.', 'wp-mail-smtp' ),
'<a href="https://app.pepipost.com/app/settings/integration" target="_blank" rel="noopener noreferrer">' . '<a href="https://app.pepipost.com/app/settings/integration" target="_blank" rel="noopener noreferrer">' .
esc_html__( 'Get the API Key', 'wp-mail-smtp' ) . esc_html__( 'Get the API Key', 'wp-mail-smtp' ) .

View File

@ -1,44 +1,44 @@
<?php <?php
namespace WPMailSMTP\Providers\SMTP; namespace WPMailSMTP\Providers\SMTP;
use WPMailSMTP\Providers\OptionsAbstract; use WPMailSMTP\Providers\OptionsAbstract;
/** /**
* Class SMTP. * Class SMTP.
* *
* @since 1.0.0 * @since 1.0.0
*/ */
class Options extends OptionsAbstract { class Options extends OptionsAbstract {
/** /**
* SMTP constructor. * SMTP constructor.
* *
* @since 1.0.0 * @since 1.0.0
*/ */
public function __construct() { public function __construct() {
parent::__construct( parent::__construct(
array( array(
'logo_url' => wp_mail_smtp()->assets_url . '/images/providers/smtp.svg', 'logo_url' => wp_mail_smtp()->assets_url . '/images/providers/smtp.svg',
'slug' => 'smtp', 'slug' => 'smtp',
'title' => esc_html__( 'Other SMTP', 'wp-mail-smtp' ), 'title' => esc_html__( 'Other SMTP', 'wp-mail-smtp' ),
'description' => sprintf( 'description' => sprintf(
wp_kses( wp_kses(
/* translators: %s - URL to a related article on WPForms.com. */ /* translators: %s - URL to SMTP documentation. */
__( 'Use the SMTP details provided by your hosting provider or email service.<br><br>To see recommended settings for the popular services as well as troubleshooting tips, check out our <a href="%s" target="_blank" rel="noopener noreferrer">SMTP documentation</a>.', 'wp-mail-smtp' ), __( 'Use the SMTP details provided by your hosting provider or email service.<br><br>To see recommended settings for the popular services as well as troubleshooting tips, check out our <a href="%s" target="_blank" rel="noopener noreferrer">SMTP documentation</a>.', 'wp-mail-smtp' ),
array( array(
'br' => array(), 'br' => array(),
'a' => array( 'a' => array(
'href' => array(), 'href' => array(),
'rel' => array(), 'rel' => array(),
'target' => array(), 'target' => array(),
), ),
) )
), ),
'https://wpmailsmtp.com/docs/how-to-set-up-the-other-smtp-mailer-in-wp-mail-smtp/' 'https://wpmailsmtp.com/docs/how-to-set-up-the-other-smtp-mailer-in-wp-mail-smtp/'
), ),
) )
); );
} }
} }

View File

@ -0,0 +1,460 @@
<?php
namespace WPMailSMTP\Providers\SMTPcom;
use WPMailSMTP\Providers\MailerAbstract;
use WPMailSMTP\WP;
/**
* Class Mailer for SMTP.com integration.
*
* @see https://www.smtp.com/smtp-api-documentation/ for the API documentation.
*
* @since 2.0.0
*/
class Mailer extends MailerAbstract {
/**
* Which response code from HTTP provider is considered to be successful?
*
* @since 2.0.0
*
* @var int
*/
protected $email_sent_code = 200;
/**
* URL to make an API request to.
*
* @since 2.0.0
*
* @var string
*/
protected $url = 'https://api.smtp.com/v4/messages';
/**
* Mailer constructor.
*
* @since 2.0.0
*
* @param \WPMailSMTP\MailCatcher $phpmailer
*/
public function __construct( $phpmailer ) {
// We want to prefill everything from \WPMailSMTP\MailCatcher class, which extends \PHPMailer.
parent::__construct( $phpmailer );
// Set mailer specific headers.
$this->set_header( 'Authorization', 'Bearer ' . $this->options->get( $this->mailer, 'api_key' ) );
$this->set_header( 'Accept', 'application/json' );
$this->set_header( 'content-type', 'application/json' );
// Set mailer specific body parameters.
$this->set_body_param(
array(
'channel' => $this->options->get( $this->mailer, 'channel' ),
)
);
}
/**
* Redefine the way email body is returned.
* By default we are sending an array of data.
* SMTP.com requires a JSON, so we encode the body.
*
* @since 2.0.0
*/
public function get_body() {
$body = parent::get_body();
return wp_json_encode( $body );
}
/**
* Define the FROM (name and email).
*
* @since 2.0.0
*
* @param string $email From Email address.
* @param string $name From Name.
*/
public function set_from( $email, $name = '' ) {
if ( ! filter_var( $email, FILTER_VALIDATE_EMAIL ) ) {
return;
}
$from['address'] = $email;
if ( ! empty( $name ) ) {
$from['name'] = $name;
}
$this->set_body_param(
array(
'originator' => array(
'from' => $from,
),
)
);
}
/**
* Define the CC/BCC/TO (with names and emails).
*
* @since 2.0.0
*
* @param array $recipients
*/
public function set_recipients( $recipients ) {
if ( empty( $recipients ) ) {
return;
}
// Allow only these recipient types.
$allowed_types = array( 'to', 'cc', 'bcc' );
$data = array();
foreach ( $recipients as $type => $emails ) {
if (
! in_array( $type, $allowed_types, true ) ||
empty( $emails ) ||
! is_array( $emails )
) {
continue;
}
$data[ $type ] = array();
// Iterate over all emails for each type.
// There might be multiple cc/to/bcc emails.
foreach ( $emails as $email ) {
$holder = array();
$address = isset( $email[0] ) ? $email[0] : false;
$name = isset( $email[1] ) ? $email[1] : false;
if ( ! filter_var( $address, FILTER_VALIDATE_EMAIL ) ) {
continue;
}
$holder['address'] = $address;
if ( ! empty( $name ) ) {
$holder['name'] = $name;
}
array_push( $data[ $type ], $holder );
}
}
if ( ! empty( $data ) ) {
$this->set_body_param(
array(
'recipients' => $data,
)
);
}
}
/**
* Set the email content.
*
* @since 2.0.0
*
* @param array|string $content String when text/plain, array otherwise.
*/
public function set_content( $content ) {
if ( empty( $content ) ) {
return;
}
$parts = array();
if ( is_array( $content ) ) {
$allowed = array( 'text', 'html' );
foreach ( $content as $type => $body ) {
if (
! in_array( $type, $allowed, true ) ||
empty( $body )
) {
continue;
}
$content_type = 'text/plain';
$content_value = $body;
if ( $type === 'html' ) {
$content_type = 'text/html';
}
$parts[] = array(
'type' => $content_type,
'content' => $content_value,
'charset' => $this->phpmailer->CharSet,
'encoding' => $this->phpmailer->Encoding,
);
}
} else {
$content_type = 'text/html';
$content_value = $content;
if ( $this->phpmailer->ContentType === 'text/plain' ) {
$content_type = 'text/plain';
}
$parts[] = array(
'type' => $content_type,
'content' => $content_value,
'charset' => $this->phpmailer->CharSet,
'encoding' => $this->phpmailer->Encoding,
);
}
$this->set_body_param(
array(
'body' => array(
'parts' => $parts,
),
)
);
}
/**
* Redefine the way custom headers are processed for this mailer - they should be in body.
*
* @since 2.0.0
*
* @param array $headers
*/
public function set_headers( $headers ) {
foreach ( $headers as $header ) {
$name = isset( $header[0] ) ? $header[0] : false;
$value = isset( $header[1] ) ? $header[1] : false;
$this->set_body_header( $name, $value );
}
// Add custom PHPMailer-specific header.
$this->set_body_header( 'X-Mailer', 'WPMailSMTP/Mailer/' . $this->mailer . ' ' . WPMS_PLUGIN_VER );
}
/**
* This mailer supports email-related custom headers inside a body of the message.
*
* @since 2.0.0
*
* @param string $name
* @param string $value
*/
public function set_body_header( $name, $value ) {
$name = sanitize_text_field( $name );
if ( empty( $name ) ) {
return;
}
$headers = isset( $this->body['custom_headers'] ) ? (array) $this->body['custom_headers'] : array();
$headers[ $name ] = WP::sanitize_value( $value );
$this->set_body_param(
array(
'custom_headers' => $headers,
)
);
}
/**
* SMTP.com accepts an array of attachments in body.attachments section of the JSON payload.
*
* @since 2.0.0
*
* @param array $attachments
*/
public function set_attachments( $attachments ) {
if ( empty( $attachments ) ) {
return;
}
$data = array();
foreach ( $attachments as $attachment ) {
$file = false;
/*
* We are not using WP_Filesystem API as we can't reliably work with it.
* It is not always available, same as credentials for FTP.
*/
try {
if ( is_file( $attachment[0] ) && is_readable( $attachment[0] ) ) {
$file = file_get_contents( $attachment[0] ); // phpcs:ignore
}
}
catch ( \Exception $e ) {
$file = false;
}
if ( $file === false ) {
continue;
}
$filetype = str_replace( ';', '', trim( $attachment[4] ) );
$data[] = array(
'content' => base64_encode( $file ),
'type' => $filetype,
'encoding' => 'base64',
'filename' => empty( $attachment[2] ) ? 'file-' . wp_hash( microtime() ) . '.' . $filetype : trim( $attachment[2] ),
'disposition' => in_array( $attachment[6], array( 'inline', 'attachment' ), true ) ? $attachment[6] : 'attachment', // either inline or attachment.
'cid' => empty( $attachment[7] ) ? '' : trim( (string) $attachment[7] ),
);
}
if ( ! empty( $data ) ) {
$this->set_body_param(
array(
'body' => array(
'attachments' => $data,
),
)
);
}
}
/**
* Set Reply-To part of the message.
*
* @since 2.0.0
*
* @param array $reply_to
*/
public function set_reply_to( $reply_to ) {
if ( empty( $reply_to ) ) {
return;
}
$data = array();
foreach ( $reply_to as $key => $emails ) {
if (
empty( $emails ) ||
! is_array( $emails )
) {
continue;
}
$address = isset( $emails[0] ) ? $emails[0] : false;
$name = isset( $emails[1] ) ? $emails[1] : false;
if ( ! filter_var( $address, FILTER_VALIDATE_EMAIL ) ) {
continue;
}
$data['address'] = $address;
if ( ! empty( $name ) ) {
$data['name'] = $name;
}
// Let the first valid email from the passed $reply_to serve as the reply_to parameter in STMP.com API.
// Only one email address and name is allowed in the `reply_to` parameter in the SMTP.com API payload.
break;
}
if ( ! empty( $data ) ) {
$this->set_body_param(
array(
'originator' => array(
'reply_to' => $data,
),
)
);
}
}
/**
* SMTP.com doesn't support return_path params.
* So we do nothing.
*
* @since 2.0.0
*
* @param string $from_email
*/
public function set_return_path( $from_email ) {}
/**
* Get a SMTP.com-specific response with a helpful error.
*
* SMTP.com API error response (non 200 error code responses) is:
* {
* "status": "fail",
* "data": {
* "error_key": "short error message",
* }
* }
*
* It's good to combine the error_key and the message together for the best error explanation.
*
* @since 2.0.0
*
* @return string
*/
protected function get_response_error() {
$body = (array) wp_remote_retrieve_body( $this->response );
$error_text = array();
if ( ! empty( $body['data'] ) ) {
foreach ( (array) $body['data'] as $error_key => $error_message ) {
$error_text[] = $error_key . ' - ' . $error_message;
}
}
return implode( PHP_EOL, array_map( 'esc_textarea', $error_text ) );
}
/**
* Get mailer debug information, that is helpful during support.
*
* @since 2.0.0
*
* @return string
*/
public function get_debug_info() {
$options = $this->options->get_group( $this->mailer );
$text[] = '<strong>' . esc_html__( 'Api Key:', 'wp-mail-smtp' ) . '</strong> ' .
( ! empty( $options['api_key'] ) ? 'Yes' : 'No' );
$text[] = '<strong>' . esc_html__( 'Channel:', 'wp-mail-smtp' ) . '</strong> ' .
( ! empty( $options['channel'] ) ? 'Yes' : 'No' );
return implode( '<br>', $text );
}
/**
* Whether the mailer has all its settings correctly set up and saved.
*
* This mailer is configured when `api_key` and `channel` settings are defined.
*
* @since 2.0.0
*
* @return bool
*/
public function is_mailer_complete() {
$options = $this->options->get_group( $this->mailer );
if ( ! empty( $options['api_key'] ) && ! empty( $options['channel'] ) ) {
return true;
}
return false;
}
}

View File

@ -0,0 +1,142 @@
<?php
namespace WPMailSMTP\Providers\SMTPcom;
use WPMailSMTP\Options as PluginOptions;
use WPMailSMTP\Providers\OptionsAbstract;
/**
* Class Options.
*
* @since 2.0.0
*/
class Options extends OptionsAbstract {
/**
* Mailer slug.
*
* @since 2.0.0
*/
const SLUG = 'smtpcom';
/**
* Options constructor.
*
* @since 2.0.0
*/
public function __construct() {
$allowed_kses_html = array(
'strong' => array(),
'br' => array(),
'a' => array(
'href' => array(),
'rel' => array(),
'target' => array(),
),
);
$description = sprintf(
wp_kses( /* translators: %s - URL to smtp.com site. */
__( '<strong><a href="%s" target="_blank" rel="noopener noreferrer">SMTP.com</a> is a recommended transactional email service.</strong> With over 22 years of email delivery expertise, SMTP.com has been around for almost as long as email itself. They are known among internet providers as one of the most reliable senders on the internet. Their easy integration process lets you start sending emails in minutes and benefit from years of experience. SMTP.com provides users 10,000 free emails the first 30 days.', 'wp-mail-smtp' ),
$allowed_kses_html
),
'https://wpmailsmtp.com/go/smtp/'
);
$description .= '<br><br>';
$description .= sprintf(
wp_kses( /* translators: %s - URL to wpmailsmtp.com doc page for stmp.com. */
__( 'Read our <a href="%s" target="_blank" rel="noopener noreferrer">SMTP.com documentation</a> to learn how to configure SMTP.com and improve your email deliverability.', 'wp-mail-smtp' ),
$allowed_kses_html
),
'https://wpmailsmtp.com/docs/how-to-set-up-the-smtp-com-mailer-in-wp-mail-smtp'
);
$mailer_options = PluginOptions::init()->get_group( self::SLUG );
if ( empty( $mailer_options['api_key'] ) && empty( $mailer_options['channel'] ) ) {
$description .= '</p><p class="buttonned"><a href="https://wpmailsmtp.com/go/smtp/" target="_blank" rel="noopener noreferrer" class="wp-mail-smtp-btn wp-mail-smtp-btn-md wp-mail-smtp-btn-blueish">' .
esc_html__( 'Get Started with SMTP.com', 'wp-mail-smtp' ) .
'</a></p>';
}
parent::__construct(
array(
'logo_url' => wp_mail_smtp()->assets_url . '/images/providers/smtp-com.svg',
'slug' => self::SLUG,
'title' => esc_html__( 'SMTP.com', 'wp-mail-smtp' ),
'description' => $description,
'recommended' => true,
)
);
}
/**
* @inheritdoc
*/
public function display_options() {
?>
<!-- API Key -->
<div id="wp-mail-smtp-setting-row-<?php echo esc_attr( $this->get_slug() ); ?>-api_key" class="wp-mail-smtp-setting-row wp-mail-smtp-setting-row-text wp-mail-smtp-clear">
<div class="wp-mail-smtp-setting-label">
<label for="wp-mail-smtp-setting-<?php echo esc_attr( $this->get_slug() ); ?>-api_key"><?php esc_html_e( 'API Key', 'wp-mail-smtp' ); ?></label>
</div>
<div class="wp-mail-smtp-setting-field">
<?php if ( $this->options->is_const_defined( $this->get_slug(), 'api_key' ) ) : ?>
<input type="text" disabled value="****************************************"
id="wp-mail-smtp-setting-<?php echo esc_attr( $this->get_slug() ); ?>-api_key"
/>
<?php $this->display_const_set_message( 'WPMS_SMTPCOM_API_KEY' ); ?>
<?php else : ?>
<input type="password" spellcheck="false"
name="wp-mail-smtp[<?php echo esc_attr( $this->get_slug() ); ?>][api_key]"
value="<?php echo esc_attr( $this->options->get( $this->get_slug(), 'api_key' ) ); ?>"
id="wp-mail-smtp-setting-<?php echo esc_attr( $this->get_slug() ); ?>-api_key"
/>
<?php endif; ?>
<p class="desc">
<?php
printf( /* translators: %s - API key link. */
esc_html__( 'Follow this link to get an API Key from SMTP.com: %s.', 'wp-mail-smtp' ),
'<a href="https://my.smtp.com/settings/api" target="_blank" rel="noopener noreferrer">' .
esc_html__( 'Get API Key', 'wp-mail-smtp' ) .
'</a>'
);
?>
</p>
</div>
</div>
<!-- Channel/Sender -->
<div id="wp-mail-smtp-setting-row-<?php echo esc_attr( $this->get_slug() ); ?>-channel" class="wp-mail-smtp-setting-row wp-mail-smtp-setting-row-text wp-mail-smtp-clear">
<div class="wp-mail-smtp-setting-label">
<label for="wp-mail-smtp-setting-<?php echo esc_attr( $this->get_slug() ); ?>-channel"><?php esc_html_e( 'Sender Name', 'wp-mail-smtp' ); ?></label>
</div>
<div class="wp-mail-smtp-setting-field">
<input name="wp-mail-smtp[<?php echo esc_attr( $this->get_slug() ); ?>][channel]" type="text"
value="<?php echo esc_attr( $this->options->get( $this->get_slug(), 'channel' ) ); ?>"
<?php echo $this->options->is_const_defined( $this->get_slug(), 'channel' ) ? 'disabled' : ''; ?>
id="wp-mail-smtp-setting-<?php echo esc_attr( $this->get_slug() ); ?>-channel" spellcheck="false"
/>
<?php
if ( $this->options->is_const_defined( $this->get_slug(), 'channel' ) ) {
$this->display_const_set_message( 'WPMS_SMTPCOM_CHANNEL' );
}
?>
<p class="desc">
<?php
printf( /* translators: %s - Channel/Sender Name link for smtp.com documentation. */
esc_html__( 'Follow this link to get a Sender Name from SMTP.com: %s.', 'wp-mail-smtp' ),
'<a href="https://my.smtp.com/senders/" target="_blank" rel="noopener noreferrer">' .
esc_html__( 'Get Sender Name', 'wp-mail-smtp' ) .
'</a>'
);
?>
</p>
</div>
</div>
<?php
}
}

View File

@ -26,42 +26,30 @@ class Options extends OptionsAbstract {
*/ */
public function __construct() { public function __construct() {
$description = sprintf(
wp_kses( /* translators: %1$s - URL to sendinblue.com site. */
__( '<strong><a href="%1$s" target="_blank" rel="noopener noreferrer">Sendinblue</a> is a recommended transactional email service.</strong> Founded in 2012, they serve 80,000+ growing companies around the world and send over 30 million emails each day. They understand that transactional emails are the heart of your customer relationships. Their email deliverability experts are constantly at work optimizing the reliability and speed of their SMTP infrastructure. Sendinblue provides users 300 free emails per day.', 'wp-mail-smtp' ) .
'<br><br>' .
/* translators: %2$s - URL to wpmailsmtp.com doc. */
__( 'Read our <a href="%2$s" target="_blank" rel="noopener noreferrer">Sendinblue documentation</a> to learn how to configure Sendinblue and improve your email deliverability.', 'wp-mail-smtp' ),
array(
'br' => true,
'strong' => true,
'a' => array(
'href' => true,
'rel' => true,
'target' => true,
),
)
),
'https://wpmailsmtp.com/go/sendinblue/',
'https://wpmailsmtp.com/docs/how-to-set-up-the-sendinblue-mailer-in-wp-mail-smtp'
);
$api_key = PluginOptions::init()->get( self::SLUG, 'api_key' );
if ( empty( $api_key ) ) {
$description .= '</p><p class="buttonned"><a href="https://wpmailsmtp.com/go/sendinblue/" target="_blank" rel="noopener noreferrer" class="wp-mail-smtp-btn wp-mail-smtp-btn-md wp-mail-smtp-btn-blueish">' .
esc_html__( 'Get Sendinblue Now (Free)', 'wp-mail-smtp' ) .
'</a></p>';
}
parent::__construct( parent::__construct(
array( array(
'logo_url' => wp_mail_smtp()->assets_url . '/images/providers/sendinblue.svg', 'logo_url' => wp_mail_smtp()->assets_url . '/images/providers/sendinblue.svg',
'slug' => self::SLUG, 'slug' => self::SLUG,
'title' => esc_html__( 'Sendinblue', 'wp-mail-smtp' ), 'title' => esc_html__( 'Sendinblue', 'wp-mail-smtp' ),
'description' => $description,
'recommended' => true,
'php' => '5.6', 'php' => '5.6',
'description' => sprintf(
wp_kses( /* translators: %1$s - URL to sendinblue.com site. */
__( '<a href="%1$s" target="_blank" rel="noopener noreferrer">Sendinblue</a> serves 80,000+ growing companies around the world and sends over 30 million emails each day. They provide users 300 free emails per day.', 'wp-mail-smtp' ) .
'<br><br>' .
/* translators: %2$s - URL to wpmailsmtp.com doc. */
__( 'Read our <a href="%2$s" target="_blank" rel="noopener noreferrer">Sendinblue documentation</a> to learn how to configure Sendinblue and improve your email deliverability.', 'wp-mail-smtp' ),
array(
'br' => true,
'a' => array(
'href' => true,
'rel' => true,
'target' => true,
),
)
),
'https://wpmailsmtp.com/go/sendinblue/',
'https://wpmailsmtp.com/docs/how-to-set-up-the-sendinblue-mailer-in-wp-mail-smtp'
),
) )
); );
} }
@ -103,7 +91,7 @@ class Options extends OptionsAbstract {
<p class="desc"> <p class="desc">
<?php <?php
printf( /* translators: %s - sendinblue.com link to get an API Key. */ printf( /* translators: %s - link to get an API Key. */
esc_html__( 'Follow this link to get an API Key: %s.', 'wp-mail-smtp' ), esc_html__( 'Follow this link to get an API Key: %s.', 'wp-mail-smtp' ),
'<a href="https://account.sendinblue.com/advanced/api" target="_blank" rel="noopener noreferrer">' . '<a href="https://account.sendinblue.com/advanced/api" target="_blank" rel="noopener noreferrer">' .
esc_html__( 'Get v3 API Key', 'wp-mail-smtp' ) . esc_html__( 'Get v3 API Key', 'wp-mail-smtp' ) .

View File

@ -5,7 +5,7 @@ namespace WPMailSMTP;
/** /**
* Class SiteHealth adds the plugin status and information to the WP Site Health admin page. * Class SiteHealth adds the plugin status and information to the WP Site Health admin page.
* *
* @since {VERSION} * @since 1.9.0
*/ */
class SiteHealth { class SiteHealth {
@ -15,7 +15,7 @@ class SiteHealth {
* *
* @see https://make.wordpress.org/core/2019/04/25/site-health-check-in-5-2/ * @see https://make.wordpress.org/core/2019/04/25/site-health-check-in-5-2/
* *
* @since {VERSION} * @since 1.9.0
*/ */
const BADGE_COLOR = 'blue'; const BADGE_COLOR = 'blue';
@ -24,14 +24,14 @@ class SiteHealth {
* This should be a plugin unique string, which will be used in the WP Site Health page, * This should be a plugin unique string, which will be used in the WP Site Health page,
* for the "info" tab and will present the plugin info section. * for the "info" tab and will present the plugin info section.
* *
* @since {VERSION} * @since 1.9.0
*/ */
const DEBUG_INFO_SLUG = 'wp_mail_smtp'; const DEBUG_INFO_SLUG = 'wp_mail_smtp';
/** /**
* Translatable string for the plugin label. * Translatable string for the plugin label.
* *
* @since {VERSION} * @since 1.9.0
* *
* @return string * @return string
*/ */
@ -43,7 +43,7 @@ class SiteHealth {
/** /**
* Initialize the site heath functionality. * Initialize the site heath functionality.
* *
* @since {VERSION} * @since 1.9.0
*/ */
public function init() { public function init() {
@ -55,7 +55,7 @@ class SiteHealth {
* Register plugin WP site health tests. * Register plugin WP site health tests.
* This will be displayed in the "Status" tab of the WP Site Health page. * This will be displayed in the "Status" tab of the WP Site Health page.
* *
* @since {VERSION} * @since 1.9.0
* *
* @param array $tests The array with all WP site health tests. * @param array $tests The array with all WP site health tests.
* *
@ -75,7 +75,7 @@ class SiteHealth {
* Register plugin WP Site Health debug information. * Register plugin WP Site Health debug information.
* This will be displayed in the "Info" tab of the WP Site Health page. * This will be displayed in the "Info" tab of the WP Site Health page.
* *
* @since {VERSION} * @since 1.9.0
* *
* @param array $debug_info Array of existing debug information. * @param array $debug_info Array of existing debug information.
* *
@ -109,7 +109,7 @@ class SiteHealth {
/** /**
* Perform the WP site health test for checking, if the mailer setup is complete. * Perform the WP site health test for checking, if the mailer setup is complete.
* *
* @since {VERSION} * @since 1.9.0
*/ */
public function mailer_setup_complete_test() { public function mailer_setup_complete_test() {

View File

@ -1,234 +1,234 @@
<?php <?php
namespace WPMailSMTP; namespace WPMailSMTP;
/** /**
* Class WP provides WordPress shortcuts. * Class WP provides WordPress shortcuts.
* *
* @since 1.0.0 * @since 1.0.0
*/ */
class WP { class WP {
/** /**
* The "queue" of notices. * The "queue" of notices.
* *
* @since 1.0.0 * @since 1.0.0
* *
* @var array * @var array
*/ */
protected static $admin_notices = array(); protected static $admin_notices = array();
/** /**
* @since 1.0.0 * @since 1.0.0
* *
* @var string * @var string
*/ */
const ADMIN_NOTICE_SUCCESS = 'notice-success'; const ADMIN_NOTICE_SUCCESS = 'notice-success';
/** /**
* @since 1.0.0 * @since 1.0.0
* *
* @var string * @var string
*/ */
const ADMIN_NOTICE_ERROR = 'notice-error'; const ADMIN_NOTICE_ERROR = 'notice-error';
/** /**
* @since 1.0.0 * @since 1.0.0
* *
* @var string * @var string
*/ */
const ADMIN_NOTICE_INFO = 'notice-info'; const ADMIN_NOTICE_INFO = 'notice-info';
/** /**
* @since 1.0.0 * @since 1.0.0
* *
* @var string * @var string
*/ */
const ADMIN_NOTICE_WARNING = 'notice-warning'; const ADMIN_NOTICE_WARNING = 'notice-warning';
/** /**
* True is WP is processing an AJAX call. * True is WP is processing an AJAX call.
* *
* @since 1.0.0 * @since 1.0.0
* *
* @return bool * @return bool
*/ */
public static function is_doing_ajax() { public static function is_doing_ajax() {
if ( function_exists( 'wp_doing_ajax' ) ) { if ( function_exists( 'wp_doing_ajax' ) ) {
return wp_doing_ajax(); return wp_doing_ajax();
} }
return ( defined( 'DOING_AJAX' ) && DOING_AJAX ); return ( defined( 'DOING_AJAX' ) && DOING_AJAX );
} }
/** /**
* True if I am in the Admin Panel, not doing AJAX. * True if I am in the Admin Panel, not doing AJAX.
* *
* @since 1.0.0 * @since 1.0.0
* *
* @return bool * @return bool
*/ */
public static function in_wp_admin() { public static function in_wp_admin() {
return ( is_admin() && ! self::is_doing_ajax() ); return ( is_admin() && ! self::is_doing_ajax() );
} }
/** /**
* Add a notice to the "queue of notices". * Add a notice to the "queue of notices".
* *
* @since 1.0.0 * @since 1.0.0
* @since 1.5.0 Added `$is_dismissible` param. * @since 1.5.0 Added `$is_dismissible` param.
* *
* @param string $message Message text (HTML is OK). * @param string $message Message text (HTML is OK).
* @param string $class Display class (severity). * @param string $class Display class (severity).
* @param bool $is_dismissible Whether the message should be dismissible. * @param bool $is_dismissible Whether the message should be dismissible.
*/ */
public static function add_admin_notice( $message, $class = self::ADMIN_NOTICE_INFO, $is_dismissible = true ) { public static function add_admin_notice( $message, $class = self::ADMIN_NOTICE_INFO, $is_dismissible = true ) {
self::$admin_notices[] = array( self::$admin_notices[] = array(
'message' => $message, 'message' => $message,
'class' => $class, 'class' => $class,
'is_dismissible' => (bool) $is_dismissible, 'is_dismissible' => (bool) $is_dismissible,
); );
} }
/** /**
* Display all notices. * Display all notices.
* *
* @since 1.0.0 * @since 1.0.0
* @since 1.5.0 Allow the notice to be dismissible, remove the id attribute, which is not unique. * @since 1.5.0 Allow the notice to be dismissible, remove the id attribute, which is not unique.
*/ */
public static function display_admin_notices() { public static function display_admin_notices() {
foreach ( (array) self::$admin_notices as $notice ) : foreach ( (array) self::$admin_notices as $notice ) :
$dismissible = $notice['is_dismissible'] ? 'is-dismissible' : ''; $dismissible = $notice['is_dismissible'] ? 'is-dismissible' : '';
?> ?>
<div class="notice wp-mail-smtp-notice <?php echo esc_attr( $notice['class'] ); ?> notice <?php echo esc_attr( $dismissible ); ?>"> <div class="notice wp-mail-smtp-notice <?php echo esc_attr( $notice['class'] ); ?> notice <?php echo esc_attr( $dismissible ); ?>">
<p> <p>
<?php echo $notice['message']; ?> <?php echo $notice['message']; ?>
</p> </p>
</div> </div>
<?php <?php
endforeach; endforeach;
} }
/** /**
* Check whether WP_DEBUG is active. * Check whether WP_DEBUG is active.
* *
* @since 1.0.0 * @since 1.0.0
* *
* @return bool * @return bool
*/ */
public static function is_debug() { public static function is_debug() {
return defined( 'WP_DEBUG' ) && WP_DEBUG; return defined( 'WP_DEBUG' ) && WP_DEBUG;
} }
/** /**
* Shortcut to global $wpdb. * Shortcut to global $wpdb.
* *
* @since 1.0.0 * @since 1.0.0
* *
* @return \wpdb * @return \wpdb
*/ */
public static function wpdb() { public static function wpdb() {
global $wpdb; global $wpdb;
return $wpdb; return $wpdb;
} }
/** /**
* Get the postfix for assets files - ".min" or empty. * Get the postfix for assets files - ".min" or empty.
* ".min" if in production mode. * ".min" if in production mode.
* *
* @since 1.0.0 * @since 1.0.0
* *
* @return string * @return string
*/ */
public static function asset_min() { public static function asset_min() {
$min = '.min'; $min = '.min';
if ( defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ) { if ( defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ) {
$min = ''; $min = '';
} }
return $min; return $min;
} }
/** /**
* Check whether the string is a JSON or not. * Check whether the string is a JSON or not.
* *
* @since 1.5.0 * @since 1.5.0
* *
* @param string $string * @param string $string
* *
* @return bool * @return bool
*/ */
public static function is_json( $string ) { public static function is_json( $string ) {
return is_string( $string ) && is_array( json_decode( $string, true ) ) && ( json_last_error() === JSON_ERROR_NONE ) ? true : false; return is_string( $string ) && is_array( json_decode( $string, true ) ) && ( json_last_error() === JSON_ERROR_NONE ) ? true : false;
} }
/** /**
* Get the full date format as per WP options. * Get the full date format as per WP options.
* *
* @since 1.5.0 * @since 1.5.0
* *
* @return string * @return string
*/ */
public static function datetime_format() { public static function datetime_format() {
return sprintf( return sprintf(
/* translators: %1$s - date, \a\t - specially escaped "at", %2$s - time. */ /* translators: %1$s - date, \a\t - specially escaped "at", %2$s - time. */
esc_html__( '%1$s \a\t %2$s', 'wp-mail-smtp' ), esc_html__( '%1$s \a\t %2$s', 'wp-mail-smtp' ),
get_option( 'date_format' ), get_option( 'date_format' ),
get_option( 'time_format' ) get_option( 'time_format' )
); );
} }
/** /**
* Get the full date form as per MySQL format. * Get the full date form as per MySQL format.
* *
* @since 1.5.0 * @since 1.5.0
* *
* @return string * @return string
*/ */
public static function datetime_mysql_format() { public static function datetime_mysql_format() {
return 'Y-m-d H:i:s'; return 'Y-m-d H:i:s';
} }
/** /**
* Sanitize the value, similar to sanitize_text_field(), but a bit differently. * Sanitize the value, similar to sanitize_text_field(), but a bit differently.
* It preserves < and > for non-HTML tags. * It preserves `<` and `>` for non-HTML tags.
* *
* @since 1.5.0 * @since 1.5.0
* *
* @param string $value * @param string $value
* *
* @return mixed|string|string[]|null * @return mixed|string|string[]|null
*/ */
public static function sanitize_value( $value ) { public static function sanitize_value( $value ) {
// Remove HTML tags. // Remove HTML tags.
$filtered = wp_strip_all_tags( $value, false ); $filtered = wp_strip_all_tags( $value, false );
// Remove multi-lines/tabs. // Remove multi-lines/tabs.
$filtered = preg_replace( '/[\r\n\t ]+/', ' ', $filtered ); $filtered = preg_replace( '/[\r\n\t ]+/', ' ', $filtered );
// Remove whitespaces. // Remove whitespaces.
$filtered = trim( $filtered ); $filtered = trim( $filtered );
// Remove octets. // Remove octets.
$found = false; $found = false;
while ( preg_match( '/%[a-f0-9]{2}/i', $filtered, $match ) ) { while ( preg_match( '/%[a-f0-9]{2}/i', $filtered, $match ) ) {
$filtered = str_replace( $match[0], '', $filtered ); $filtered = str_replace( $match[0], '', $filtered );
$found = true; $found = true;
} }
if ( $found ) { if ( $found ) {
// Strip out the whitespace that may now exist after removing the octets. // Strip out the whitespace that may now exist after removing the octets.
$filtered = trim( preg_replace( '/ +/', ' ', $filtered ) ); $filtered = trim( preg_replace( '/ +/', ' ', $filtered ) );
} }
return $filtered; return $filtered;
} }
} }

View File

@ -4,4 +4,4 @@
require_once __DIR__ . '/composer/autoload_real.php'; require_once __DIR__ . '/composer/autoload_real.php';
return ComposerAutoloaderInit4589a9f05a03f0a29add21e0e493a064::getLoader(); return ComposerAutoloaderInit72f613a3d0c2cc77892490951b6e5352::getLoader();

View File

@ -9,6 +9,9 @@ return array(
'7b11c4dc42b3b3023073cb14e519683c' => $vendorDir . '/ralouphie/getallheaders/src/getallheaders.php', '7b11c4dc42b3b3023073cb14e519683c' => $vendorDir . '/ralouphie/getallheaders/src/getallheaders.php',
'a0edc8309cc5e1d60e3047b5df6b7052' => $vendorDir . '/guzzlehttp/psr7/src/functions_include.php', 'a0edc8309cc5e1d60e3047b5df6b7052' => $vendorDir . '/guzzlehttp/psr7/src/functions_include.php',
'c964ee0ededf28c96ebd9db5099ef910' => $vendorDir . '/guzzlehttp/promises/src/functions_include.php', 'c964ee0ededf28c96ebd9db5099ef910' => $vendorDir . '/guzzlehttp/promises/src/functions_include.php',
'0e6d7bf4a5811bfa5cf40c5ccd6fae6a' => $vendorDir . '/symfony/polyfill-mbstring/bootstrap.php',
'25072dd6e2470089de65ae7bf11d3109' => $vendorDir . '/symfony/polyfill-php72/bootstrap.php',
'f598d06aa772fa33d905e87be6398fb1' => $vendorDir . '/symfony/polyfill-intl-idn/bootstrap.php',
'37a3dc5111fe8f707ab4c132ef1dbc62' => $vendorDir . '/guzzlehttp/guzzle/src/functions_include.php', '37a3dc5111fe8f707ab4c132ef1dbc62' => $vendorDir . '/guzzlehttp/guzzle/src/functions_include.php',
'decc78cc4436b1292c6c0d151b19445c' => $vendorDir . '/phpseclib/phpseclib/phpseclib/bootstrap.php', 'decc78cc4436b1292c6c0d151b19445c' => $vendorDir . '/phpseclib/phpseclib/phpseclib/bootstrap.php',
); );

View File

@ -8,6 +8,9 @@ $baseDir = dirname($vendorDir);
return array( return array(
'phpseclib\\' => array($vendorDir . '/phpseclib/phpseclib/phpseclib'), 'phpseclib\\' => array($vendorDir . '/phpseclib/phpseclib/phpseclib'),
'WPMailSMTP\\' => array($baseDir . '/src'), 'WPMailSMTP\\' => array($baseDir . '/src'),
'Symfony\\Polyfill\\Php72\\' => array($vendorDir . '/symfony/polyfill-php72'),
'Symfony\\Polyfill\\Mbstring\\' => array($vendorDir . '/symfony/polyfill-mbstring'),
'Symfony\\Polyfill\\Intl\\Idn\\' => array($vendorDir . '/symfony/polyfill-intl-idn'),
'SendinBlue\\Client\\' => array($vendorDir . '/sendinblue/api-v3-sdk/lib'), 'SendinBlue\\Client\\' => array($vendorDir . '/sendinblue/api-v3-sdk/lib'),
'Psr\\Log\\' => array($vendorDir . '/psr/log/Psr/Log'), 'Psr\\Log\\' => array($vendorDir . '/psr/log/Psr/Log'),
'Psr\\Http\\Message\\' => array($vendorDir . '/psr/http-message/src'), 'Psr\\Http\\Message\\' => array($vendorDir . '/psr/http-message/src'),

View File

@ -2,7 +2,7 @@
// autoload_real.php @generated by Composer // autoload_real.php @generated by Composer
class ComposerAutoloaderInit4589a9f05a03f0a29add21e0e493a064 class ComposerAutoloaderInit72f613a3d0c2cc77892490951b6e5352
{ {
private static $loader; private static $loader;
@ -13,21 +13,24 @@ class ComposerAutoloaderInit4589a9f05a03f0a29add21e0e493a064
} }
} }
/**
* @return \Composer\Autoload\ClassLoader
*/
public static function getLoader() public static function getLoader()
{ {
if (null !== self::$loader) { if (null !== self::$loader) {
return self::$loader; return self::$loader;
} }
spl_autoload_register(array('ComposerAutoloaderInit4589a9f05a03f0a29add21e0e493a064', 'loadClassLoader'), true, true); spl_autoload_register(array('ComposerAutoloaderInit72f613a3d0c2cc77892490951b6e5352', 'loadClassLoader'), true, true);
self::$loader = $loader = new \Composer\Autoload\ClassLoader(); self::$loader = $loader = new \Composer\Autoload\ClassLoader();
spl_autoload_unregister(array('ComposerAutoloaderInit4589a9f05a03f0a29add21e0e493a064', 'loadClassLoader')); spl_autoload_unregister(array('ComposerAutoloaderInit72f613a3d0c2cc77892490951b6e5352', 'loadClassLoader'));
$useStaticLoader = PHP_VERSION_ID >= 50600 && !defined('HHVM_VERSION') && (!function_exists('zend_loader_file_encoded') || !zend_loader_file_encoded()); $useStaticLoader = PHP_VERSION_ID >= 50600 && !defined('HHVM_VERSION') && (!function_exists('zend_loader_file_encoded') || !zend_loader_file_encoded());
if ($useStaticLoader) { if ($useStaticLoader) {
require_once __DIR__ . '/autoload_static.php'; require_once __DIR__ . '/autoload_static.php';
call_user_func(\Composer\Autoload\ComposerStaticInit4589a9f05a03f0a29add21e0e493a064::getInitializer($loader)); call_user_func(\Composer\Autoload\ComposerStaticInit72f613a3d0c2cc77892490951b6e5352::getInitializer($loader));
} else { } else {
$map = require __DIR__ . '/autoload_namespaces.php'; $map = require __DIR__ . '/autoload_namespaces.php';
foreach ($map as $namespace => $path) { foreach ($map as $namespace => $path) {
@ -48,19 +51,19 @@ class ComposerAutoloaderInit4589a9f05a03f0a29add21e0e493a064
$loader->register(true); $loader->register(true);
if ($useStaticLoader) { if ($useStaticLoader) {
$includeFiles = Composer\Autoload\ComposerStaticInit4589a9f05a03f0a29add21e0e493a064::$files; $includeFiles = Composer\Autoload\ComposerStaticInit72f613a3d0c2cc77892490951b6e5352::$files;
} else { } else {
$includeFiles = require __DIR__ . '/autoload_files.php'; $includeFiles = require __DIR__ . '/autoload_files.php';
} }
foreach ($includeFiles as $fileIdentifier => $file) { foreach ($includeFiles as $fileIdentifier => $file) {
composerRequire4589a9f05a03f0a29add21e0e493a064($fileIdentifier, $file); composerRequire72f613a3d0c2cc77892490951b6e5352($fileIdentifier, $file);
} }
return $loader; return $loader;
} }
} }
function composerRequire4589a9f05a03f0a29add21e0e493a064($fileIdentifier, $file) function composerRequire72f613a3d0c2cc77892490951b6e5352($fileIdentifier, $file)
{ {
if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) { if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) {
require $file; require $file;

View File

@ -4,12 +4,15 @@
namespace Composer\Autoload; namespace Composer\Autoload;
class ComposerStaticInit4589a9f05a03f0a29add21e0e493a064 class ComposerStaticInit72f613a3d0c2cc77892490951b6e5352
{ {
public static $files = array ( public static $files = array (
'7b11c4dc42b3b3023073cb14e519683c' => __DIR__ . '/..' . '/ralouphie/getallheaders/src/getallheaders.php', '7b11c4dc42b3b3023073cb14e519683c' => __DIR__ . '/..' . '/ralouphie/getallheaders/src/getallheaders.php',
'a0edc8309cc5e1d60e3047b5df6b7052' => __DIR__ . '/..' . '/guzzlehttp/psr7/src/functions_include.php', 'a0edc8309cc5e1d60e3047b5df6b7052' => __DIR__ . '/..' . '/guzzlehttp/psr7/src/functions_include.php',
'c964ee0ededf28c96ebd9db5099ef910' => __DIR__ . '/..' . '/guzzlehttp/promises/src/functions_include.php', 'c964ee0ededf28c96ebd9db5099ef910' => __DIR__ . '/..' . '/guzzlehttp/promises/src/functions_include.php',
'0e6d7bf4a5811bfa5cf40c5ccd6fae6a' => __DIR__ . '/..' . '/symfony/polyfill-mbstring/bootstrap.php',
'25072dd6e2470089de65ae7bf11d3109' => __DIR__ . '/..' . '/symfony/polyfill-php72/bootstrap.php',
'f598d06aa772fa33d905e87be6398fb1' => __DIR__ . '/..' . '/symfony/polyfill-intl-idn/bootstrap.php',
'37a3dc5111fe8f707ab4c132ef1dbc62' => __DIR__ . '/..' . '/guzzlehttp/guzzle/src/functions_include.php', '37a3dc5111fe8f707ab4c132ef1dbc62' => __DIR__ . '/..' . '/guzzlehttp/guzzle/src/functions_include.php',
'decc78cc4436b1292c6c0d151b19445c' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/bootstrap.php', 'decc78cc4436b1292c6c0d151b19445c' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/bootstrap.php',
); );
@ -25,6 +28,9 @@ class ComposerStaticInit4589a9f05a03f0a29add21e0e493a064
), ),
'S' => 'S' =>
array ( array (
'Symfony\\Polyfill\\Php72\\' => 23,
'Symfony\\Polyfill\\Mbstring\\' => 26,
'Symfony\\Polyfill\\Intl\\Idn\\' => 26,
'SendinBlue\\Client\\' => 18, 'SendinBlue\\Client\\' => 18,
), ),
'P' => 'P' =>
@ -63,6 +69,18 @@ class ComposerStaticInit4589a9f05a03f0a29add21e0e493a064
array ( array (
0 => __DIR__ . '/../..' . '/src', 0 => __DIR__ . '/../..' . '/src',
), ),
'Symfony\\Polyfill\\Php72\\' =>
array (
0 => __DIR__ . '/..' . '/symfony/polyfill-php72',
),
'Symfony\\Polyfill\\Mbstring\\' =>
array (
0 => __DIR__ . '/..' . '/symfony/polyfill-mbstring',
),
'Symfony\\Polyfill\\Intl\\Idn\\' =>
array (
0 => __DIR__ . '/..' . '/symfony/polyfill-intl-idn',
),
'SendinBlue\\Client\\' => 'SendinBlue\\Client\\' =>
array ( array (
0 => __DIR__ . '/..' . '/sendinblue/api-v3-sdk/lib', 0 => __DIR__ . '/..' . '/sendinblue/api-v3-sdk/lib',
@ -131,10 +149,10 @@ class ComposerStaticInit4589a9f05a03f0a29add21e0e493a064
public static function getInitializer(ClassLoader $loader) public static function getInitializer(ClassLoader $loader)
{ {
return \Closure::bind(function () use ($loader) { return \Closure::bind(function () use ($loader) {
$loader->prefixLengthsPsr4 = ComposerStaticInit4589a9f05a03f0a29add21e0e493a064::$prefixLengthsPsr4; $loader->prefixLengthsPsr4 = ComposerStaticInit72f613a3d0c2cc77892490951b6e5352::$prefixLengthsPsr4;
$loader->prefixDirsPsr4 = ComposerStaticInit4589a9f05a03f0a29add21e0e493a064::$prefixDirsPsr4; $loader->prefixDirsPsr4 = ComposerStaticInit72f613a3d0c2cc77892490951b6e5352::$prefixDirsPsr4;
$loader->prefixesPsr0 = ComposerStaticInit4589a9f05a03f0a29add21e0e493a064::$prefixesPsr0; $loader->prefixesPsr0 = ComposerStaticInit72f613a3d0c2cc77892490951b6e5352::$prefixesPsr0;
$loader->classMap = ComposerStaticInit4589a9f05a03f0a29add21e0e493a064::$classMap; $loader->classMap = ComposerStaticInit72f613a3d0c2cc77892490951b6e5352::$classMap;
}, null, ClassLoader::class); }, null, ClassLoader::class);
} }

View File

@ -19,7 +19,8 @@
* Service definition for Gmail (v1). * Service definition for Gmail (v1).
* *
* <p> * <p>
* Access Gmail mailboxes including sending user email.</p> * The Gmail API lets you view and manage Gmail mailbox data like threads,
* messages, and labels.</p>
* *
* <p> * <p>
* For more information about this service, see the API * For more information about this service, see the API
@ -33,6 +34,18 @@ class Google_Service_Gmail extends Google_Service
/** Read, compose, send, and permanently delete all your email from Gmail. */ /** Read, compose, send, and permanently delete all your email from Gmail. */
const MAIL_GOOGLE_COM = const MAIL_GOOGLE_COM =
"https://mail.google.com/"; "https://mail.google.com/";
/** Manage drafts and send emails when you interact with the add-on. */
const GMAIL_ADDONS_CURRENT_ACTION_COMPOSE =
"https://www.googleapis.com/auth/gmail.addons.current.action.compose";
/** View your email messages when you interact with the add-on. */
const GMAIL_ADDONS_CURRENT_MESSAGE_ACTION =
"https://www.googleapis.com/auth/gmail.addons.current.message.action";
/** View your email message metadata when the add-on is running. */
const GMAIL_ADDONS_CURRENT_MESSAGE_METADATA =
"https://www.googleapis.com/auth/gmail.addons.current.message.metadata";
/** View your email messages when the add-on is running. */
const GMAIL_ADDONS_CURRENT_MESSAGE_READONLY =
"https://www.googleapis.com/auth/gmail.addons.current.message.readonly";
/** Manage drafts and send emails. */ /** Manage drafts and send emails. */
const GMAIL_COMPOSE = const GMAIL_COMPOSE =
"https://www.googleapis.com/auth/gmail.compose"; "https://www.googleapis.com/auth/gmail.compose";
@ -85,8 +98,8 @@ class Google_Service_Gmail extends Google_Service
{ {
parent::__construct($client); parent::__construct($client);
$this->rootUrl = $rootUrl ?: 'https://www.googleapis.com/'; $this->rootUrl = $rootUrl ?: 'https://www.googleapis.com/';
$this->servicePath = 'gmail/v1/users/'; $this->servicePath = '';
$this->batchPath = 'batch/gmail/v1'; $this->batchPath = 'batch';
$this->version = 'v1'; $this->version = 'v1';
$this->serviceName = 'gmail'; $this->serviceName = 'gmail';
@ -97,7 +110,7 @@ class Google_Service_Gmail extends Google_Service
array( array(
'methods' => array( 'methods' => array(
'getProfile' => array( 'getProfile' => array(
'path' => '{userId}/profile', 'path' => 'gmail/v1/users/{userId}/profile',
'httpMethod' => 'GET', 'httpMethod' => 'GET',
'parameters' => array( 'parameters' => array(
'userId' => array( 'userId' => array(
@ -107,7 +120,7 @@ class Google_Service_Gmail extends Google_Service
), ),
), ),
),'stop' => array( ),'stop' => array(
'path' => '{userId}/stop', 'path' => 'gmail/v1/users/{userId}/stop',
'httpMethod' => 'POST', 'httpMethod' => 'POST',
'parameters' => array( 'parameters' => array(
'userId' => array( 'userId' => array(
@ -117,7 +130,7 @@ class Google_Service_Gmail extends Google_Service
), ),
), ),
),'watch' => array( ),'watch' => array(
'path' => '{userId}/watch', 'path' => 'gmail/v1/users/{userId}/watch',
'httpMethod' => 'POST', 'httpMethod' => 'POST',
'parameters' => array( 'parameters' => array(
'userId' => array( 'userId' => array(
@ -137,7 +150,7 @@ class Google_Service_Gmail extends Google_Service
array( array(
'methods' => array( 'methods' => array(
'create' => array( 'create' => array(
'path' => '{userId}/drafts', 'path' => 'gmail/v1/users/{userId}/drafts',
'httpMethod' => 'POST', 'httpMethod' => 'POST',
'parameters' => array( 'parameters' => array(
'userId' => array( 'userId' => array(
@ -147,7 +160,7 @@ class Google_Service_Gmail extends Google_Service
), ),
), ),
),'delete' => array( ),'delete' => array(
'path' => '{userId}/drafts/{id}', 'path' => 'gmail/v1/users/{userId}/drafts/{id}',
'httpMethod' => 'DELETE', 'httpMethod' => 'DELETE',
'parameters' => array( 'parameters' => array(
'userId' => array( 'userId' => array(
@ -162,7 +175,7 @@ class Google_Service_Gmail extends Google_Service
), ),
), ),
),'get' => array( ),'get' => array(
'path' => '{userId}/drafts/{id}', 'path' => 'gmail/v1/users/{userId}/drafts/{id}',
'httpMethod' => 'GET', 'httpMethod' => 'GET',
'parameters' => array( 'parameters' => array(
'userId' => array( 'userId' => array(
@ -181,7 +194,7 @@ class Google_Service_Gmail extends Google_Service
), ),
), ),
),'list' => array( ),'list' => array(
'path' => '{userId}/drafts', 'path' => 'gmail/v1/users/{userId}/drafts',
'httpMethod' => 'GET', 'httpMethod' => 'GET',
'parameters' => array( 'parameters' => array(
'userId' => array( 'userId' => array(
@ -193,10 +206,6 @@ class Google_Service_Gmail extends Google_Service
'location' => 'query', 'location' => 'query',
'type' => 'boolean', 'type' => 'boolean',
), ),
'maxResults' => array(
'location' => 'query',
'type' => 'integer',
),
'pageToken' => array( 'pageToken' => array(
'location' => 'query', 'location' => 'query',
'type' => 'string', 'type' => 'string',
@ -205,9 +214,13 @@ class Google_Service_Gmail extends Google_Service
'location' => 'query', 'location' => 'query',
'type' => 'string', 'type' => 'string',
), ),
'maxResults' => array(
'location' => 'query',
'type' => 'integer',
),
), ),
),'send' => array( ),'send' => array(
'path' => '{userId}/drafts/send', 'path' => 'gmail/v1/users/{userId}/drafts/send',
'httpMethod' => 'POST', 'httpMethod' => 'POST',
'parameters' => array( 'parameters' => array(
'userId' => array( 'userId' => array(
@ -217,7 +230,7 @@ class Google_Service_Gmail extends Google_Service
), ),
), ),
),'update' => array( ),'update' => array(
'path' => '{userId}/drafts/{id}', 'path' => 'gmail/v1/users/{userId}/drafts/{id}',
'httpMethod' => 'PUT', 'httpMethod' => 'PUT',
'parameters' => array( 'parameters' => array(
'userId' => array( 'userId' => array(
@ -242,7 +255,7 @@ class Google_Service_Gmail extends Google_Service
array( array(
'methods' => array( 'methods' => array(
'list' => array( 'list' => array(
'path' => '{userId}/history', 'path' => 'gmail/v1/users/{userId}/history',
'httpMethod' => 'GET', 'httpMethod' => 'GET',
'parameters' => array( 'parameters' => array(
'userId' => array( 'userId' => array(
@ -250,10 +263,9 @@ class Google_Service_Gmail extends Google_Service
'type' => 'string', 'type' => 'string',
'required' => true, 'required' => true,
), ),
'historyTypes' => array( 'pageToken' => array(
'location' => 'query', 'location' => 'query',
'type' => 'string', 'type' => 'string',
'repeated' => true,
), ),
'labelId' => array( 'labelId' => array(
'location' => 'query', 'location' => 'query',
@ -263,9 +275,10 @@ class Google_Service_Gmail extends Google_Service
'location' => 'query', 'location' => 'query',
'type' => 'integer', 'type' => 'integer',
), ),
'pageToken' => array( 'historyTypes' => array(
'location' => 'query', 'location' => 'query',
'type' => 'string', 'type' => 'string',
'repeated' => true,
), ),
'startHistoryId' => array( 'startHistoryId' => array(
'location' => 'query', 'location' => 'query',
@ -283,7 +296,7 @@ class Google_Service_Gmail extends Google_Service
array( array(
'methods' => array( 'methods' => array(
'create' => array( 'create' => array(
'path' => '{userId}/labels', 'path' => 'gmail/v1/users/{userId}/labels',
'httpMethod' => 'POST', 'httpMethod' => 'POST',
'parameters' => array( 'parameters' => array(
'userId' => array( 'userId' => array(
@ -293,7 +306,7 @@ class Google_Service_Gmail extends Google_Service
), ),
), ),
),'delete' => array( ),'delete' => array(
'path' => '{userId}/labels/{id}', 'path' => 'gmail/v1/users/{userId}/labels/{id}',
'httpMethod' => 'DELETE', 'httpMethod' => 'DELETE',
'parameters' => array( 'parameters' => array(
'userId' => array( 'userId' => array(
@ -308,7 +321,7 @@ class Google_Service_Gmail extends Google_Service
), ),
), ),
),'get' => array( ),'get' => array(
'path' => '{userId}/labels/{id}', 'path' => 'gmail/v1/users/{userId}/labels/{id}',
'httpMethod' => 'GET', 'httpMethod' => 'GET',
'parameters' => array( 'parameters' => array(
'userId' => array( 'userId' => array(
@ -323,7 +336,7 @@ class Google_Service_Gmail extends Google_Service
), ),
), ),
),'list' => array( ),'list' => array(
'path' => '{userId}/labels', 'path' => 'gmail/v1/users/{userId}/labels',
'httpMethod' => 'GET', 'httpMethod' => 'GET',
'parameters' => array( 'parameters' => array(
'userId' => array( 'userId' => array(
@ -333,7 +346,7 @@ class Google_Service_Gmail extends Google_Service
), ),
), ),
),'patch' => array( ),'patch' => array(
'path' => '{userId}/labels/{id}', 'path' => 'gmail/v1/users/{userId}/labels/{id}',
'httpMethod' => 'PATCH', 'httpMethod' => 'PATCH',
'parameters' => array( 'parameters' => array(
'userId' => array( 'userId' => array(
@ -348,7 +361,7 @@ class Google_Service_Gmail extends Google_Service
), ),
), ),
),'update' => array( ),'update' => array(
'path' => '{userId}/labels/{id}', 'path' => 'gmail/v1/users/{userId}/labels/{id}',
'httpMethod' => 'PUT', 'httpMethod' => 'PUT',
'parameters' => array( 'parameters' => array(
'userId' => array( 'userId' => array(
@ -373,7 +386,7 @@ class Google_Service_Gmail extends Google_Service
array( array(
'methods' => array( 'methods' => array(
'batchDelete' => array( 'batchDelete' => array(
'path' => '{userId}/messages/batchDelete', 'path' => 'gmail/v1/users/{userId}/messages/batchDelete',
'httpMethod' => 'POST', 'httpMethod' => 'POST',
'parameters' => array( 'parameters' => array(
'userId' => array( 'userId' => array(
@ -383,7 +396,7 @@ class Google_Service_Gmail extends Google_Service
), ),
), ),
),'batchModify' => array( ),'batchModify' => array(
'path' => '{userId}/messages/batchModify', 'path' => 'gmail/v1/users/{userId}/messages/batchModify',
'httpMethod' => 'POST', 'httpMethod' => 'POST',
'parameters' => array( 'parameters' => array(
'userId' => array( 'userId' => array(
@ -393,7 +406,7 @@ class Google_Service_Gmail extends Google_Service
), ),
), ),
),'delete' => array( ),'delete' => array(
'path' => '{userId}/messages/{id}', 'path' => 'gmail/v1/users/{userId}/messages/{id}',
'httpMethod' => 'DELETE', 'httpMethod' => 'DELETE',
'parameters' => array( 'parameters' => array(
'userId' => array( 'userId' => array(
@ -408,7 +421,7 @@ class Google_Service_Gmail extends Google_Service
), ),
), ),
),'get' => array( ),'get' => array(
'path' => '{userId}/messages/{id}', 'path' => 'gmail/v1/users/{userId}/messages/{id}',
'httpMethod' => 'GET', 'httpMethod' => 'GET',
'parameters' => array( 'parameters' => array(
'userId' => array( 'userId' => array(
@ -421,18 +434,18 @@ class Google_Service_Gmail extends Google_Service
'type' => 'string', 'type' => 'string',
'required' => true, 'required' => true,
), ),
'format' => array(
'location' => 'query',
'type' => 'string',
),
'metadataHeaders' => array( 'metadataHeaders' => array(
'location' => 'query', 'location' => 'query',
'type' => 'string', 'type' => 'string',
'repeated' => true, 'repeated' => true,
), ),
'format' => array(
'location' => 'query',
'type' => 'string',
),
), ),
),'import' => array( ),'import' => array(
'path' => '{userId}/messages/import', 'path' => 'gmail/v1/users/{userId}/messages/import',
'httpMethod' => 'POST', 'httpMethod' => 'POST',
'parameters' => array( 'parameters' => array(
'userId' => array( 'userId' => array(
@ -440,7 +453,7 @@ class Google_Service_Gmail extends Google_Service
'type' => 'string', 'type' => 'string',
'required' => true, 'required' => true,
), ),
'deleted' => array( 'processForCalendar' => array(
'location' => 'query', 'location' => 'query',
'type' => 'boolean', 'type' => 'boolean',
), ),
@ -452,13 +465,13 @@ class Google_Service_Gmail extends Google_Service
'location' => 'query', 'location' => 'query',
'type' => 'boolean', 'type' => 'boolean',
), ),
'processForCalendar' => array( 'deleted' => array(
'location' => 'query', 'location' => 'query',
'type' => 'boolean', 'type' => 'boolean',
), ),
), ),
),'insert' => array( ),'insert' => array(
'path' => '{userId}/messages', 'path' => 'gmail/v1/users/{userId}/messages',
'httpMethod' => 'POST', 'httpMethod' => 'POST',
'parameters' => array( 'parameters' => array(
'userId' => array( 'userId' => array(
@ -466,17 +479,17 @@ class Google_Service_Gmail extends Google_Service
'type' => 'string', 'type' => 'string',
'required' => true, 'required' => true,
), ),
'deleted' => array(
'location' => 'query',
'type' => 'boolean',
),
'internalDateSource' => array( 'internalDateSource' => array(
'location' => 'query', 'location' => 'query',
'type' => 'string', 'type' => 'string',
), ),
'deleted' => array(
'location' => 'query',
'type' => 'boolean',
),
), ),
),'list' => array( ),'list' => array(
'path' => '{userId}/messages', 'path' => 'gmail/v1/users/{userId}/messages',
'httpMethod' => 'GET', 'httpMethod' => 'GET',
'parameters' => array( 'parameters' => array(
'userId' => array( 'userId' => array(
@ -488,26 +501,26 @@ class Google_Service_Gmail extends Google_Service
'location' => 'query', 'location' => 'query',
'type' => 'boolean', 'type' => 'boolean',
), ),
'pageToken' => array(
'location' => 'query',
'type' => 'string',
),
'labelIds' => array( 'labelIds' => array(
'location' => 'query', 'location' => 'query',
'type' => 'string', 'type' => 'string',
'repeated' => true, 'repeated' => true,
), ),
'maxResults' => array(
'location' => 'query',
'type' => 'integer',
),
'pageToken' => array(
'location' => 'query',
'type' => 'string',
),
'q' => array( 'q' => array(
'location' => 'query', 'location' => 'query',
'type' => 'string', 'type' => 'string',
), ),
'maxResults' => array(
'location' => 'query',
'type' => 'integer',
),
), ),
),'modify' => array( ),'modify' => array(
'path' => '{userId}/messages/{id}/modify', 'path' => 'gmail/v1/users/{userId}/messages/{id}/modify',
'httpMethod' => 'POST', 'httpMethod' => 'POST',
'parameters' => array( 'parameters' => array(
'userId' => array( 'userId' => array(
@ -522,7 +535,7 @@ class Google_Service_Gmail extends Google_Service
), ),
), ),
),'send' => array( ),'send' => array(
'path' => '{userId}/messages/send', 'path' => 'gmail/v1/users/{userId}/messages/send',
'httpMethod' => 'POST', 'httpMethod' => 'POST',
'parameters' => array( 'parameters' => array(
'userId' => array( 'userId' => array(
@ -532,7 +545,7 @@ class Google_Service_Gmail extends Google_Service
), ),
), ),
),'trash' => array( ),'trash' => array(
'path' => '{userId}/messages/{id}/trash', 'path' => 'gmail/v1/users/{userId}/messages/{id}/trash',
'httpMethod' => 'POST', 'httpMethod' => 'POST',
'parameters' => array( 'parameters' => array(
'userId' => array( 'userId' => array(
@ -547,7 +560,7 @@ class Google_Service_Gmail extends Google_Service
), ),
), ),
),'untrash' => array( ),'untrash' => array(
'path' => '{userId}/messages/{id}/untrash', 'path' => 'gmail/v1/users/{userId}/messages/{id}/untrash',
'httpMethod' => 'POST', 'httpMethod' => 'POST',
'parameters' => array( 'parameters' => array(
'userId' => array( 'userId' => array(
@ -572,7 +585,7 @@ class Google_Service_Gmail extends Google_Service
array( array(
'methods' => array( 'methods' => array(
'get' => array( 'get' => array(
'path' => '{userId}/messages/{messageId}/attachments/{id}', 'path' => 'gmail/v1/users/{userId}/messages/{messageId}/attachments/{id}',
'httpMethod' => 'GET', 'httpMethod' => 'GET',
'parameters' => array( 'parameters' => array(
'userId' => array( 'userId' => array(
@ -602,7 +615,7 @@ class Google_Service_Gmail extends Google_Service
array( array(
'methods' => array( 'methods' => array(
'getAutoForwarding' => array( 'getAutoForwarding' => array(
'path' => '{userId}/settings/autoForwarding', 'path' => 'gmail/v1/users/{userId}/settings/autoForwarding',
'httpMethod' => 'GET', 'httpMethod' => 'GET',
'parameters' => array( 'parameters' => array(
'userId' => array( 'userId' => array(
@ -612,7 +625,7 @@ class Google_Service_Gmail extends Google_Service
), ),
), ),
),'getImap' => array( ),'getImap' => array(
'path' => '{userId}/settings/imap', 'path' => 'gmail/v1/users/{userId}/settings/imap',
'httpMethod' => 'GET', 'httpMethod' => 'GET',
'parameters' => array( 'parameters' => array(
'userId' => array( 'userId' => array(
@ -622,7 +635,7 @@ class Google_Service_Gmail extends Google_Service
), ),
), ),
),'getLanguage' => array( ),'getLanguage' => array(
'path' => '{userId}/settings/language', 'path' => 'gmail/v1/users/{userId}/settings/language',
'httpMethod' => 'GET', 'httpMethod' => 'GET',
'parameters' => array( 'parameters' => array(
'userId' => array( 'userId' => array(
@ -632,7 +645,7 @@ class Google_Service_Gmail extends Google_Service
), ),
), ),
),'getPop' => array( ),'getPop' => array(
'path' => '{userId}/settings/pop', 'path' => 'gmail/v1/users/{userId}/settings/pop',
'httpMethod' => 'GET', 'httpMethod' => 'GET',
'parameters' => array( 'parameters' => array(
'userId' => array( 'userId' => array(
@ -642,7 +655,7 @@ class Google_Service_Gmail extends Google_Service
), ),
), ),
),'getVacation' => array( ),'getVacation' => array(
'path' => '{userId}/settings/vacation', 'path' => 'gmail/v1/users/{userId}/settings/vacation',
'httpMethod' => 'GET', 'httpMethod' => 'GET',
'parameters' => array( 'parameters' => array(
'userId' => array( 'userId' => array(
@ -652,7 +665,7 @@ class Google_Service_Gmail extends Google_Service
), ),
), ),
),'updateAutoForwarding' => array( ),'updateAutoForwarding' => array(
'path' => '{userId}/settings/autoForwarding', 'path' => 'gmail/v1/users/{userId}/settings/autoForwarding',
'httpMethod' => 'PUT', 'httpMethod' => 'PUT',
'parameters' => array( 'parameters' => array(
'userId' => array( 'userId' => array(
@ -662,7 +675,7 @@ class Google_Service_Gmail extends Google_Service
), ),
), ),
),'updateImap' => array( ),'updateImap' => array(
'path' => '{userId}/settings/imap', 'path' => 'gmail/v1/users/{userId}/settings/imap',
'httpMethod' => 'PUT', 'httpMethod' => 'PUT',
'parameters' => array( 'parameters' => array(
'userId' => array( 'userId' => array(
@ -672,7 +685,7 @@ class Google_Service_Gmail extends Google_Service
), ),
), ),
),'updateLanguage' => array( ),'updateLanguage' => array(
'path' => '{userId}/settings/language', 'path' => 'gmail/v1/users/{userId}/settings/language',
'httpMethod' => 'PUT', 'httpMethod' => 'PUT',
'parameters' => array( 'parameters' => array(
'userId' => array( 'userId' => array(
@ -682,7 +695,7 @@ class Google_Service_Gmail extends Google_Service
), ),
), ),
),'updatePop' => array( ),'updatePop' => array(
'path' => '{userId}/settings/pop', 'path' => 'gmail/v1/users/{userId}/settings/pop',
'httpMethod' => 'PUT', 'httpMethod' => 'PUT',
'parameters' => array( 'parameters' => array(
'userId' => array( 'userId' => array(
@ -692,7 +705,7 @@ class Google_Service_Gmail extends Google_Service
), ),
), ),
),'updateVacation' => array( ),'updateVacation' => array(
'path' => '{userId}/settings/vacation', 'path' => 'gmail/v1/users/{userId}/settings/vacation',
'httpMethod' => 'PUT', 'httpMethod' => 'PUT',
'parameters' => array( 'parameters' => array(
'userId' => array( 'userId' => array(
@ -712,7 +725,7 @@ class Google_Service_Gmail extends Google_Service
array( array(
'methods' => array( 'methods' => array(
'create' => array( 'create' => array(
'path' => '{userId}/settings/delegates', 'path' => 'gmail/v1/users/{userId}/settings/delegates',
'httpMethod' => 'POST', 'httpMethod' => 'POST',
'parameters' => array( 'parameters' => array(
'userId' => array( 'userId' => array(
@ -722,7 +735,7 @@ class Google_Service_Gmail extends Google_Service
), ),
), ),
),'delete' => array( ),'delete' => array(
'path' => '{userId}/settings/delegates/{delegateEmail}', 'path' => 'gmail/v1/users/{userId}/settings/delegates/{delegateEmail}',
'httpMethod' => 'DELETE', 'httpMethod' => 'DELETE',
'parameters' => array( 'parameters' => array(
'userId' => array( 'userId' => array(
@ -737,7 +750,7 @@ class Google_Service_Gmail extends Google_Service
), ),
), ),
),'get' => array( ),'get' => array(
'path' => '{userId}/settings/delegates/{delegateEmail}', 'path' => 'gmail/v1/users/{userId}/settings/delegates/{delegateEmail}',
'httpMethod' => 'GET', 'httpMethod' => 'GET',
'parameters' => array( 'parameters' => array(
'userId' => array( 'userId' => array(
@ -752,7 +765,7 @@ class Google_Service_Gmail extends Google_Service
), ),
), ),
),'list' => array( ),'list' => array(
'path' => '{userId}/settings/delegates', 'path' => 'gmail/v1/users/{userId}/settings/delegates',
'httpMethod' => 'GET', 'httpMethod' => 'GET',
'parameters' => array( 'parameters' => array(
'userId' => array( 'userId' => array(
@ -772,7 +785,7 @@ class Google_Service_Gmail extends Google_Service
array( array(
'methods' => array( 'methods' => array(
'create' => array( 'create' => array(
'path' => '{userId}/settings/filters', 'path' => 'gmail/v1/users/{userId}/settings/filters',
'httpMethod' => 'POST', 'httpMethod' => 'POST',
'parameters' => array( 'parameters' => array(
'userId' => array( 'userId' => array(
@ -782,7 +795,7 @@ class Google_Service_Gmail extends Google_Service
), ),
), ),
),'delete' => array( ),'delete' => array(
'path' => '{userId}/settings/filters/{id}', 'path' => 'gmail/v1/users/{userId}/settings/filters/{id}',
'httpMethod' => 'DELETE', 'httpMethod' => 'DELETE',
'parameters' => array( 'parameters' => array(
'userId' => array( 'userId' => array(
@ -797,7 +810,7 @@ class Google_Service_Gmail extends Google_Service
), ),
), ),
),'get' => array( ),'get' => array(
'path' => '{userId}/settings/filters/{id}', 'path' => 'gmail/v1/users/{userId}/settings/filters/{id}',
'httpMethod' => 'GET', 'httpMethod' => 'GET',
'parameters' => array( 'parameters' => array(
'userId' => array( 'userId' => array(
@ -812,7 +825,7 @@ class Google_Service_Gmail extends Google_Service
), ),
), ),
),'list' => array( ),'list' => array(
'path' => '{userId}/settings/filters', 'path' => 'gmail/v1/users/{userId}/settings/filters',
'httpMethod' => 'GET', 'httpMethod' => 'GET',
'parameters' => array( 'parameters' => array(
'userId' => array( 'userId' => array(
@ -832,7 +845,7 @@ class Google_Service_Gmail extends Google_Service
array( array(
'methods' => array( 'methods' => array(
'create' => array( 'create' => array(
'path' => '{userId}/settings/forwardingAddresses', 'path' => 'gmail/v1/users/{userId}/settings/forwardingAddresses',
'httpMethod' => 'POST', 'httpMethod' => 'POST',
'parameters' => array( 'parameters' => array(
'userId' => array( 'userId' => array(
@ -842,7 +855,7 @@ class Google_Service_Gmail extends Google_Service
), ),
), ),
),'delete' => array( ),'delete' => array(
'path' => '{userId}/settings/forwardingAddresses/{forwardingEmail}', 'path' => 'gmail/v1/users/{userId}/settings/forwardingAddresses/{forwardingEmail}',
'httpMethod' => 'DELETE', 'httpMethod' => 'DELETE',
'parameters' => array( 'parameters' => array(
'userId' => array( 'userId' => array(
@ -857,7 +870,7 @@ class Google_Service_Gmail extends Google_Service
), ),
), ),
),'get' => array( ),'get' => array(
'path' => '{userId}/settings/forwardingAddresses/{forwardingEmail}', 'path' => 'gmail/v1/users/{userId}/settings/forwardingAddresses/{forwardingEmail}',
'httpMethod' => 'GET', 'httpMethod' => 'GET',
'parameters' => array( 'parameters' => array(
'userId' => array( 'userId' => array(
@ -872,7 +885,7 @@ class Google_Service_Gmail extends Google_Service
), ),
), ),
),'list' => array( ),'list' => array(
'path' => '{userId}/settings/forwardingAddresses', 'path' => 'gmail/v1/users/{userId}/settings/forwardingAddresses',
'httpMethod' => 'GET', 'httpMethod' => 'GET',
'parameters' => array( 'parameters' => array(
'userId' => array( 'userId' => array(
@ -892,7 +905,7 @@ class Google_Service_Gmail extends Google_Service
array( array(
'methods' => array( 'methods' => array(
'create' => array( 'create' => array(
'path' => '{userId}/settings/sendAs', 'path' => 'gmail/v1/users/{userId}/settings/sendAs',
'httpMethod' => 'POST', 'httpMethod' => 'POST',
'parameters' => array( 'parameters' => array(
'userId' => array( 'userId' => array(
@ -902,7 +915,7 @@ class Google_Service_Gmail extends Google_Service
), ),
), ),
),'delete' => array( ),'delete' => array(
'path' => '{userId}/settings/sendAs/{sendAsEmail}', 'path' => 'gmail/v1/users/{userId}/settings/sendAs/{sendAsEmail}',
'httpMethod' => 'DELETE', 'httpMethod' => 'DELETE',
'parameters' => array( 'parameters' => array(
'userId' => array( 'userId' => array(
@ -917,7 +930,7 @@ class Google_Service_Gmail extends Google_Service
), ),
), ),
),'get' => array( ),'get' => array(
'path' => '{userId}/settings/sendAs/{sendAsEmail}', 'path' => 'gmail/v1/users/{userId}/settings/sendAs/{sendAsEmail}',
'httpMethod' => 'GET', 'httpMethod' => 'GET',
'parameters' => array( 'parameters' => array(
'userId' => array( 'userId' => array(
@ -932,7 +945,7 @@ class Google_Service_Gmail extends Google_Service
), ),
), ),
),'list' => array( ),'list' => array(
'path' => '{userId}/settings/sendAs', 'path' => 'gmail/v1/users/{userId}/settings/sendAs',
'httpMethod' => 'GET', 'httpMethod' => 'GET',
'parameters' => array( 'parameters' => array(
'userId' => array( 'userId' => array(
@ -942,7 +955,7 @@ class Google_Service_Gmail extends Google_Service
), ),
), ),
),'patch' => array( ),'patch' => array(
'path' => '{userId}/settings/sendAs/{sendAsEmail}', 'path' => 'gmail/v1/users/{userId}/settings/sendAs/{sendAsEmail}',
'httpMethod' => 'PATCH', 'httpMethod' => 'PATCH',
'parameters' => array( 'parameters' => array(
'userId' => array( 'userId' => array(
@ -957,7 +970,7 @@ class Google_Service_Gmail extends Google_Service
), ),
), ),
),'update' => array( ),'update' => array(
'path' => '{userId}/settings/sendAs/{sendAsEmail}', 'path' => 'gmail/v1/users/{userId}/settings/sendAs/{sendAsEmail}',
'httpMethod' => 'PUT', 'httpMethod' => 'PUT',
'parameters' => array( 'parameters' => array(
'userId' => array( 'userId' => array(
@ -972,7 +985,7 @@ class Google_Service_Gmail extends Google_Service
), ),
), ),
),'verify' => array( ),'verify' => array(
'path' => '{userId}/settings/sendAs/{sendAsEmail}/verify', 'path' => 'gmail/v1/users/{userId}/settings/sendAs/{sendAsEmail}/verify',
'httpMethod' => 'POST', 'httpMethod' => 'POST',
'parameters' => array( 'parameters' => array(
'userId' => array( 'userId' => array(
@ -997,7 +1010,7 @@ class Google_Service_Gmail extends Google_Service
array( array(
'methods' => array( 'methods' => array(
'delete' => array( 'delete' => array(
'path' => '{userId}/settings/sendAs/{sendAsEmail}/smimeInfo/{id}', 'path' => 'gmail/v1/users/{userId}/settings/sendAs/{sendAsEmail}/smimeInfo/{id}',
'httpMethod' => 'DELETE', 'httpMethod' => 'DELETE',
'parameters' => array( 'parameters' => array(
'userId' => array( 'userId' => array(
@ -1017,7 +1030,7 @@ class Google_Service_Gmail extends Google_Service
), ),
), ),
),'get' => array( ),'get' => array(
'path' => '{userId}/settings/sendAs/{sendAsEmail}/smimeInfo/{id}', 'path' => 'gmail/v1/users/{userId}/settings/sendAs/{sendAsEmail}/smimeInfo/{id}',
'httpMethod' => 'GET', 'httpMethod' => 'GET',
'parameters' => array( 'parameters' => array(
'userId' => array( 'userId' => array(
@ -1037,7 +1050,7 @@ class Google_Service_Gmail extends Google_Service
), ),
), ),
),'insert' => array( ),'insert' => array(
'path' => '{userId}/settings/sendAs/{sendAsEmail}/smimeInfo', 'path' => 'gmail/v1/users/{userId}/settings/sendAs/{sendAsEmail}/smimeInfo',
'httpMethod' => 'POST', 'httpMethod' => 'POST',
'parameters' => array( 'parameters' => array(
'userId' => array( 'userId' => array(
@ -1052,7 +1065,7 @@ class Google_Service_Gmail extends Google_Service
), ),
), ),
),'list' => array( ),'list' => array(
'path' => '{userId}/settings/sendAs/{sendAsEmail}/smimeInfo', 'path' => 'gmail/v1/users/{userId}/settings/sendAs/{sendAsEmail}/smimeInfo',
'httpMethod' => 'GET', 'httpMethod' => 'GET',
'parameters' => array( 'parameters' => array(
'userId' => array( 'userId' => array(
@ -1067,7 +1080,7 @@ class Google_Service_Gmail extends Google_Service
), ),
), ),
),'setDefault' => array( ),'setDefault' => array(
'path' => '{userId}/settings/sendAs/{sendAsEmail}/smimeInfo/{id}/setDefault', 'path' => 'gmail/v1/users/{userId}/settings/sendAs/{sendAsEmail}/smimeInfo/{id}/setDefault',
'httpMethod' => 'POST', 'httpMethod' => 'POST',
'parameters' => array( 'parameters' => array(
'userId' => array( 'userId' => array(
@ -1097,7 +1110,7 @@ class Google_Service_Gmail extends Google_Service
array( array(
'methods' => array( 'methods' => array(
'delete' => array( 'delete' => array(
'path' => '{userId}/threads/{id}', 'path' => 'gmail/v1/users/{userId}/threads/{id}',
'httpMethod' => 'DELETE', 'httpMethod' => 'DELETE',
'parameters' => array( 'parameters' => array(
'userId' => array( 'userId' => array(
@ -1112,7 +1125,7 @@ class Google_Service_Gmail extends Google_Service
), ),
), ),
),'get' => array( ),'get' => array(
'path' => '{userId}/threads/{id}', 'path' => 'gmail/v1/users/{userId}/threads/{id}',
'httpMethod' => 'GET', 'httpMethod' => 'GET',
'parameters' => array( 'parameters' => array(
'userId' => array( 'userId' => array(
@ -1125,18 +1138,18 @@ class Google_Service_Gmail extends Google_Service
'type' => 'string', 'type' => 'string',
'required' => true, 'required' => true,
), ),
'format' => array(
'location' => 'query',
'type' => 'string',
),
'metadataHeaders' => array( 'metadataHeaders' => array(
'location' => 'query', 'location' => 'query',
'type' => 'string', 'type' => 'string',
'repeated' => true, 'repeated' => true,
), ),
'format' => array(
'location' => 'query',
'type' => 'string',
),
), ),
),'list' => array( ),'list' => array(
'path' => '{userId}/threads', 'path' => 'gmail/v1/users/{userId}/threads',
'httpMethod' => 'GET', 'httpMethod' => 'GET',
'parameters' => array( 'parameters' => array(
'userId' => array( 'userId' => array(
@ -1144,30 +1157,30 @@ class Google_Service_Gmail extends Google_Service
'type' => 'string', 'type' => 'string',
'required' => true, 'required' => true,
), ),
'includeSpamTrash' => array( 'pageToken' => array(
'location' => 'query', 'location' => 'query',
'type' => 'boolean', 'type' => 'string',
), ),
'labelIds' => array( 'labelIds' => array(
'location' => 'query', 'location' => 'query',
'type' => 'string', 'type' => 'string',
'repeated' => true, 'repeated' => true,
), ),
'maxResults' => array(
'location' => 'query',
'type' => 'integer',
),
'pageToken' => array(
'location' => 'query',
'type' => 'string',
),
'q' => array( 'q' => array(
'location' => 'query', 'location' => 'query',
'type' => 'string', 'type' => 'string',
), ),
'maxResults' => array(
'location' => 'query',
'type' => 'integer',
),
'includeSpamTrash' => array(
'location' => 'query',
'type' => 'boolean',
),
), ),
),'modify' => array( ),'modify' => array(
'path' => '{userId}/threads/{id}/modify', 'path' => 'gmail/v1/users/{userId}/threads/{id}/modify',
'httpMethod' => 'POST', 'httpMethod' => 'POST',
'parameters' => array( 'parameters' => array(
'userId' => array( 'userId' => array(
@ -1182,7 +1195,7 @@ class Google_Service_Gmail extends Google_Service
), ),
), ),
),'trash' => array( ),'trash' => array(
'path' => '{userId}/threads/{id}/trash', 'path' => 'gmail/v1/users/{userId}/threads/{id}/trash',
'httpMethod' => 'POST', 'httpMethod' => 'POST',
'parameters' => array( 'parameters' => array(
'userId' => array( 'userId' => array(
@ -1197,7 +1210,7 @@ class Google_Service_Gmail extends Google_Service
), ),
), ),
),'untrash' => array( ),'untrash' => array(
'path' => '{userId}/threads/{id}/untrash', 'path' => 'gmail/v1/users/{userId}/threads/{id}/untrash',
'httpMethod' => 'POST', 'httpMethod' => 'POST',
'parameters' => array( 'parameters' => array(
'userId' => array( 'userId' => array(

View File

@ -81,12 +81,12 @@ class Google_Service_Gmail_Resource_UsersDrafts extends Google_Service_Resource
* *
* @opt_param bool includeSpamTrash Include drafts from SPAM and TRASH in the * @opt_param bool includeSpamTrash Include drafts from SPAM and TRASH in the
* results. * results.
* @opt_param string maxResults Maximum number of drafts to return.
* @opt_param string pageToken Page token to retrieve a specific page of results * @opt_param string pageToken Page token to retrieve a specific page of results
* in the list. * in the list.
* @opt_param string q Only return draft messages matching the specified query. * @opt_param string q Only return draft messages matching the specified query.
* Supports the same query format as the Gmail search box. For example, * Supports the same query format as the Gmail search box. For example,
* "from:someuser@example.com rfc822msgid: is:unread". * "from:someuser@example.com rfc822msgid: is:unread".
* @opt_param string maxResults Maximum number of drafts to return.
* @return Google_Service_Gmail_ListDraftsResponse * @return Google_Service_Gmail_ListDraftsResponse
*/ */
public function listUsersDrafts($userId, $optParams = array()) public function listUsersDrafts($userId, $optParams = array())

View File

@ -34,11 +34,11 @@ class Google_Service_Gmail_Resource_UsersHistory extends Google_Service_Resource
* used to indicate the authenticated user. * used to indicate the authenticated user.
* @param array $optParams Optional parameters. * @param array $optParams Optional parameters.
* *
* @opt_param string historyTypes History types to be returned by the function
* @opt_param string labelId Only return messages with a label matching the ID.
* @opt_param string maxResults The maximum number of history records to return.
* @opt_param string pageToken Page token to retrieve a specific page of results * @opt_param string pageToken Page token to retrieve a specific page of results
* in the list. * in the list.
* @opt_param string labelId Only return messages with a label matching the ID.
* @opt_param string maxResults The maximum number of history records to return.
* @opt_param string historyTypes History types to be returned by the function
* @opt_param string startHistoryId Required. Returns history records after the * @opt_param string startHistoryId Required. Returns history records after the
* specified startHistoryId. The supplied startHistoryId should be obtained from * specified startHistoryId. The supplied startHistoryId should be obtained from
* the historyId of a message, thread, or previous list response. History IDs * the historyId of a message, thread, or previous list response. History IDs
@ -46,7 +46,7 @@ class Google_Service_Gmail_Resource_UsersHistory extends Google_Service_Resource
* valid IDs. Supplying an invalid or out of date startHistoryId typically * valid IDs. Supplying an invalid or out of date startHistoryId typically
* returns an HTTP 404 error code. A historyId is typically valid for at least a * returns an HTTP 404 error code. A historyId is typically valid for at least a
* week, but in some rare circumstances may be valid for only a few hours. If * week, but in some rare circumstances may be valid for only a few hours. If
* you receive an HTTP 404 error response, your application should perform a * you receive an HTTP 404 error response, your application should perform a
* full sync. If you receive no nextPageToken in the response, there are no * full sync. If you receive no nextPageToken in the response, there are no
* updates to retrieve and you can store the returned historyId for a future * updates to retrieve and you can store the returned historyId for a future
* request. * request.

View File

@ -85,8 +85,7 @@ class Google_Service_Gmail_Resource_UsersLabels extends Google_Service_Resource
return $this->call('list', array($params), "Google_Service_Gmail_ListLabelsResponse"); return $this->call('list', array($params), "Google_Service_Gmail_ListLabelsResponse");
} }
/** /**
* Updates the specified label. This method supports patch semantics. * Patch the specified label. (labels.patch)
* (labels.patch)
* *
* @param string $userId The user's email address. The special value me can be * @param string $userId The user's email address. The special value me can be
* used to indicate the authenticated user. * used to indicate the authenticated user.

View File

@ -26,7 +26,7 @@
class Google_Service_Gmail_Resource_UsersMessages extends Google_Service_Resource class Google_Service_Gmail_Resource_UsersMessages extends Google_Service_Resource
{ {
/** /**
* Deletes many messages by message ID. Provides no guarantees that messages * Deletes many messages by message ID. Provides no guarantees that messages
* were not already deleted or even existed at all. (messages.batchDelete) * were not already deleted or even existed at all. (messages.batchDelete)
* *
* @param string $userId The user's email address. The special value me can be * @param string $userId The user's email address. The special value me can be
@ -56,7 +56,7 @@ class Google_Service_Gmail_Resource_UsersMessages extends Google_Service_Resourc
} }
/** /**
* Immediately and permanently deletes the specified message. This operation * Immediately and permanently deletes the specified message. This operation
* cannot be undone. Prefer messages.trash instead. (messages.delete) * cannot be undone. Prefer messages.trash instead. (messages.delete)
* *
* @param string $userId The user's email address. The special value me can be * @param string $userId The user's email address. The special value me can be
* used to indicate the authenticated user. * used to indicate the authenticated user.
@ -77,9 +77,9 @@ class Google_Service_Gmail_Resource_UsersMessages extends Google_Service_Resourc
* @param string $id The ID of the message to retrieve. * @param string $id The ID of the message to retrieve.
* @param array $optParams Optional parameters. * @param array $optParams Optional parameters.
* *
* @opt_param string format The format to return the message in.
* @opt_param string metadataHeaders When given and format is METADATA, only * @opt_param string metadataHeaders When given and format is METADATA, only
* include headers specified. * include headers specified.
* @opt_param string format The format to return the message in.
* @return Google_Service_Gmail_Message * @return Google_Service_Gmail_Message
*/ */
public function get($userId, $id, $optParams = array()) public function get($userId, $id, $optParams = array())
@ -98,15 +98,15 @@ class Google_Service_Gmail_Resource_UsersMessages extends Google_Service_Resourc
* @param Google_Service_Gmail_Message $postBody * @param Google_Service_Gmail_Message $postBody
* @param array $optParams Optional parameters. * @param array $optParams Optional parameters.
* *
* @opt_param bool deleted Mark the email as permanently deleted (not TRASH) and * @opt_param bool processForCalendar Process calendar invites in the email and
* only visible in Google Vault to a Vault administrator. Only used for G Suite * add any extracted meetings to the Google Calendar for this user.
* accounts.
* @opt_param string internalDateSource Source for Gmail's internal date of the * @opt_param string internalDateSource Source for Gmail's internal date of the
* message. * message.
* @opt_param bool neverMarkSpam Ignore the Gmail spam classifier decision and * @opt_param bool neverMarkSpam Ignore the Gmail spam classifier decision and
* never mark this email as SPAM in the mailbox. * never mark this email as SPAM in the mailbox.
* @opt_param bool processForCalendar Process calendar invites in the email and * @opt_param bool deleted Mark the email as permanently deleted (not TRASH) and
* add any extracted meetings to the Google Calendar for this user. * only visible in Google Vault to a Vault administrator. Only used for G Suite
* accounts.
* @return Google_Service_Gmail_Message * @return Google_Service_Gmail_Message
*/ */
public function import($userId, Google_Service_Gmail_Message $postBody, $optParams = array()) public function import($userId, Google_Service_Gmail_Message $postBody, $optParams = array())
@ -125,11 +125,11 @@ class Google_Service_Gmail_Resource_UsersMessages extends Google_Service_Resourc
* @param Google_Service_Gmail_Message $postBody * @param Google_Service_Gmail_Message $postBody
* @param array $optParams Optional parameters. * @param array $optParams Optional parameters.
* *
* @opt_param string internalDateSource Source for Gmail's internal date of the
* message.
* @opt_param bool deleted Mark the email as permanently deleted (not TRASH) and * @opt_param bool deleted Mark the email as permanently deleted (not TRASH) and
* only visible in Google Vault to a Vault administrator. Only used for G Suite * only visible in Google Vault to a Vault administrator. Only used for G Suite
* accounts. * accounts.
* @opt_param string internalDateSource Source for Gmail's internal date of the
* message.
* @return Google_Service_Gmail_Message * @return Google_Service_Gmail_Message
*/ */
public function insert($userId, Google_Service_Gmail_Message $postBody, $optParams = array()) public function insert($userId, Google_Service_Gmail_Message $postBody, $optParams = array())
@ -147,15 +147,16 @@ class Google_Service_Gmail_Resource_UsersMessages extends Google_Service_Resourc
* *
* @opt_param bool includeSpamTrash Include messages from SPAM and TRASH in the * @opt_param bool includeSpamTrash Include messages from SPAM and TRASH in the
* results. * results.
* @opt_param string labelIds Only return messages with labels that match all of
* the specified label IDs.
* @opt_param string maxResults Maximum number of messages to return.
* @opt_param string pageToken Page token to retrieve a specific page of results * @opt_param string pageToken Page token to retrieve a specific page of results
* in the list. * in the list.
* @opt_param string labelIds Only return messages with labels that match all of
* the specified label IDs.
* @opt_param string q Only return messages matching the specified query. * @opt_param string q Only return messages matching the specified query.
* Supports the same query format as the Gmail search box. For example, * Supports the same query format as the Gmail search box. For example,
* "from:someuser@example.com rfc822msgid: is:unread". Parameter cannot be used * "from:someuser@example.com rfc822msgid:somemsgid@example.com is:unread".
* when accessing the api using the gmail.metadata scope. * Parameter cannot be used when accessing the api using the gmail.metadata
* scope.
* @opt_param string maxResults Maximum number of messages to return.
* @return Google_Service_Gmail_ListMessagesResponse * @return Google_Service_Gmail_ListMessagesResponse
*/ */
public function listUsersMessages($userId, $optParams = array()) public function listUsersMessages($userId, $optParams = array())

View File

@ -29,7 +29,7 @@ class Google_Service_Gmail_Resource_UsersSettings extends Google_Service_Resourc
* Gets the auto-forwarding setting for the specified account. * Gets the auto-forwarding setting for the specified account.
* (settings.getAutoForwarding) * (settings.getAutoForwarding)
* *
* @param string $userId User's email address. The special value "me" can be * @param string $userId User's email address. The special value "me" can be
* used to indicate the authenticated user. * used to indicate the authenticated user.
* @param array $optParams Optional parameters. * @param array $optParams Optional parameters.
* @return Google_Service_Gmail_AutoForwarding * @return Google_Service_Gmail_AutoForwarding
@ -43,7 +43,7 @@ class Google_Service_Gmail_Resource_UsersSettings extends Google_Service_Resourc
/** /**
* Gets IMAP settings. (settings.getImap) * Gets IMAP settings. (settings.getImap)
* *
* @param string $userId User's email address. The special value "me" can be * @param string $userId User's email address. The special value "me" can be
* used to indicate the authenticated user. * used to indicate the authenticated user.
* @param array $optParams Optional parameters. * @param array $optParams Optional parameters.
* @return Google_Service_Gmail_ImapSettings * @return Google_Service_Gmail_ImapSettings
@ -57,7 +57,7 @@ class Google_Service_Gmail_Resource_UsersSettings extends Google_Service_Resourc
/** /**
* Gets language settings. (settings.getLanguage) * Gets language settings. (settings.getLanguage)
* *
* @param string $userId User's email address. The special value "me" can be * @param string $userId User's email address. The special value "me" can be
* used to indicate the authenticated user. * used to indicate the authenticated user.
* @param array $optParams Optional parameters. * @param array $optParams Optional parameters.
* @return Google_Service_Gmail_LanguageSettings * @return Google_Service_Gmail_LanguageSettings
@ -71,7 +71,7 @@ class Google_Service_Gmail_Resource_UsersSettings extends Google_Service_Resourc
/** /**
* Gets POP settings. (settings.getPop) * Gets POP settings. (settings.getPop)
* *
* @param string $userId User's email address. The special value "me" can be * @param string $userId User's email address. The special value "me" can be
* used to indicate the authenticated user. * used to indicate the authenticated user.
* @param array $optParams Optional parameters. * @param array $optParams Optional parameters.
* @return Google_Service_Gmail_PopSettings * @return Google_Service_Gmail_PopSettings
@ -85,7 +85,7 @@ class Google_Service_Gmail_Resource_UsersSettings extends Google_Service_Resourc
/** /**
* Gets vacation responder settings. (settings.getVacation) * Gets vacation responder settings. (settings.getVacation)
* *
* @param string $userId User's email address. The special value "me" can be * @param string $userId User's email address. The special value "me" can be
* used to indicate the authenticated user. * used to indicate the authenticated user.
* @param array $optParams Optional parameters. * @param array $optParams Optional parameters.
* @return Google_Service_Gmail_VacationSettings * @return Google_Service_Gmail_VacationSettings
@ -97,13 +97,13 @@ class Google_Service_Gmail_Resource_UsersSettings extends Google_Service_Resourc
return $this->call('getVacation', array($params), "Google_Service_Gmail_VacationSettings"); return $this->call('getVacation', array($params), "Google_Service_Gmail_VacationSettings");
} }
/** /**
* Updates the auto-forwarding setting for the specified account. A verified * Updates the auto-forwarding setting for the specified account. A verified
* forwarding address must be specified when auto-forwarding is enabled. * forwarding address must be specified when auto-forwarding is enabled.
* *
* This method is only available to service account clients that have been * This method is only available to service account clients that have been
* delegated domain-wide authority. (settings.updateAutoForwarding) * delegated domain-wide authority. (settings.updateAutoForwarding)
* *
* @param string $userId User's email address. The special value "me" can be * @param string $userId User's email address. The special value "me" can be
* used to indicate the authenticated user. * used to indicate the authenticated user.
* @param Google_Service_Gmail_AutoForwarding $postBody * @param Google_Service_Gmail_AutoForwarding $postBody
* @param array $optParams Optional parameters. * @param array $optParams Optional parameters.
@ -118,7 +118,7 @@ class Google_Service_Gmail_Resource_UsersSettings extends Google_Service_Resourc
/** /**
* Updates IMAP settings. (settings.updateImap) * Updates IMAP settings. (settings.updateImap)
* *
* @param string $userId User's email address. The special value "me" can be * @param string $userId User's email address. The special value "me" can be
* used to indicate the authenticated user. * used to indicate the authenticated user.
* @param Google_Service_Gmail_ImapSettings $postBody * @param Google_Service_Gmail_ImapSettings $postBody
* @param array $optParams Optional parameters. * @param array $optParams Optional parameters.
@ -139,7 +139,7 @@ class Google_Service_Gmail_Resource_UsersSettings extends Google_Service_Resourc
* Gmail but have a close variant that is, and so the variant may be chosen and * Gmail but have a close variant that is, and so the variant may be chosen and
* saved instead. (settings.updateLanguage) * saved instead. (settings.updateLanguage)
* *
* @param string $userId User's email address. The special value "me" can be * @param string $userId User's email address. The special value "me" can be
* used to indicate the authenticated user. * used to indicate the authenticated user.
* @param Google_Service_Gmail_LanguageSettings $postBody * @param Google_Service_Gmail_LanguageSettings $postBody
* @param array $optParams Optional parameters. * @param array $optParams Optional parameters.
@ -154,7 +154,7 @@ class Google_Service_Gmail_Resource_UsersSettings extends Google_Service_Resourc
/** /**
* Updates POP settings. (settings.updatePop) * Updates POP settings. (settings.updatePop)
* *
* @param string $userId User's email address. The special value "me" can be * @param string $userId User's email address. The special value "me" can be
* used to indicate the authenticated user. * used to indicate the authenticated user.
* @param Google_Service_Gmail_PopSettings $postBody * @param Google_Service_Gmail_PopSettings $postBody
* @param array $optParams Optional parameters. * @param array $optParams Optional parameters.
@ -169,7 +169,7 @@ class Google_Service_Gmail_Resource_UsersSettings extends Google_Service_Resourc
/** /**
* Updates vacation responder settings. (settings.updateVacation) * Updates vacation responder settings. (settings.updateVacation)
* *
* @param string $userId User's email address. The special value "me" can be * @param string $userId User's email address. The special value "me" can be
* used to indicate the authenticated user. * used to indicate the authenticated user.
* @param Google_Service_Gmail_VacationSettings $postBody * @param Google_Service_Gmail_VacationSettings $postBody
* @param array $optParams Optional parameters. * @param array $optParams Optional parameters.

View File

@ -27,10 +27,10 @@ class Google_Service_Gmail_Resource_UsersSettingsDelegates extends Google_Servic
{ {
/** /**
* Adds a delegate with its verification status set directly to accepted, * Adds a delegate with its verification status set directly to accepted,
* without sending any verification email. The delegate user must be a member of * without sending any verification email. The delegate user must be a member
* the same G Suite organization as the delegator user. * of the same G Suite organization as the delegator user.
* *
* Gmail imposes limtations on the number of delegates and delegators each user * Gmail imposes limitations on the number of delegates and delegators each user
* in a G Suite organization can have. These limits depend on your organization, * in a G Suite organization can have. These limits depend on your organization,
* but in general each user can have up to 25 delegates and up to 10 delegators. * but in general each user can have up to 25 delegates and up to 10 delegators.
* *
@ -43,7 +43,7 @@ class Google_Service_Gmail_Resource_UsersSettingsDelegates extends Google_Servic
* This method is only available to service account clients that have been * This method is only available to service account clients that have been
* delegated domain-wide authority. (delegates.create) * delegated domain-wide authority. (delegates.create)
* *
* @param string $userId User's email address. The special value "me" can be * @param string $userId User's email address. The special value "me" can be
* used to indicate the authenticated user. * used to indicate the authenticated user.
* @param Google_Service_Gmail_Delegate $postBody * @param Google_Service_Gmail_Delegate $postBody
* @param array $optParams Optional parameters. * @param array $optParams Optional parameters.
@ -65,7 +65,7 @@ class Google_Service_Gmail_Resource_UsersSettingsDelegates extends Google_Servic
* This method is only available to service account clients that have been * This method is only available to service account clients that have been
* delegated domain-wide authority. (delegates.delete) * delegated domain-wide authority. (delegates.delete)
* *
* @param string $userId User's email address. The special value "me" can be * @param string $userId User's email address. The special value "me" can be
* used to indicate the authenticated user. * used to indicate the authenticated user.
* @param string $delegateEmail The email address of the user to be removed as a * @param string $delegateEmail The email address of the user to be removed as a
* delegate. * delegate.
@ -86,7 +86,7 @@ class Google_Service_Gmail_Resource_UsersSettingsDelegates extends Google_Servic
* This method is only available to service account clients that have been * This method is only available to service account clients that have been
* delegated domain-wide authority. (delegates.get) * delegated domain-wide authority. (delegates.get)
* *
* @param string $userId User's email address. The special value "me" can be * @param string $userId User's email address. The special value "me" can be
* used to indicate the authenticated user. * used to indicate the authenticated user.
* @param string $delegateEmail The email address of the user whose delegate * @param string $delegateEmail The email address of the user whose delegate
* relationship is to be retrieved. * relationship is to be retrieved.
@ -105,7 +105,7 @@ class Google_Service_Gmail_Resource_UsersSettingsDelegates extends Google_Servic
* This method is only available to service account clients that have been * This method is only available to service account clients that have been
* delegated domain-wide authority. (delegates.listUsersSettingsDelegates) * delegated domain-wide authority. (delegates.listUsersSettingsDelegates)
* *
* @param string $userId User's email address. The special value "me" can be * @param string $userId User's email address. The special value "me" can be
* used to indicate the authenticated user. * used to indicate the authenticated user.
* @param array $optParams Optional parameters. * @param array $optParams Optional parameters.
* @return Google_Service_Gmail_ListDelegatesResponse * @return Google_Service_Gmail_ListDelegatesResponse

View File

@ -26,7 +26,7 @@
class Google_Service_Gmail_Resource_UsersSettingsForwardingAddresses extends Google_Service_Resource class Google_Service_Gmail_Resource_UsersSettingsForwardingAddresses extends Google_Service_Resource
{ {
/** /**
* Creates a forwarding address. If ownership verification is required, a * Creates a forwarding address. If ownership verification is required, a
* message will be sent to the recipient and the resource's verification status * message will be sent to the recipient and the resource's verification status
* will be set to pending; otherwise, the resource will be created with * will be set to pending; otherwise, the resource will be created with
* verification status set to accepted. * verification status set to accepted.
@ -34,7 +34,7 @@ class Google_Service_Gmail_Resource_UsersSettingsForwardingAddresses extends Goo
* This method is only available to service account clients that have been * This method is only available to service account clients that have been
* delegated domain-wide authority. (forwardingAddresses.create) * delegated domain-wide authority. (forwardingAddresses.create)
* *
* @param string $userId User's email address. The special value "me" can be * @param string $userId User's email address. The special value "me" can be
* used to indicate the authenticated user. * used to indicate the authenticated user.
* @param Google_Service_Gmail_ForwardingAddress $postBody * @param Google_Service_Gmail_ForwardingAddress $postBody
* @param array $optParams Optional parameters. * @param array $optParams Optional parameters.
@ -53,7 +53,7 @@ class Google_Service_Gmail_Resource_UsersSettingsForwardingAddresses extends Goo
* This method is only available to service account clients that have been * This method is only available to service account clients that have been
* delegated domain-wide authority. (forwardingAddresses.delete) * delegated domain-wide authority. (forwardingAddresses.delete)
* *
* @param string $userId User's email address. The special value "me" can be * @param string $userId User's email address. The special value "me" can be
* used to indicate the authenticated user. * used to indicate the authenticated user.
* @param string $forwardingEmail The forwarding address to be deleted. * @param string $forwardingEmail The forwarding address to be deleted.
* @param array $optParams Optional parameters. * @param array $optParams Optional parameters.
@ -67,7 +67,7 @@ class Google_Service_Gmail_Resource_UsersSettingsForwardingAddresses extends Goo
/** /**
* Gets the specified forwarding address. (forwardingAddresses.get) * Gets the specified forwarding address. (forwardingAddresses.get)
* *
* @param string $userId User's email address. The special value "me" can be * @param string $userId User's email address. The special value "me" can be
* used to indicate the authenticated user. * used to indicate the authenticated user.
* @param string $forwardingEmail The forwarding address to be retrieved. * @param string $forwardingEmail The forwarding address to be retrieved.
* @param array $optParams Optional parameters. * @param array $optParams Optional parameters.
@ -83,7 +83,7 @@ class Google_Service_Gmail_Resource_UsersSettingsForwardingAddresses extends Goo
* Lists the forwarding addresses for the specified account. * Lists the forwarding addresses for the specified account.
* (forwardingAddresses.listUsersSettingsForwardingAddresses) * (forwardingAddresses.listUsersSettingsForwardingAddresses)
* *
* @param string $userId User's email address. The special value "me" can be * @param string $userId User's email address. The special value "me" can be
* used to indicate the authenticated user. * used to indicate the authenticated user.
* @param array $optParams Optional parameters. * @param array $optParams Optional parameters.
* @return Google_Service_Gmail_ListForwardingAddressesResponse * @return Google_Service_Gmail_ListForwardingAddressesResponse

View File

@ -26,18 +26,18 @@
class Google_Service_Gmail_Resource_UsersSettingsSendAs extends Google_Service_Resource class Google_Service_Gmail_Resource_UsersSettingsSendAs extends Google_Service_Resource
{ {
/** /**
* Creates a custom "from" send-as alias. If an SMTP MSA is specified, Gmail * Creates a custom "from" send-as alias. If an SMTP MSA is specified, Gmail
* will attempt to connect to the SMTP service to validate the configuration * will attempt to connect to the SMTP service to validate the configuration
* before creating the alias. If ownership verification is required for the * before creating the alias. If ownership verification is required for the
* alias, a message will be sent to the email address and the resource's * alias, a message will be sent to the email address and the resource's
* verification status will be set to pending; otherwise, the resource will be * verification status will be set to pending; otherwise, the resource will be
* created with verification status set to accepted. If a signature is provided, * created with verification status set to accepted. If a signature is
* Gmail will sanitize the HTML before saving it with the alias. * provided, Gmail will sanitize the HTML before saving it with the alias.
* *
* This method is only available to service account clients that have been * This method is only available to service account clients that have been
* delegated domain-wide authority. (sendAs.create) * delegated domain-wide authority. (sendAs.create)
* *
* @param string $userId User's email address. The special value "me" can be * @param string $userId User's email address. The special value "me" can be
* used to indicate the authenticated user. * used to indicate the authenticated user.
* @param Google_Service_Gmail_SendAs $postBody * @param Google_Service_Gmail_SendAs $postBody
* @param array $optParams Optional parameters. * @param array $optParams Optional parameters.
@ -50,13 +50,13 @@ class Google_Service_Gmail_Resource_UsersSettingsSendAs extends Google_Service_R
return $this->call('create', array($params), "Google_Service_Gmail_SendAs"); return $this->call('create', array($params), "Google_Service_Gmail_SendAs");
} }
/** /**
* Deletes the specified send-as alias. Revokes any verification that may have * Deletes the specified send-as alias. Revokes any verification that may have
* been required for using it. * been required for using it.
* *
* This method is only available to service account clients that have been * This method is only available to service account clients that have been
* delegated domain-wide authority. (sendAs.delete) * delegated domain-wide authority. (sendAs.delete)
* *
* @param string $userId User's email address. The special value "me" can be * @param string $userId User's email address. The special value "me" can be
* used to indicate the authenticated user. * used to indicate the authenticated user.
* @param string $sendAsEmail The send-as alias to be deleted. * @param string $sendAsEmail The send-as alias to be deleted.
* @param array $optParams Optional parameters. * @param array $optParams Optional parameters.
@ -68,10 +68,10 @@ class Google_Service_Gmail_Resource_UsersSettingsSendAs extends Google_Service_R
return $this->call('delete', array($params)); return $this->call('delete', array($params));
} }
/** /**
* Gets the specified send-as alias. Fails with an HTTP 404 error if the * Gets the specified send-as alias. Fails with an HTTP 404 error if the
* specified address is not a member of the collection. (sendAs.get) * specified address is not a member of the collection. (sendAs.get)
* *
* @param string $userId User's email address. The special value "me" can be * @param string $userId User's email address. The special value "me" can be
* used to indicate the authenticated user. * used to indicate the authenticated user.
* @param string $sendAsEmail The send-as alias to be retrieved. * @param string $sendAsEmail The send-as alias to be retrieved.
* @param array $optParams Optional parameters. * @param array $optParams Optional parameters.
@ -84,11 +84,11 @@ class Google_Service_Gmail_Resource_UsersSettingsSendAs extends Google_Service_R
return $this->call('get', array($params), "Google_Service_Gmail_SendAs"); return $this->call('get', array($params), "Google_Service_Gmail_SendAs");
} }
/** /**
* Lists the send-as aliases for the specified account. The result includes the * Lists the send-as aliases for the specified account. The result includes the
* primary send-as address associated with the account as well as any custom * primary send-as address associated with the account as well as any custom
* "from" aliases. (sendAs.listUsersSettingsSendAs) * "from" aliases. (sendAs.listUsersSettingsSendAs)
* *
* @param string $userId User's email address. The special value "me" can be * @param string $userId User's email address. The special value "me" can be
* used to indicate the authenticated user. * used to indicate the authenticated user.
* @param array $optParams Optional parameters. * @param array $optParams Optional parameters.
* @return Google_Service_Gmail_ListSendAsResponse * @return Google_Service_Gmail_ListSendAsResponse
@ -100,14 +100,9 @@ class Google_Service_Gmail_Resource_UsersSettingsSendAs extends Google_Service_R
return $this->call('list', array($params), "Google_Service_Gmail_ListSendAsResponse"); return $this->call('list', array($params), "Google_Service_Gmail_ListSendAsResponse");
} }
/** /**
* Updates a send-as alias. If a signature is provided, Gmail will sanitize the * Patch the specified send-as alias. (sendAs.patch)
* HTML before saving it with the alias.
* *
* Addresses other than the primary address for the account can only be updated * @param string $userId User's email address. The special value "me" can be
* by service account clients that have been delegated domain-wide authority.
* This method supports patch semantics. (sendAs.patch)
*
* @param string $userId User's email address. The special value "me" can be
* used to indicate the authenticated user. * used to indicate the authenticated user.
* @param string $sendAsEmail The send-as alias to be updated. * @param string $sendAsEmail The send-as alias to be updated.
* @param Google_Service_Gmail_SendAs $postBody * @param Google_Service_Gmail_SendAs $postBody
@ -121,14 +116,14 @@ class Google_Service_Gmail_Resource_UsersSettingsSendAs extends Google_Service_R
return $this->call('patch', array($params), "Google_Service_Gmail_SendAs"); return $this->call('patch', array($params), "Google_Service_Gmail_SendAs");
} }
/** /**
* Updates a send-as alias. If a signature is provided, Gmail will sanitize the * Updates a send-as alias. If a signature is provided, Gmail will sanitize the
* HTML before saving it with the alias. * HTML before saving it with the alias.
* *
* Addresses other than the primary address for the account can only be updated * Addresses other than the primary address for the account can only be updated
* by service account clients that have been delegated domain-wide authority. * by service account clients that have been delegated domain-wide authority.
* (sendAs.update) * (sendAs.update)
* *
* @param string $userId User's email address. The special value "me" can be * @param string $userId User's email address. The special value "me" can be
* used to indicate the authenticated user. * used to indicate the authenticated user.
* @param string $sendAsEmail The send-as alias to be updated. * @param string $sendAsEmail The send-as alias to be updated.
* @param Google_Service_Gmail_SendAs $postBody * @param Google_Service_Gmail_SendAs $postBody
@ -148,7 +143,7 @@ class Google_Service_Gmail_Resource_UsersSettingsSendAs extends Google_Service_R
* This method is only available to service account clients that have been * This method is only available to service account clients that have been
* delegated domain-wide authority. (sendAs.verify) * delegated domain-wide authority. (sendAs.verify)
* *
* @param string $userId User's email address. The special value "me" can be * @param string $userId User's email address. The special value "me" can be
* used to indicate the authenticated user. * used to indicate the authenticated user.
* @param string $sendAsEmail The send-as alias to be verified. * @param string $sendAsEmail The send-as alias to be verified.
* @param array $optParams Optional parameters. * @param array $optParams Optional parameters.

View File

@ -48,9 +48,9 @@ class Google_Service_Gmail_Resource_UsersThreads extends Google_Service_Resource
* @param string $id The ID of the thread to retrieve. * @param string $id The ID of the thread to retrieve.
* @param array $optParams Optional parameters. * @param array $optParams Optional parameters.
* *
* @opt_param string format The format to return the messages in.
* @opt_param string metadataHeaders When given and format is METADATA, only * @opt_param string metadataHeaders When given and format is METADATA, only
* include headers specified. * include headers specified.
* @opt_param string format The format to return the messages in.
* @return Google_Service_Gmail_Thread * @return Google_Service_Gmail_Thread
*/ */
public function get($userId, $id, $optParams = array()) public function get($userId, $id, $optParams = array())
@ -66,17 +66,17 @@ class Google_Service_Gmail_Resource_UsersThreads extends Google_Service_Resource
* used to indicate the authenticated user. * used to indicate the authenticated user.
* @param array $optParams Optional parameters. * @param array $optParams Optional parameters.
* *
* @opt_param bool includeSpamTrash Include threads from SPAM and TRASH in the
* results.
* @opt_param string labelIds Only return threads with labels that match all of
* the specified label IDs.
* @opt_param string maxResults Maximum number of threads to return.
* @opt_param string pageToken Page token to retrieve a specific page of results * @opt_param string pageToken Page token to retrieve a specific page of results
* in the list. * in the list.
* @opt_param string labelIds Only return threads with labels that match all of
* the specified label IDs.
* @opt_param string q Only return threads matching the specified query. * @opt_param string q Only return threads matching the specified query.
* Supports the same query format as the Gmail search box. For example, * Supports the same query format as the Gmail search box. For example,
* "from:someuser@example.com rfc822msgid: is:unread". Parameter cannot be used * "from:someuser@example.com rfc822msgid: is:unread". Parameter cannot be used
* when accessing the api using the gmail.metadata scope. * when accessing the api using the gmail.metadata scope.
* @opt_param string maxResults Maximum number of threads to return.
* @opt_param bool includeSpamTrash Include threads from SPAM and TRASH in the
* results.
* @return Google_Service_Gmail_ListThreadsResponse * @return Google_Service_Gmail_ListThreadsResponse
*/ */
public function listUsersThreads($userId, $optParams = array()) public function listUsersThreads($userId, $optParams = array())

View File

@ -38,7 +38,7 @@ use Monolog\Handler\SyslogHandler as MonologSyslogHandler;
*/ */
class Google_Client class Google_Client
{ {
const LIBVER = "2.2.3"; const LIBVER = "2.4.1";
const USER_AGENT_SUFFIX = "google-api-php-client/"; const USER_AGENT_SUFFIX = "google-api-php-client/";
const OAUTH2_REVOKE_URI = 'https://oauth2.googleapis.com/revoke'; const OAUTH2_REVOKE_URI = 'https://oauth2.googleapis.com/revoke';
const OAUTH2_TOKEN_URI = 'https://oauth2.googleapis.com/token'; const OAUTH2_TOKEN_URI = 'https://oauth2.googleapis.com/token';
@ -142,6 +142,10 @@ class Google_Client
// Service class used in Google_Client::verifyIdToken. // Service class used in Google_Client::verifyIdToken.
// Explicitly pass this in to avoid setting JWT::$leeway // Explicitly pass this in to avoid setting JWT::$leeway
'jwt' => null, 'jwt' => null,
// Setting api_format_v2 will return more detailed error messages
// from certain APIs.
'api_format_v2' => false
], ],
$config $config
); );
@ -412,6 +416,17 @@ class Google_Client
} }
/** /**
* Set the access token used for requests.
*
* Note that at the time requests are sent, tokens are cached. A token will be
* cached for each combination of service and authentication scopes. If a
* cache pool is not provided, creating a new instance of the client will
* allow modification of access tokens. If a persistent cache pool is
* provided, in order to change the access token, you must clear the cached
* token by calling `$client->getCache()->clear()`. (Use caution in this case,
* as calling `clear()` will remove all cache items, including any items not
* related to Google API PHP Client.)
*
* @param string|array $token * @param string|array $token
* @throws InvalidArgumentException * @throws InvalidArgumentException
*/ */
@ -789,12 +804,31 @@ class Google_Client
*/ */
public function execute(RequestInterface $request, $expectedClass = null) public function execute(RequestInterface $request, $expectedClass = null)
{ {
$request = $request->withHeader( $request = $request
'User-Agent', ->withHeader(
$this->config['application_name'] 'User-Agent',
. " " . self::USER_AGENT_SUFFIX sprintf(
. $this->getLibraryVersion() '%s %s%s',
); $this->config['application_name'],
self::USER_AGENT_SUFFIX,
$this->getLibraryVersion()
)
)
->withHeader(
'x-goog-api-client',
sprintf(
'gl-php/%s gdcl/%s',
phpversion(),
$this->getLibraryVersion()
)
);
if ($this->config['api_format_v2']) {
$request = $request->withHeader(
'X-GOOG-API-FORMAT-VERSION',
2
);
}
// call the authorize method // call the authorize method
// this is where most of the grunt work is done // this is where most of the grunt work is done
@ -1056,6 +1090,18 @@ class Google_Client
return $this->http; return $this->http;
} }
/**
* Set the API format version.
*
* `true` will use V2, which may return more useful error messages.
*
* @param bool $value
*/
public function setApiFormatV2($value)
{
$this->config['api_format_v2'] = (bool) $value;
}
protected function createDefaultHttpClient() protected function createDefaultHttpClient()
{ {
$options = ['exceptions' => false]; $options = ['exceptions' => false];

View File

@ -67,9 +67,11 @@ class Google_Http_MediaFileUpload
private $httpResultCode; private $httpResultCode;
/** /**
* @param $mimeType string * @param Google_Client $client
* @param $data string The bytes you want to upload. * @param RequestInterface $request
* @param $resumable bool * @param string $mimeType
* @param string $data The bytes you want to upload.
* @param bool $resumable
* @param bool $chunkSize File will be uploaded in chunks of this many bytes. * @param bool $chunkSize File will be uploaded in chunks of this many bytes.
* only used if resumable=True * only used if resumable=True
*/ */

View File

@ -294,7 +294,7 @@ class Google_Service_Resource
} }
if (count($queryVars)) { if (count($queryVars)) {
$requestUrl .= '?' . implode($queryVars, '&'); $requestUrl .= '?' . implode('&', $queryVars);
} }
return $requestUrl; return $requestUrl;

View File

@ -17,6 +17,8 @@
namespace Google\Auth; namespace Google\Auth;
use DateTime;
use Exception;
use Firebase\JWT\ExpiredException; use Firebase\JWT\ExpiredException;
use Firebase\JWT\JWT; use Firebase\JWT\JWT;
use Firebase\JWT\SignatureInvalidException; use Firebase\JWT\SignatureInvalidException;
@ -25,9 +27,16 @@ use Google\Auth\HttpHandler\HttpClientCache;
use Google\Auth\HttpHandler\HttpHandlerFactory; use Google\Auth\HttpHandler\HttpHandlerFactory;
use GuzzleHttp\Psr7; use GuzzleHttp\Psr7;
use GuzzleHttp\Psr7\Request; use GuzzleHttp\Psr7\Request;
use InvalidArgumentException;
use phpseclib\Crypt\RSA; use phpseclib\Crypt\RSA;
use phpseclib\Math\BigInteger; use phpseclib\Math\BigInteger;
use Psr\Cache\CacheItemPoolInterface; use Psr\Cache\CacheItemPoolInterface;
use RuntimeException;
use SimpleJWT\InvalidTokenException;
use SimpleJWT\JWT as SimpleJWT;
use SimpleJWT\Keys\KeyFactory;
use SimpleJWT\Keys\KeySet;
use UnexpectedValueException;
/** /**
* Wrapper around Google Access Tokens which provides convenience functions. * Wrapper around Google Access Tokens which provides convenience functions.
@ -37,6 +46,8 @@ use Psr\Cache\CacheItemPoolInterface;
class AccessToken class AccessToken
{ {
const FEDERATED_SIGNON_CERT_URL = 'https://www.googleapis.com/oauth2/v3/certs'; const FEDERATED_SIGNON_CERT_URL = 'https://www.googleapis.com/oauth2/v3/certs';
const IAP_CERT_URL = 'https://www.gstatic.com/iap/verify/public_key-jwk';
const IAP_ISSUER = 'https://cloud.google.com/iap';
const OAUTH2_ISSUER = 'accounts.google.com'; const OAUTH2_ISSUER = 'accounts.google.com';
const OAUTH2_ISSUER_HTTPS = 'https://accounts.google.com'; const OAUTH2_ISSUER_HTTPS = 'https://accounts.google.com';
const OAUTH2_REVOKE_URI = 'https://oauth2.googleapis.com/revoke'; const OAUTH2_REVOKE_URI = 'https://oauth2.googleapis.com/revoke';
@ -59,19 +70,9 @@ class AccessToken
callable $httpHandler = null, callable $httpHandler = null,
CacheItemPoolInterface $cache = null CacheItemPoolInterface $cache = null
) { ) {
// @codeCoverageIgnoreStart
if (!class_exists('phpseclib\Crypt\RSA')) {
throw new \RuntimeException('Please require phpseclib/phpseclib v2 to use this utility.');
}
// @codeCoverageIgnoreEnd
$this->httpHandler = $httpHandler $this->httpHandler = $httpHandler
?: HttpHandlerFactory::build(HttpClientCache::getHttpClient()); ?: HttpHandlerFactory::build(HttpClientCache::getHttpClient());
$this->cache = $cache ?: new MemoryCacheItemPool(); $this->cache = $cache ?: new MemoryCacheItemPool();
$this->configureJwtService();
// set phpseclib constants if applicable
$this->setPhpsecConstants();
} }
/** /**
@ -85,87 +86,215 @@ class AccessToken
* Configuration options. * Configuration options.
* *
* @type string $audience The indended recipient of the token. * @type string $audience The indended recipient of the token.
* @type string $issuer The intended issuer of the token.
* @type string $certsLocation The location (remote or local) from which * @type string $certsLocation The location (remote or local) from which
* to retrieve certificates, if not cached. This value should only be * to retrieve certificates, if not cached. This value should only be
* provided in limited circumstances in which you are sure of the * provided in limited circumstances in which you are sure of the
* behavior. * behavior.
* @type string $cacheKey The cache key of the cached certs. Defaults to
* the sha1 of $certsLocation if provided, otherwise is set to
* "federated_signon_certs_v3".
* @type bool $throwException Whether the function should throw an
* exception if the verification fails. This is useful for
* determining the reason verification failed.
* } * }
* @return array|bool the token payload, if successful, or false if not. * @return array|bool the token payload, if successful, or false if not.
* @throws \InvalidArgumentException If certs could not be retrieved from a local file. * @throws InvalidArgumentException If certs could not be retrieved from a local file.
* @throws \InvalidArgumentException If received certs are in an invalid format. * @throws InvalidArgumentException If received certs are in an invalid format.
* @throws \RuntimeException If certs could not be retrieved from a remote location. * @throws InvalidArgumentException If the cert alg is not supported.
* @throws RuntimeException If certs could not be retrieved from a remote location.
* @throws UnexpectedValueException If the token issuer does not match.
* @throws UnexpectedValueException If the token audience does not match.
*/ */
public function verify($token, array $options = []) public function verify($token, array $options = [])
{ {
$audience = isset($options['audience']) $audience = isset($options['audience'])
? $options['audience'] ? $options['audience']
: null; : null;
$issuer = isset($options['issuer'])
? $options['issuer']
: null;
$certsLocation = isset($options['certsLocation']) $certsLocation = isset($options['certsLocation'])
? $options['certsLocation'] ? $options['certsLocation']
: self::FEDERATED_SIGNON_CERT_URL; : self::FEDERATED_SIGNON_CERT_URL;
$cacheKey = isset($options['cacheKey'])
unset($options['audience'], $options['certsLocation']); ? $options['cacheKey']
: $this->getCacheKeyFromCertLocation($certsLocation);
$throwException = isset($options['throwException'])
? $options['throwException']
: false; // for backwards compatibility
// Check signature against each available cert. // Check signature against each available cert.
// allow the loop to complete unless a known bad result is encountered. $certs = $this->getCerts($certsLocation, $cacheKey, $options);
$certs = $this->getFederatedSignOnCerts($certsLocation, $options); $alg = $this->determineAlg($certs);
foreach ($certs as $cert) { if (!in_array($alg, ['RS256', 'ES256'])) {
$rsa = new RSA(); throw new InvalidArgumentException(
$rsa->loadKey([ 'unrecognized "alg" in certs, expected ES256 or RS256');
'n' => new BigInteger($this->callJwtStatic('urlsafeB64Decode', [ }
$cert['n'] try {
]), 256), if ($alg == 'RS256') {
'e' => new BigInteger($this->callJwtStatic('urlsafeB64Decode', [ return $this->verifyRs256($token, $certs, $audience, $issuer);
$cert['e']
]), 256)
]);
try {
$pubkey = $rsa->getPublicKey();
$payload = $this->callJwtStatic('decode', [
$token,
$pubkey,
['RS256']
]);
if (property_exists($payload, 'aud')) {
if ($audience && $payload->aud != $audience) {
return false;
}
}
// support HTTP and HTTPS issuers
// @see https://developers.google.com/identity/sign-in/web/backend-auth
$issuers = [self::OAUTH2_ISSUER, self::OAUTH2_ISSUER_HTTPS];
if (!isset($payload->iss) || !in_array($payload->iss, $issuers)) {
return false;
}
return (array) $payload;
} catch (ExpiredException $e) {
return false;
} catch (\ExpiredException $e) {
// (firebase/php-jwt 2)
return false;
} catch (SignatureInvalidException $e) {
// continue
} catch (\SignatureInvalidException $e) {
// continue (firebase/php-jwt 2)
} catch (\DomainException $e) {
// continue
} }
return $this->verifyEs256($token, $certs, $audience, $issuer);
} catch (ExpiredException $e) { // firebase/php-jwt 3+
} catch (\ExpiredException $e) { // firebase/php-jwt 2
} catch (SignatureInvalidException $e) { // firebase/php-jwt 3+
} catch (\SignatureInvalidException $e) { // firebase/php-jwt 2
} catch (InvalidTokenException $e) { // simplejwt
} catch (DomainException $e) {
} catch (InvalidArgumentException $e) {
} catch (UnexpectedValueException $e) {
}
if ($throwException) {
throw $e;
} }
return false; return false;
} }
/**
* Identifies the expected algorithm to verify by looking at the "alg" key
* of the provided certs.
*
* @param array $certs Certificate array according to the JWK spec (see
* https://tools.ietf.org/html/rfc7517).
* @return string The expected algorithm, such as "ES256" or "RS256".
*/
private function determineAlg(array $certs)
{
$alg = null;
foreach ($certs as $cert) {
if (empty($cert['alg'])) {
throw new InvalidArgumentException(
'certs expects "alg" to be set'
);
}
$alg = $alg ?: $cert['alg'];
if ($alg != $cert['alg']) {
throw new InvalidArgumentException(
'More than one alg detected in certs'
);
}
}
return $alg;
}
/**
* Verifies an ES256-signed JWT.
*
* @param string $token The JSON Web Token to be verified.
* @param array $certs Certificate array according to the JWK spec (see
* https://tools.ietf.org/html/rfc7517).
* @param string|null $audience If set, returns false if the provided
* audience does not match the "aud" claim on
* the JWT.
* @param string|null $issuer If set, returns false if the provided
* issuer does not match the "iss" claim on
* the JWT.
* @return array|bool the token payload, if successful, or false if not.
*/
private function verifyEs256($token, array $certs, $audience = null, $issuer = null)
{
$this->checkSimpleJwt();
$jwkset = new KeySet();
foreach ($certs as $cert) {
$jwkset->add(KeyFactory::create($cert, 'php'));
}
// Validate the signature using the key set and ES256 algorithm.
$jwt = $this->callSimpleJwtDecode([$token, $jwkset, 'ES256']);
$payload = $jwt->getClaims();
if (isset($payload['aud'])) {
if ($audience && $payload['aud'] != $audience) {
throw new UnexpectedValueException('Audience does not match');
}
}
// @see https://cloud.google.com/iap/docs/signed-headers-howto#verifying_the_jwt_payload
$issuer = $issuer ?: self::IAP_ISSUER;
if (!isset($payload['iss']) || $payload['iss'] !== $issuer) {
throw new UnexpectedValueException('Issuer does not match');
}
return $payload;
}
/**
* Verifies an RS256-signed JWT.
*
* @param string $token The JSON Web Token to be verified.
* @param array $certs Certificate array according to the JWK spec (see
* https://tools.ietf.org/html/rfc7517).
* @param string|null $audience If set, returns false if the provided
* audience does not match the "aud" claim on
* the JWT.
* @param string|null $issuer If set, returns false if the provided
* issuer does not match the "iss" claim on
* the JWT.
* @return array|bool the token payload, if successful, or false if not.
*/
private function verifyRs256($token, array $certs, $audience = null, $issuer = null)
{
$this->checkAndInitializePhpsec();
$keys = [];
foreach ($certs as $cert) {
if (empty($cert['kid'])) {
throw new InvalidArgumentException(
'certs expects "kid" to be set'
);
}
if (empty($cert['n']) || empty($cert['e'])) {
throw new InvalidArgumentException(
'RSA certs expects "n" and "e" to be set'
);
}
$rsa = new RSA();
$rsa->loadKey([
'n' => new BigInteger($this->callJwtStatic('urlsafeB64Decode', [
$cert['n'],
]), 256),
'e' => new BigInteger($this->callJwtStatic('urlsafeB64Decode', [
$cert['e']
]), 256),
]);
// create an array of key IDs to certs for the JWT library
$keys[$cert['kid']] = $rsa->getPublicKey();
}
$payload = $this->callJwtStatic('decode', [
$token,
$keys,
['RS256']
]);
if (property_exists($payload, 'aud')) {
if ($audience && $payload->aud != $audience) {
throw new UnexpectedValueException('Audience does not match');
}
}
// support HTTP and HTTPS issuers
// @see https://developers.google.com/identity/sign-in/web/backend-auth
$issuers = $issuer ? [$issuer] : [self::OAUTH2_ISSUER, self::OAUTH2_ISSUER_HTTPS];
if (!isset($payload->iss) || !in_array($payload->iss, $issuers)) {
throw new UnexpectedValueException('Issuer does not match');
}
return (array) $payload;
}
/** /**
* Revoke an OAuth2 access token or refresh token. This method will revoke the current access * Revoke an OAuth2 access token or refresh token. This method will revoke the current access
* token, if a token isn't provided. * token, if a token isn't provided.
* *
* @param string|array $token The token (access token or a refresh token) that should be revoked. * @param string|array $token The token (access token or a refresh token) that should be revoked.
* @param array $options [optional] Configuration options. * @param array $options [optional] Configuration options.
* @return boolean Returns True if the revocation was successful, otherwise False. * @return bool Returns True if the revocation was successful, otherwise False.
*/ */
public function revoke($token, array $options = []) public function revoke($token, array $options = [])
{ {
@ -198,11 +327,11 @@ class AccessToken
* @param string $location The location from which to retrieve certs. * @param string $location The location from which to retrieve certs.
* @param array $options [optional] Configuration options. * @param array $options [optional] Configuration options.
* @return array * @return array
* @throws \InvalidArgumentException If received certs are in an invalid format. * @throws InvalidArgumentException If received certs are in an invalid format.
*/ */
private function getFederatedSignOnCerts($location, array $options = []) private function getCerts($location, $cacheKey, array $options = [])
{ {
$cacheItem = $this->cache->getItem('federated_signon_certs_v3'); $cacheItem = $this->cache->getItem($cacheKey);
$certs = $cacheItem ? $cacheItem->get() : null; $certs = $cacheItem ? $cacheItem->get() : null;
$gotNewCerts = false; $gotNewCerts = false;
@ -213,15 +342,20 @@ class AccessToken
} }
if (!isset($certs['keys'])) { if (!isset($certs['keys'])) {
throw new \InvalidArgumentException( if ($location !== self::IAP_CERT_URL) {
'federated sign-on certs expects "keys" to be set' throw new InvalidArgumentException(
'federated sign-on certs expects "keys" to be set'
);
}
throw new InvalidArgumentException(
'certs expects "keys" to be set'
); );
} }
// Push caching off until after verifying certs are in a valid format. // Push caching off until after verifying certs are in a valid format.
// Don't want to cache bad data. // Don't want to cache bad data.
if ($gotNewCerts) { if ($gotNewCerts) {
$cacheItem->expiresAt(new \DateTime('+1 hour')); $cacheItem->expiresAt(new DateTime('+1 hour'));
$cacheItem->set($certs); $cacheItem->set($certs);
$this->cache->save($cacheItem); $this->cache->save($cacheItem);
} }
@ -234,17 +368,16 @@ class AccessToken
* *
* @param $url string location * @param $url string location
* @param array $options [optional] Configuration options. * @param array $options [optional] Configuration options.
* @throws \RuntimeException
* @return array certificates * @return array certificates
* @throws \InvalidArgumentException If certs could not be retrieved from a local file. * @throws InvalidArgumentException If certs could not be retrieved from a local file.
* @throws \RuntimeException If certs could not be retrieved from a remote location. * @throws RuntimeException If certs could not be retrieved from a remote location.
*/ */
private function retrieveCertsFromLocation($url, array $options = []) private function retrieveCertsFromLocation($url, array $options = [])
{ {
// If we're retrieving a local file, just grab it. // If we're retrieving a local file, just grab it.
if (strpos($url, 'http') !== 0) { if (strpos($url, 'http') !== 0) {
if (!file_exists($url)) { if (!file_exists($url)) {
throw new \InvalidArgumentException(sprintf( throw new InvalidArgumentException(sprintf(
'Failed to retrieve verification certificates from path: %s.', 'Failed to retrieve verification certificates from path: %s.',
$url $url
)); ));
@ -260,26 +393,30 @@ class AccessToken
return json_decode((string) $response->getBody(), true); return json_decode((string) $response->getBody(), true);
} }
throw new \RuntimeException(sprintf( throw new RuntimeException(sprintf(
'Failed to retrieve verification certificates: "%s".', 'Failed to retrieve verification certificates: "%s".',
$response->getBody()->getContents() $response->getBody()->getContents()
), $response->getStatusCode()); ), $response->getStatusCode());
} }
/** private function checkAndInitializePhpsec()
* Set required defaults for JWT.
*/
private function configureJwtService()
{ {
$class = class_exists('Firebase\JWT\JWT') // @codeCoverageIgnoreStart
? 'Firebase\JWT\JWT' if (!class_exists('phpseclib\Crypt\RSA')) {
: '\JWT'; throw new RuntimeException('Please require phpseclib/phpseclib v2 to use this utility.');
if (property_exists($class, 'leeway') && $class::$leeway < 1) {
// Ensures JWT leeway is at least 1
// @see https://github.com/google/google-api-php-client/issues/827
$class::$leeway = 1;
} }
// @codeCoverageIgnoreEnd
$this->setPhpsecConstants();
}
private function checkSimpleJwt()
{
// @codeCoverageIgnoreStart
if (!class_exists('SimpleJWT\JWT')) {
throw new RuntimeException('Please require kelvinmo/simplejwt ^0.2 to use this utility.');
}
// @codeCoverageIgnoreEnd
} }
/** /**
@ -317,4 +454,31 @@ class AccessToken
: 'JWT'; : 'JWT';
return call_user_func_array([$class, $method], $args); return call_user_func_array([$class, $method], $args);
} }
/**
* Provide a hook to mock calls to the JWT static methods.
*
* @param array $args
* @return mixed
*/
protected function callSimpleJwtDecode(array $args = [])
{
return call_user_func_array(['SimpleJWT\JWT', 'decode'], $args);
}
/**
* Generate a cache key based on the cert location using sha1 with the
* exception of using "federated_signon_certs_v3" to preserve BC.
*
* @param string $certsLocation
* @return string
*/
private function getCacheKeyFromCertLocation($certsLocation)
{
$key = $certsLocation === self::FEDERATED_SIGNON_CERT_URL
? 'federated_signon_certs_v3'
: sha1($certsLocation);
return 'google_auth_certs_cache|' . $key;
}
} }

View File

@ -20,11 +20,13 @@ namespace Google\Auth;
use DomainException; use DomainException;
use Google\Auth\Credentials\AppIdentityCredentials; use Google\Auth\Credentials\AppIdentityCredentials;
use Google\Auth\Credentials\GCECredentials; use Google\Auth\Credentials\GCECredentials;
use Google\Auth\Credentials\ServiceAccountCredentials;
use Google\Auth\HttpHandler\HttpClientCache; use Google\Auth\HttpHandler\HttpClientCache;
use Google\Auth\HttpHandler\HttpHandlerFactory; use Google\Auth\HttpHandler\HttpHandlerFactory;
use Google\Auth\Middleware\AuthTokenMiddleware; use Google\Auth\Middleware\AuthTokenMiddleware;
use Google\Auth\Subscriber\AuthTokenSubscriber; use Google\Auth\Subscriber\AuthTokenSubscriber;
use GuzzleHttp\Client; use GuzzleHttp\Client;
use InvalidArgumentException;
use Psr\Cache\CacheItemPoolInterface; use Psr\Cache\CacheItemPoolInterface;
/** /**
@ -121,8 +123,9 @@ class ApplicationDefaultCredentials
} }
/** /**
* Obtains the default FetchAuthTokenInterface implementation to use * Obtains an AuthTokenMiddleware which will fetch an access token to use in
* in this environment. * the Authorization header. The middleware is configured with the default
* FetchAuthTokenInterface implementation to use in this environment.
* *
* If supplied, $scope is used to in creating the credentials instance if * If supplied, $scope is used to in creating the credentials instance if
* this does not fallback to the Compute Engine defaults. * this does not fallback to the Compute Engine defaults.
@ -165,7 +168,97 @@ class ApplicationDefaultCredentials
} }
if (is_null($creds)) { if (is_null($creds)) {
throw new \DomainException(self::notFound()); throw new DomainException(self::notFound());
}
if (!is_null($cache)) {
$creds = new FetchAuthTokenCache($creds, $cacheConfig, $cache);
}
return $creds;
}
/**
* Obtains an AuthTokenMiddleware which will fetch an ID token to use in the
* Authorization header. The middleware is configured with the default
* FetchAuthTokenInterface implementation to use in this environment.
*
* If supplied, $targetAudience is used to set the "aud" on the resulting
* ID token.
*
* @param string $targetAudience The audience for the ID token.
* @param callable $httpHandler callback which delivers psr7 request
* @param array $cacheConfig configuration for the cache when it's present
* @param CacheItemPoolInterface $cache
*
* @return AuthTokenMiddleware
*
* @throws DomainException if no implementation can be obtained.
*/
public static function getIdTokenMiddleware(
$targetAudience,
callable $httpHandler = null,
array $cacheConfig = null,
CacheItemPoolInterface $cache = null
) {
$creds = self::getIdTokenCredentials($targetAudience, $httpHandler, $cacheConfig, $cache);
return new AuthTokenMiddleware($creds, $httpHandler);
}
/**
* Obtains the default FetchAuthTokenInterface implementation to use
* in this environment, configured with a $targetAudience for fetching an ID
* token.
*
* @param string $targetAudience The audience for the ID token.
* @param callable $httpHandler callback which delivers psr7 request
* @param array $cacheConfig configuration for the cache when it's present
* @param CacheItemPoolInterface $cache
*
* @return CredentialsLoader
*
* @throws DomainException if no implementation can be obtained.
* @throws InvalidArgumentException if JSON "type" key is invalid
*/
public static function getIdTokenCredentials(
$targetAudience,
callable $httpHandler = null,
array $cacheConfig = null,
CacheItemPoolInterface $cache = null
) {
$creds = null;
$jsonKey = CredentialsLoader::fromEnv()
?: CredentialsLoader::fromWellKnownFile();
if (!$httpHandler) {
if (!($client = HttpClientCache::getHttpClient())) {
$client = new Client();
HttpClientCache::setHttpClient($client);
}
$httpHandler = HttpHandlerFactory::build($client);
}
if (!is_null($jsonKey)) {
if (!array_key_exists('type', $jsonKey)) {
throw new \InvalidArgumentException('json key is missing the type field');
}
if ($jsonKey['type'] == 'authorized_user') {
throw new InvalidArgumentException('ID tokens are not supported for end user credentials');
}
if ($jsonKey['type'] != 'service_account') {
throw new InvalidArgumentException('invalid value in the type field');
}
$creds = new ServiceAccountCredentials(null, $jsonKey, null, $targetAudience);
} elseif (GCECredentials::onGce($httpHandler)) {
$creds = new GCECredentials(null, null, $targetAudience);
}
if (is_null($creds)) {
throw new DomainException(self::notFound());
} }
if (!is_null($cache)) { if (!is_null($cache)) {
$creds = new FetchAuthTokenCache($creds, $cacheConfig, $cache); $creds = new FetchAuthTokenCache($creds, $cacheConfig, $cache);

View File

@ -76,7 +76,7 @@ class SysVCacheItemPool implements CacheItemPoolInterface
public function __construct($options = []) public function __construct($options = [])
{ {
if (! extension_loaded('sysvshm')) { if (! extension_loaded('sysvshm')) {
throw \RuntimeException( throw new \RuntimeException(
'sysvshm extension is required to use this ItemPool'); 'sysvshm extension is required to use this ItemPool');
} }
$this->options = $options + [ $this->options = $options + [

View File

@ -24,6 +24,7 @@ namespace Google\Auth\Credentials;
*/ */
use google\appengine\api\app_identity\AppIdentityService; use google\appengine\api\app_identity\AppIdentityService;
use Google\Auth\CredentialsLoader; use Google\Auth\CredentialsLoader;
use Google\Auth\ProjectIdProviderInterface;
use Google\Auth\SignBlobInterface; use Google\Auth\SignBlobInterface;
/** /**
@ -32,35 +33,42 @@ use Google\Auth\SignBlobInterface;
* It can be used to authorize requests using the AuthTokenMiddleware or * It can be used to authorize requests using the AuthTokenMiddleware or
* AuthTokenSubscriber, but will only succeed if being run on App Engine: * AuthTokenSubscriber, but will only succeed if being run on App Engine:
* *
* use Google\Auth\Credentials\AppIdentityCredentials; * Example:
* use Google\Auth\Middleware\AuthTokenMiddleware; * ```
* use GuzzleHttp\Client; * use Google\Auth\Credentials\AppIdentityCredentials;
* use GuzzleHttp\HandlerStack; * use Google\Auth\Middleware\AuthTokenMiddleware;
* use GuzzleHttp\Client;
* use GuzzleHttp\HandlerStack;
* *
* $gae = new AppIdentityCredentials('https://www.googleapis.com/auth/books'); * $gae = new AppIdentityCredentials('https://www.googleapis.com/auth/books');
* $middleware = new AuthTokenMiddleware($gae); * $middleware = new AuthTokenMiddleware($gae);
* $stack = HandlerStack::create(); * $stack = HandlerStack::create();
* $stack->push($middleware); * $stack->push($middleware);
* *
* $client = new Client([ * $client = new Client([
* 'handler' => $stack, * 'handler' => $stack,
* 'base_uri' => 'https://www.googleapis.com/books/v1', * 'base_uri' => 'https://www.googleapis.com/books/v1',
* 'auth' => 'google_auth' * 'auth' => 'google_auth'
* ]); * ]);
* *
* $res = $client->get('volumes?q=Henry+David+Thoreau&country=US'); * $res = $client->get('volumes?q=Henry+David+Thoreau&country=US');
* ```
*/ */
class AppIdentityCredentials extends CredentialsLoader implements SignBlobInterface class AppIdentityCredentials extends CredentialsLoader implements
SignBlobInterface,
ProjectIdProviderInterface
{ {
/** /**
* Result of fetchAuthToken. * Result of fetchAuthToken.
* *
* @array * @var array
*/ */
protected $lastReceivedToken; protected $lastReceivedToken;
/** /**
* Array of OAuth2 scopes to be requested. * Array of OAuth2 scopes to be requested.
*
* @var array
*/ */
private $scope; private $scope;
@ -69,6 +77,9 @@ class AppIdentityCredentials extends CredentialsLoader implements SignBlobInterf
*/ */
private $clientName; private $clientName;
/**
* @param array $scope One or more scopes.
*/
public function __construct($scope = array()) public function __construct($scope = array())
{ {
$this->scope = $scope; $this->scope = $scope;
@ -143,6 +154,25 @@ class AppIdentityCredentials extends CredentialsLoader implements SignBlobInterf
return base64_encode(AppIdentityService::signForApp($stringToSign)['signature']); return base64_encode(AppIdentityService::signForApp($stringToSign)['signature']);
} }
/**
* Get the project ID from AppIdentityService.
*
* Returns null if AppIdentityService is unavailable.
*
* @param callable $httpHandler Not used by this type.
* @return string|null
*/
public function getProjectId(callable $httpHander = null)
{
try {
$this->checkAppEngineContext();
} catch (\Exception $e) {
return null;
}
return AppIdentityService::getApplicationId();
}
/** /**
* Get the client name from AppIdentityService. * Get the client name from AppIdentityService.
* *

View File

@ -21,11 +21,13 @@ use Google\Auth\CredentialsLoader;
use Google\Auth\HttpHandler\HttpClientCache; use Google\Auth\HttpHandler\HttpClientCache;
use Google\Auth\HttpHandler\HttpHandlerFactory; use Google\Auth\HttpHandler\HttpHandlerFactory;
use Google\Auth\Iam; use Google\Auth\Iam;
use Google\Auth\ProjectIdProviderInterface;
use Google\Auth\SignBlobInterface; use Google\Auth\SignBlobInterface;
use GuzzleHttp\Exception\ClientException; use GuzzleHttp\Exception\ClientException;
use GuzzleHttp\Exception\RequestException; use GuzzleHttp\Exception\RequestException;
use GuzzleHttp\Exception\ServerException; use GuzzleHttp\Exception\ServerException;
use GuzzleHttp\Psr7\Request; use GuzzleHttp\Psr7\Request;
use InvalidArgumentException;
/** /**
* GCECredentials supports authorization on Google Compute Engine. * GCECredentials supports authorization on Google Compute Engine.
@ -51,7 +53,9 @@ use GuzzleHttp\Psr7\Request;
* *
* $res = $client->get('myproject/taskqueues/myqueue'); * $res = $client->get('myproject/taskqueues/myqueue');
*/ */
class GCECredentials extends CredentialsLoader implements SignBlobInterface class GCECredentials extends CredentialsLoader implements
SignBlobInterface,
ProjectIdProviderInterface
{ {
const cacheKey = 'GOOGLE_AUTH_PHP_GCE'; const cacheKey = 'GOOGLE_AUTH_PHP_GCE';
@ -68,11 +72,21 @@ class GCECredentials extends CredentialsLoader implements SignBlobInterface
*/ */
const TOKEN_URI_PATH = 'v1/instance/service-accounts/default/token'; const TOKEN_URI_PATH = 'v1/instance/service-accounts/default/token';
/**
* The metadata path of the default id token.
*/
const ID_TOKEN_URI_PATH = 'v1/instance/service-accounts/default/identity';
/** /**
* The metadata path of the client ID. * The metadata path of the client ID.
*/ */
const CLIENT_ID_URI_PATH = 'v1/instance/service-accounts/default/email'; const CLIENT_ID_URI_PATH = 'v1/instance/service-accounts/default/email';
/**
* The metadata path of the project ID.
*/
const PROJECT_ID_URI_PATH = 'v1/project/project-id';
/** /**
* The header whose presence indicates GCE presence. * The header whose presence indicates GCE presence.
*/ */
@ -111,10 +125,15 @@ class GCECredentials extends CredentialsLoader implements SignBlobInterface
protected $lastReceivedToken; protected $lastReceivedToken;
/** /**
* @var string * @var string|null
*/ */
private $clientName; private $clientName;
/**
* @var string|null
*/
private $projectId;
/** /**
* @var Iam|null * @var Iam|null
*/ */
@ -125,15 +144,26 @@ class GCECredentials extends CredentialsLoader implements SignBlobInterface
*/ */
private $tokenUri; private $tokenUri;
/**
* @var string
*/
private $targetAudience;
/** /**
* @param Iam $iam [optional] An IAM instance. * @param Iam $iam [optional] An IAM instance.
* @param string|array $scope [optional] the scope of the access request, * @param string|array $scope [optional] the scope of the access request,
* expressed either as an array or as a space-delimited string. * expressed either as an array or as a space-delimited string.
* @param string $targetAudience [optional] The audience for the ID token.
*/ */
public function __construct(Iam $iam = null, $scope = null) public function __construct(Iam $iam = null, $scope = null, $targetAudience = null)
{ {
$this->iam = $iam; $this->iam = $iam;
if ($scope && $targetAudience) {
throw new InvalidArgumentException(
'Scope and targetAudience cannot both be supplied');
}
$tokenUri = self::getTokenUri(); $tokenUri = self::getTokenUri();
if ($scope) { if ($scope) {
if (is_string($scope)) { if (is_string($scope)) {
@ -143,6 +173,13 @@ class GCECredentials extends CredentialsLoader implements SignBlobInterface
$scope = implode(',', $scope); $scope = implode(',', $scope);
$tokenUri = $tokenUri . '?scopes='. $scope; $tokenUri = $tokenUri . '?scopes='. $scope;
} elseif ($targetAudience) {
$tokenUri = sprintf('http://%s/computeMetadata/%s?audience=%s',
self::METADATA_IP,
self::ID_TOKEN_URI_PATH,
$targetAudience
);
$this->targetAudience = $targetAudience;
} }
$this->tokenUri = $tokenUri; $this->tokenUri = $tokenUri;
@ -172,6 +209,18 @@ class GCECredentials extends CredentialsLoader implements SignBlobInterface
return $base . self::CLIENT_ID_URI_PATH; return $base . self::CLIENT_ID_URI_PATH;
} }
/**
* The full uri for accessing the default project ID.
*
* @return string
*/
private static function getProjectIdUri()
{
$base = 'http://' . self::METADATA_IP . '/computeMetadata/';
return $base . self::PROJECT_ID_URI_PATH;
}
/** /**
* Determines if this an App Engine Flexible instance, by accessing the * Determines if this an App Engine Flexible instance, by accessing the
* GAE_INSTANCE environment variable. * GAE_INSTANCE environment variable.
@ -189,8 +238,7 @@ class GCECredentials extends CredentialsLoader implements SignBlobInterface
* If $httpHandler is not specified a the default HttpHandler is used. * If $httpHandler is not specified a the default HttpHandler is used.
* *
* @param callable $httpHandler callback which delivers psr7 request * @param callable $httpHandler callback which delivers psr7 request
* * @return bool True if this a GCEInstance, false otherwise
* @return true if this a GCEInstance false otherwise
*/ */
public static function onGce(callable $httpHandler = null) public static function onGce(callable $httpHandler = null)
{ {
@ -234,11 +282,14 @@ class GCECredentials extends CredentialsLoader implements SignBlobInterface
* *
* @param callable $httpHandler callback which delivers psr7 request * @param callable $httpHandler callback which delivers psr7 request
* *
* @return array A set of auth related metadata, containing the following * @return array A set of auth related metadata, based on the token type.
* keys: *
* Access tokens have the following keys:
* - access_token (string) * - access_token (string)
* - expires_in (int) * - expires_in (int)
* - token_type (string) * - token_type (string)
* ID tokens have the following keys:
* - id_token (string)
* *
* @throws \Exception * @throws \Exception
*/ */
@ -255,8 +306,13 @@ class GCECredentials extends CredentialsLoader implements SignBlobInterface
return array(); // return an empty array with no access token return array(); // return an empty array with no access token
} }
$json = $this->getFromMetadata($httpHandler, $this->tokenUri); $response = $this->getFromMetadata($httpHandler, $this->tokenUri);
if (null === $json = json_decode($json, true)) {
if ($this->targetAudience) {
return ['id_token' => $response];
}
if (null === $json = json_decode($response, true)) {
throw new \Exception('Invalid JSON response'); throw new \Exception('Invalid JSON response');
} }
@ -351,6 +407,36 @@ class GCECredentials extends CredentialsLoader implements SignBlobInterface
return $signer->signBlob($email, $accessToken, $stringToSign); return $signer->signBlob($email, $accessToken, $stringToSign);
} }
/**
* Fetch the default Project ID from compute engine.
*
* Returns null if called outside GCE.
*
* @param callable $httpHandler Callback which delivers psr7 request
* @return string|null
*/
public function getProjectId(callable $httpHandler = null)
{
if ($this->projectId) {
return $this->projectId;
}
$httpHandler = $httpHandler
?: HttpHandlerFactory::build(HttpClientCache::getHttpClient());
if (!$this->hasCheckedOnGce) {
$this->isOnGce = self::onGce($httpHandler);
$this->hasCheckedOnGce = true;
}
if (!$this->isOnGce) {
return null;
}
$this->projectId = $this->getFromMetadata($httpHandler, self::getProjectIdUri());
return $this->projectId;
}
/** /**
* Fetch the value of a GCE metadata server URI. * Fetch the value of a GCE metadata server URI.
* *

View File

@ -18,9 +18,12 @@
namespace Google\Auth\Credentials; namespace Google\Auth\Credentials;
use Google\Auth\CredentialsLoader; use Google\Auth\CredentialsLoader;
use Google\Auth\GetQuotaProjectInterface;
use Google\Auth\OAuth2; use Google\Auth\OAuth2;
use Google\Auth\ProjectIdProviderInterface;
use Google\Auth\ServiceAccountSignerTrait; use Google\Auth\ServiceAccountSignerTrait;
use Google\Auth\SignBlobInterface; use Google\Auth\SignBlobInterface;
use InvalidArgumentException;
/** /**
* ServiceAccountCredentials supports authorization using a Google service * ServiceAccountCredentials supports authorization using a Google service
@ -55,7 +58,10 @@ use Google\Auth\SignBlobInterface;
* *
* $res = $client->get('myproject/taskqueues/myqueue'); * $res = $client->get('myproject/taskqueues/myqueue');
*/ */
class ServiceAccountCredentials extends CredentialsLoader implements SignBlobInterface class ServiceAccountCredentials extends CredentialsLoader implements
GetQuotaProjectInterface,
SignBlobInterface,
ProjectIdProviderInterface
{ {
use ServiceAccountSignerTrait; use ServiceAccountSignerTrait;
@ -66,6 +72,18 @@ class ServiceAccountCredentials extends CredentialsLoader implements SignBlobInt
*/ */
protected $auth; protected $auth;
/**
* The quota project associated with the JSON credentials
*
* @var string
*/
protected $quotaProject;
/*
* @var string|null
*/
protected $projectId;
/** /**
* Create a new ServiceAccountCredentials. * Create a new ServiceAccountCredentials.
* *
@ -75,11 +93,13 @@ class ServiceAccountCredentials extends CredentialsLoader implements SignBlobInt
* as an associative array * as an associative array
* @param string $sub an email address account to impersonate, in situations when * @param string $sub an email address account to impersonate, in situations when
* the service account has been delegated domain wide access. * the service account has been delegated domain wide access.
* @param string $targetAudience The audience for the ID token.
*/ */
public function __construct( public function __construct(
$scope, $scope,
$jsonKey, $jsonKey,
$sub = null $sub = null,
$targetAudience = null
) { ) {
if (is_string($jsonKey)) { if (is_string($jsonKey)) {
if (!file_exists($jsonKey)) { if (!file_exists($jsonKey)) {
@ -98,6 +118,17 @@ class ServiceAccountCredentials extends CredentialsLoader implements SignBlobInt
throw new \InvalidArgumentException( throw new \InvalidArgumentException(
'json key is missing the private_key field'); 'json key is missing the private_key field');
} }
if (array_key_exists('quota_project', $jsonKey)) {
$this->quotaProject = (string) $jsonKey['quota_project'];
}
if ($scope && $targetAudience) {
throw new InvalidArgumentException(
'Scope and targetAudience cannot both be supplied');
}
$additionalClaims = [];
if ($targetAudience) {
$additionalClaims = ['target_audience' => $targetAudience];
}
$this->auth = new OAuth2([ $this->auth = new OAuth2([
'audience' => self::TOKEN_CREDENTIAL_URI, 'audience' => self::TOKEN_CREDENTIAL_URI,
'issuer' => $jsonKey['client_email'], 'issuer' => $jsonKey['client_email'],
@ -106,7 +137,12 @@ class ServiceAccountCredentials extends CredentialsLoader implements SignBlobInt
'signingKey' => $jsonKey['private_key'], 'signingKey' => $jsonKey['private_key'],
'sub' => $sub, 'sub' => $sub,
'tokenCredentialUri' => self::TOKEN_CREDENTIAL_URI, 'tokenCredentialUri' => self::TOKEN_CREDENTIAL_URI,
'additionalClaims' => $additionalClaims,
]); ]);
$this->projectId = isset($jsonKey['project_id'])
? $jsonKey['project_id']
: null;
} }
/** /**
@ -144,6 +180,19 @@ class ServiceAccountCredentials extends CredentialsLoader implements SignBlobInt
return $this->auth->getLastReceivedToken(); return $this->auth->getLastReceivedToken();
} }
/**
* Get the project ID from the service account keyfile.
*
* Returns null if the project ID does not exist in the keyfile.
*
* @param callable $httpHandler Not used by this credentials type.
* @return string|null
*/
public function getProjectId(callable $httpHandler = null)
{
return $this->projectId;
}
/** /**
* Updates metadata with the authorization token. * Updates metadata with the authorization token.
* *
@ -195,4 +244,14 @@ class ServiceAccountCredentials extends CredentialsLoader implements SignBlobInt
{ {
return $this->auth->getIssuer(); return $this->auth->getIssuer();
} }
/**
* Get the quota project used for this API request
*
* @return string|null
*/
public function getQuotaProject()
{
return $this->quotaProject;
}
} }

View File

@ -18,7 +18,9 @@
namespace Google\Auth\Credentials; namespace Google\Auth\Credentials;
use Google\Auth\CredentialsLoader; use Google\Auth\CredentialsLoader;
use Google\Auth\GetQuotaProjectInterface;
use Google\Auth\OAuth2; use Google\Auth\OAuth2;
use Google\Auth\ProjectIdProviderInterface;
use Google\Auth\ServiceAccountSignerTrait; use Google\Auth\ServiceAccountSignerTrait;
use Google\Auth\SignBlobInterface; use Google\Auth\SignBlobInterface;
@ -31,7 +33,10 @@ use Google\Auth\SignBlobInterface;
* console (via 'Generate new Json Key'). It is not part of any OAuth2 * console (via 'Generate new Json Key'). It is not part of any OAuth2
* flow, rather it creates a JWT and sends that as a credential. * flow, rather it creates a JWT and sends that as a credential.
*/ */
class ServiceAccountJwtAccessCredentials extends CredentialsLoader implements SignBlobInterface class ServiceAccountJwtAccessCredentials extends CredentialsLoader implements
GetQuotaProjectInterface,
SignBlobInterface,
ProjectIdProviderInterface
{ {
use ServiceAccountSignerTrait; use ServiceAccountSignerTrait;
@ -42,6 +47,11 @@ class ServiceAccountJwtAccessCredentials extends CredentialsLoader implements Si
*/ */
protected $auth; protected $auth;
/**
* The quota project associated with the JSON credentials
*/
protected $quotaProject;
/** /**
* Create a new ServiceAccountJwtAccessCredentials. * Create a new ServiceAccountJwtAccessCredentials.
* *
@ -67,12 +77,19 @@ class ServiceAccountJwtAccessCredentials extends CredentialsLoader implements Si
throw new \InvalidArgumentException( throw new \InvalidArgumentException(
'json key is missing the private_key field'); 'json key is missing the private_key field');
} }
if (array_key_exists('quota_project', $jsonKey)) {
$this->quotaProject = (string) $jsonKey['quota_project'];
}
$this->auth = new OAuth2([ $this->auth = new OAuth2([
'issuer' => $jsonKey['client_email'], 'issuer' => $jsonKey['client_email'],
'sub' => $jsonKey['client_email'], 'sub' => $jsonKey['client_email'],
'signingAlgorithm' => 'RS256', 'signingAlgorithm' => 'RS256',
'signingKey' => $jsonKey['private_key'], 'signingKey' => $jsonKey['private_key'],
]); ]);
$this->projectId = isset($jsonKey['project_id'])
? $jsonKey['project_id']
: null;
} }
/** /**
@ -135,6 +152,19 @@ class ServiceAccountJwtAccessCredentials extends CredentialsLoader implements Si
return $this->auth->getLastReceivedToken(); return $this->auth->getLastReceivedToken();
} }
/**
* Get the project ID from the service account keyfile.
*
* Returns null if the project ID does not exist in the keyfile.
*
* @param callable $httpHandler Not used by this credentials type.
* @return string|null
*/
public function getProjectId(callable $httpHandler = null)
{
return $this->projectId;
}
/** /**
* Get the client name from the keyfile. * Get the client name from the keyfile.
* *
@ -147,4 +177,14 @@ class ServiceAccountJwtAccessCredentials extends CredentialsLoader implements Si
{ {
return $this->auth->getIssuer(); return $this->auth->getIssuer();
} }
/**
* Get the quota project used for this API request
*
* @return string|null
*/
public function getQuotaProject()
{
return $this->quotaProject;
}
} }

View File

@ -18,6 +18,7 @@
namespace Google\Auth\Credentials; namespace Google\Auth\Credentials;
use Google\Auth\CredentialsLoader; use Google\Auth\CredentialsLoader;
use Google\Auth\GetQuotaProjectInterface;
use Google\Auth\OAuth2; use Google\Auth\OAuth2;
/** /**
@ -31,7 +32,7 @@ use Google\Auth\OAuth2;
* *
* @see [Application Default Credentials](http://goo.gl/mkAHpZ) * @see [Application Default Credentials](http://goo.gl/mkAHpZ)
*/ */
class UserRefreshCredentials extends CredentialsLoader class UserRefreshCredentials extends CredentialsLoader implements GetQuotaProjectInterface
{ {
const CLOUD_SDK_CLIENT_ID = const CLOUD_SDK_CLIENT_ID =
'764086051850-6qr4p6gpi6hn506pt8ejuq83di341hur.apps.googleusercontent.com'; '764086051850-6qr4p6gpi6hn506pt8ejuq83di341hur.apps.googleusercontent.com';
@ -45,6 +46,11 @@ class UserRefreshCredentials extends CredentialsLoader
*/ */
protected $auth; protected $auth;
/**
* The quota project associated with the JSON credentials
*/
protected $quotaProject;
/** /**
* Create a new UserRefreshCredentials. * Create a new UserRefreshCredentials.
* *
@ -85,7 +91,11 @@ class UserRefreshCredentials extends CredentialsLoader
'scope' => $scope, 'scope' => $scope,
'tokenCredentialUri' => self::TOKEN_CREDENTIAL_URI, 'tokenCredentialUri' => self::TOKEN_CREDENTIAL_URI,
]); ]);
if (array_key_exists('quota_project', $jsonKey)) {
$this->quotaProject = (string) $jsonKey['quota_project'];
}
if ($jsonKey['client_id'] === self::CLOUD_SDK_CLIENT_ID if ($jsonKey['client_id'] === self::CLOUD_SDK_CLIENT_ID
&& is_null($this->quotaProject)
&& getenv(self::SUPPRESS_CLOUD_SDK_CREDS_WARNING_ENV) !== 'true') { && getenv(self::SUPPRESS_CLOUD_SDK_CREDS_WARNING_ENV) !== 'true') {
trigger_error( trigger_error(
'Your application has authenticated using end user credentials ' 'Your application has authenticated using end user credentials '
@ -134,4 +144,14 @@ class UserRefreshCredentials extends CredentialsLoader
{ {
return $this->auth->getLastReceivedToken(); return $this->auth->getLastReceivedToken();
} }
/**
* Get the quota project used for this API request
*
* @return string|null
*/
public function getQuotaProject()
{
return $this->quotaProject;
}
} }

View File

@ -23,7 +23,11 @@ use Psr\Cache\CacheItemPoolInterface;
* A class to implement caching for any object implementing * A class to implement caching for any object implementing
* FetchAuthTokenInterface * FetchAuthTokenInterface
*/ */
class FetchAuthTokenCache implements FetchAuthTokenInterface, SignBlobInterface class FetchAuthTokenCache implements
FetchAuthTokenInterface,
GetQuotaProjectInterface,
SignBlobInterface,
ProjectIdProviderInterface
{ {
use CacheTrait; use CacheTrait;
@ -139,4 +143,37 @@ class FetchAuthTokenCache implements FetchAuthTokenInterface, SignBlobInterface
return $this->fetcher->signBlob($stringToSign, $forceOpenSsl); return $this->fetcher->signBlob($stringToSign, $forceOpenSsl);
} }
/**
* Get the quota project used for this API request from the credentials
* fetcher.
*
* @return string|null
*/
public function getQuotaProject()
{
if ($this->fetcher instanceof GetQuotaProjectInterface) {
return $this->fetcher->getQuotaProject();
}
}
/*
* Get the Project ID from the fetcher.
*
* @param callable $httpHandler Callback which delivers psr7 request
* @return string|null
* @throws \RuntimeException If the fetcher does not implement
* `Google\Auth\ProvidesProjectIdInterface`.
*/
public function getProjectId(callable $httpHandler = null)
{
if (!$this->fetcher instanceof ProjectIdProviderInterface) {
throw new \RuntimeException(
'Credentials fetcher does not implement ' .
'Google\Auth\ProvidesProjectIdInterface'
);
}
return $this->fetcher->getProjectId($httpHandler);
}
} }

View File

@ -0,0 +1,33 @@
<?php
/*
* Copyright 2019 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
namespace Google\Auth;
/**
* An interface implemented by objects that can get quota projects.
*/
interface GetQuotaProjectInterface
{
const X_GOOG_USER_PROJECT_HEADER = 'X-Goog-User-Project';
/**
* Get the quota project used for this API request
*
* @return string|null
*/
public function getQuotaProject();
}

View File

@ -18,6 +18,7 @@
namespace Google\Auth\Middleware; namespace Google\Auth\Middleware;
use Google\Auth\FetchAuthTokenInterface; use Google\Auth\FetchAuthTokenInterface;
use Google\Auth\GetQuotaProjectInterface;
use Psr\Http\Message\RequestInterface; use Psr\Http\Message\RequestInterface;
/** /**
@ -101,6 +102,13 @@ class AuthTokenMiddleware
$request = $request->withHeader('authorization', 'Bearer ' . $this->fetchToken()); $request = $request->withHeader('authorization', 'Bearer ' . $this->fetchToken());
if ($quotaProject = $this->getQuotaProject()) {
$request = $request->withHeader(
GetQuotaProjectInterface::X_GOOG_USER_PROJECT_HEADER,
$quotaProject
);
}
return $handler($request, $options); return $handler($request, $options);
}; };
} }
@ -122,5 +130,16 @@ class AuthTokenMiddleware
return $auth_tokens['access_token']; return $auth_tokens['access_token'];
} }
if (array_key_exists('id_token', $auth_tokens)) {
return $auth_tokens['id_token'];
}
}
private function getQuotaProject()
{
if ($this->fetcher instanceof GetQuotaProjectInterface) {
return $this->fetcher->getQuotaProject();
}
} }
} }

View File

@ -0,0 +1,32 @@
<?php
/*
* Copyright 2020 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
namespace Google\Auth;
/**
* Describes a Credentials object which supports fetching the project ID.
*/
interface ProjectIdProviderInterface
{
/**
* Get the project ID.
*
* @param callable $httpHandler Callback which delivers psr7 request
* @return string|null
*/
public function getProjectId(callable $httpHandler = null);
}

View File

@ -18,6 +18,7 @@
namespace Google\Auth\Subscriber; namespace Google\Auth\Subscriber;
use Google\Auth\FetchAuthTokenInterface; use Google\Auth\FetchAuthTokenInterface;
use Google\Auth\GetQuotaProjectInterface;
use GuzzleHttp\Event\BeforeEvent; use GuzzleHttp\Event\BeforeEvent;
use GuzzleHttp\Event\RequestEvents; use GuzzleHttp\Event\RequestEvents;
use GuzzleHttp\Event\SubscriberInterface; use GuzzleHttp\Event\SubscriberInterface;
@ -114,5 +115,19 @@ class AuthTokenSubscriber implements SubscriberInterface
call_user_func($this->tokenCallback, $this->fetcher->getCacheKey(), $auth_tokens['access_token']); call_user_func($this->tokenCallback, $this->fetcher->getCacheKey(), $auth_tokens['access_token']);
} }
} }
if ($quotaProject = $this->getQuotaProject()) {
$request->setHeader(
GetQuotaProjectInterface::X_GOOG_USER_PROJECT_HEADER,
$quotaProject
);
}
}
private function getQuotaProject()
{
if ($this->fetcher instanceof GetQuotaProjectInterface) {
return $this->fetcher->getQuotaProject();
}
} }
} }

View File

@ -1,18 +0,0 @@
FROM composer:latest as setup
RUN mkdir /guzzle
WORKDIR /guzzle
RUN set -xe \
&& composer init --name=guzzlehttp/test --description="Simple project for testing Guzzle scripts" --author="Márk Sági-Kazár <mark.sagikazar@gmail.com>" --no-interaction \
&& composer require guzzlehttp/guzzle
FROM php:7.3
RUN mkdir /guzzle
WORKDIR /guzzle
COPY --from=setup /guzzle /guzzle

View File

@ -2,11 +2,12 @@
namespace GuzzleHttp; namespace GuzzleHttp;
use GuzzleHttp\Cookie\CookieJar; use GuzzleHttp\Cookie\CookieJar;
use GuzzleHttp\Exception\InvalidArgumentException;
use GuzzleHttp\Promise; use GuzzleHttp\Promise;
use GuzzleHttp\Psr7; use GuzzleHttp\Psr7;
use Psr\Http\Message\UriInterface;
use Psr\Http\Message\RequestInterface; use Psr\Http\Message\RequestInterface;
use Psr\Http\Message\ResponseInterface; use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\UriInterface;
/** /**
* @method ResponseInterface get(string|UriInterface $uri, array $options = []) * @method ResponseInterface get(string|UriInterface $uri, array $options = [])
@ -75,6 +76,12 @@ class Client implements ClientInterface
$this->configureDefaults($config); $this->configureDefaults($config);
} }
/**
* @param string $method
* @param array $args
*
* @return Promise\PromiseInterface
*/
public function __call($method, $args) public function __call($method, $args)
{ {
if (count($args) < 1) { if (count($args) < 1) {
@ -89,6 +96,14 @@ class Client implements ClientInterface
: $this->request($method, $uri, $opts); : $this->request($method, $uri, $opts);
} }
/**
* Asynchronously send an HTTP request.
*
* @param array $options Request options to apply to the given
* request and to the transfer. See \GuzzleHttp\RequestOptions.
*
* @return Promise\PromiseInterface
*/
public function sendAsync(RequestInterface $request, array $options = []) public function sendAsync(RequestInterface $request, array $options = [])
{ {
// Merge the base URI into the request URI if needed. // Merge the base URI into the request URI if needed.
@ -100,12 +115,35 @@ class Client implements ClientInterface
); );
} }
/**
* Send an HTTP request.
*
* @param array $options Request options to apply to the given
* request and to the transfer. See \GuzzleHttp\RequestOptions.
*
* @return ResponseInterface
* @throws GuzzleException
*/
public function send(RequestInterface $request, array $options = []) public function send(RequestInterface $request, array $options = [])
{ {
$options[RequestOptions::SYNCHRONOUS] = true; $options[RequestOptions::SYNCHRONOUS] = true;
return $this->sendAsync($request, $options)->wait(); return $this->sendAsync($request, $options)->wait();
} }
/**
* Create and send an asynchronous HTTP request.
*
* Use an absolute path to override the base path of the client, or a
* relative path to append to the base path of the client. The URL can
* contain the query string as well. Use an array to provide a URL
* template and additional variables to use in the URL template expansion.
*
* @param string $method HTTP method
* @param string|UriInterface $uri URI object or string.
* @param array $options Request options to apply. See \GuzzleHttp\RequestOptions.
*
* @return Promise\PromiseInterface
*/
public function requestAsync($method, $uri = '', array $options = []) public function requestAsync($method, $uri = '', array $options = [])
{ {
$options = $this->prepareDefaults($options); $options = $this->prepareDefaults($options);
@ -125,12 +163,37 @@ class Client implements ClientInterface
return $this->transfer($request, $options); return $this->transfer($request, $options);
} }
/**
* Create and send an HTTP request.
*
* Use an absolute path to override the base path of the client, or a
* relative path to append to the base path of the client. The URL can
* contain the query string as well.
*
* @param string $method HTTP method.
* @param string|UriInterface $uri URI object or string.
* @param array $options Request options to apply. See \GuzzleHttp\RequestOptions.
*
* @return ResponseInterface
* @throws GuzzleException
*/
public function request($method, $uri = '', array $options = []) public function request($method, $uri = '', array $options = [])
{ {
$options[RequestOptions::SYNCHRONOUS] = true; $options[RequestOptions::SYNCHRONOUS] = true;
return $this->requestAsync($method, $uri, $options)->wait(); return $this->requestAsync($method, $uri, $options)->wait();
} }
/**
* Get a client configuration option.
*
* These options include default request options of the client, a "handler"
* (if utilized by the concrete client), and a "base_uri" if utilized by
* the concrete client.
*
* @param string|null $option The config option to retrieve.
*
* @return mixed
*/
public function getConfig($option = null) public function getConfig($option = null)
{ {
return $option === null return $option === null
@ -138,6 +201,11 @@ class Client implements ClientInterface
: (isset($this->config[$option]) ? $this->config[$option] : null); : (isset($this->config[$option]) ? $this->config[$option] : null);
} }
/**
* @param string|null $uri
*
* @return UriInterface
*/
private function buildUri($uri, array $config) private function buildUri($uri, array $config)
{ {
// for BC we accept null which would otherwise fail in uri_for // for BC we accept null which would otherwise fail in uri_for
@ -147,6 +215,11 @@ class Client implements ClientInterface
$uri = Psr7\UriResolver::resolve(Psr7\uri_for($config['base_uri']), $uri); $uri = Psr7\UriResolver::resolve(Psr7\uri_for($config['base_uri']), $uri);
} }
if (isset($config['idn_conversion']) && ($config['idn_conversion'] !== false)) {
$idnOptions = ($config['idn_conversion'] === true) ? IDNA_DEFAULT : $config['idn_conversion'];
$uri = Utils::idnUriConvert($uri, $idnOptions);
}
return $uri->getScheme() === '' && $uri->getHost() !== '' ? $uri->withScheme('http') : $uri; return $uri->getScheme() === '' && $uri->getHost() !== '' ? $uri->withScheme('http') : $uri;
} }
@ -154,6 +227,7 @@ class Client implements ClientInterface
* Configures the default options for a client. * Configures the default options for a client.
* *
* @param array $config * @param array $config
* @return void
*/ */
private function configureDefaults(array $config) private function configureDefaults(array $config)
{ {
@ -162,7 +236,8 @@ class Client implements ClientInterface
'http_errors' => true, 'http_errors' => true,
'decode_content' => true, 'decode_content' => true,
'verify' => true, 'verify' => true,
'cookies' => false 'cookies' => false,
'idn_conversion' => true,
]; ];
// Use the standard Linux HTTP_PROXY and HTTPS_PROXY if set. // Use the standard Linux HTTP_PROXY and HTTPS_PROXY if set.
@ -170,7 +245,7 @@ class Client implements ClientInterface
// We can only trust the HTTP_PROXY environment variable in a CLI // We can only trust the HTTP_PROXY environment variable in a CLI
// process due to the fact that PHP has no reliable mechanism to // process due to the fact that PHP has no reliable mechanism to
// get environment variables that start with "HTTP_". // get environment variables that start with "HTTP_".
if (php_sapi_name() == 'cli' && getenv('HTTP_PROXY')) { if (php_sapi_name() === 'cli' && getenv('HTTP_PROXY')) {
$defaults['proxy']['http'] = getenv('HTTP_PROXY'); $defaults['proxy']['http'] = getenv('HTTP_PROXY');
} }
@ -225,7 +300,7 @@ class Client implements ClientInterface
if (array_key_exists('headers', $options)) { if (array_key_exists('headers', $options)) {
// Allows default headers to be unset. // Allows default headers to be unset.
if ($options['headers'] === null) { if ($options['headers'] === null) {
$defaults['_conditional'] = null; $defaults['_conditional'] = [];
unset($options['headers']); unset($options['headers']);
} elseif (!is_array($options['headers'])) { } elseif (!is_array($options['headers'])) {
throw new \InvalidArgumentException('headers must be an array'); throw new \InvalidArgumentException('headers must be an array');
@ -251,8 +326,7 @@ class Client implements ClientInterface
* The URI of the request is not modified and the request options are used * The URI of the request is not modified and the request options are used
* as-is without merging in default options. * as-is without merging in default options.
* *
* @param RequestInterface $request * @param array $options See \GuzzleHttp\RequestOptions.
* @param array $options
* *
* @return Promise\PromiseInterface * @return Promise\PromiseInterface
*/ */
@ -271,6 +345,7 @@ class Client implements ClientInterface
} }
$request = $this->applyOptions($request, $options); $request = $this->applyOptions($request, $options);
/** @var HandlerStack $handler */
$handler = $options['handler']; $handler = $options['handler'];
try { try {
@ -411,6 +486,11 @@ class Client implements ClientInterface
return $request; return $request;
} }
/**
* Throw Exception with pre-set message.
* @return void
* @throws InvalidArgumentException Invalid body.
*/
private function invalidBody() private function invalidBody()
{ {
throw new \InvalidArgumentException('Passing in the "body" request ' throw new \InvalidArgumentException('Passing in the "body" request '

View File

@ -1,8 +1,8 @@
<?php <?php
namespace GuzzleHttp; namespace GuzzleHttp;
use GuzzleHttp\Promise\PromiseInterface;
use GuzzleHttp\Exception\GuzzleException; use GuzzleHttp\Exception\GuzzleException;
use GuzzleHttp\Promise\PromiseInterface;
use Psr\Http\Message\RequestInterface; use Psr\Http\Message\RequestInterface;
use Psr\Http\Message\ResponseInterface; use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\UriInterface; use Psr\Http\Message\UriInterface;
@ -12,7 +12,10 @@ use Psr\Http\Message\UriInterface;
*/ */
interface ClientInterface interface ClientInterface
{ {
const VERSION = '6.4.1'; /**
* @deprecated Will be removed in Guzzle 7.0.0
*/
const VERSION = '6.5.3';
/** /**
* Send an HTTP request. * Send an HTTP request.

View File

@ -94,8 +94,8 @@ class CookieJar implements CookieJarInterface
*/ */
public function getCookieByName($name) public function getCookieByName($name)
{ {
// don't allow a null name // don't allow a non string name
if ($name === null) { if ($name === null || !is_scalar($name)) {
return null; return null;
} }
foreach ($this->cookies as $cookie) { foreach ($this->cookies as $cookie) {
@ -103,6 +103,8 @@ class CookieJar implements CookieJarInterface
return $cookie; return $cookie;
} }
} }
return null;
} }
public function toArray() public function toArray()

View File

@ -58,9 +58,9 @@ interface CookieJarInterface extends \Countable, \IteratorAggregate
* arguments, then the cookie with the specified name, path and domain is * arguments, then the cookie with the specified name, path and domain is
* removed. * removed.
* *
* @param string $domain Clears cookies matching a domain * @param string|null $domain Clears cookies matching a domain
* @param string $path Clears cookies matching a domain and path * @param string|null $path Clears cookies matching a domain and path
* @param string $name Clears cookies matching a domain, path, and name * @param string|null $name Clears cookies matching a domain, path, and name
* *
* @return CookieJarInterface * @return CookieJarInterface
*/ */

View File

@ -1,9 +1,9 @@
<?php <?php
namespace GuzzleHttp\Exception; namespace GuzzleHttp\Exception;
use GuzzleHttp\Promise\PromiseInterface;
use Psr\Http\Message\RequestInterface; use Psr\Http\Message\RequestInterface;
use Psr\Http\Message\ResponseInterface; use Psr\Http\Message\ResponseInterface;
use GuzzleHttp\Promise\PromiseInterface;
use Psr\Http\Message\UriInterface; use Psr\Http\Message\UriInterface;
/** /**
@ -14,7 +14,7 @@ class RequestException extends TransferException
/** @var RequestInterface */ /** @var RequestInterface */
private $request; private $request;
/** @var ResponseInterface */ /** @var ResponseInterface|null */
private $response; private $response;
/** @var array */ /** @var array */
@ -124,42 +124,17 @@ class RequestException extends TransferException
*/ */
public static function getResponseBodySummary(ResponseInterface $response) public static function getResponseBodySummary(ResponseInterface $response)
{ {
$body = $response->getBody(); return \GuzzleHttp\Psr7\get_message_body_summary($response);
if (!$body->isSeekable() || !$body->isReadable()) {
return null;
}
$size = $body->getSize();
if ($size === 0) {
return null;
}
$summary = $body->read(120);
$body->rewind();
if ($size > 120) {
$summary .= ' (truncated...)';
}
// Matches any printable character, including unicode characters:
// letters, marks, numbers, punctuation, spacing, and separators.
if (preg_match('/[^\pL\pM\pN\pP\pS\pZ\n\r\t]/', $summary)) {
return null;
}
return $summary;
} }
/** /**
* Obfuscates URI if there is an username and a password present * Obfuscates URI if there is a username and a password present
* *
* @param UriInterface $uri * @param UriInterface $uri
* *
* @return UriInterface * @return UriInterface
*/ */
private static function obfuscateUri($uri) private static function obfuscateUri(UriInterface $uri)
{ {
$userInfo = $uri->getUserInfo(); $userInfo = $uri->getUserInfo();

View File

@ -1,8 +1,8 @@
<?php <?php
namespace GuzzleHttp\Handler; namespace GuzzleHttp\Handler;
use GuzzleHttp\Exception\RequestException;
use GuzzleHttp\Exception\ConnectException; use GuzzleHttp\Exception\ConnectException;
use GuzzleHttp\Exception\RequestException;
use GuzzleHttp\Promise\FulfilledPromise; use GuzzleHttp\Promise\FulfilledPromise;
use GuzzleHttp\Psr7; use GuzzleHttp\Psr7;
use GuzzleHttp\Psr7\LazyOpenStream; use GuzzleHttp\Psr7\LazyOpenStream;
@ -454,11 +454,16 @@ class CurlFactory implements CurlFactoryInterface
} }
if (isset($options['ssl_key'])) { if (isset($options['ssl_key'])) {
$sslKey = $options['ssl_key']; if (is_array($options['ssl_key'])) {
if (is_array($sslKey)) { if (count($options['ssl_key']) === 2) {
$conf[CURLOPT_SSLKEYPASSWD] = $sslKey[1]; list($sslKey, $conf[CURLOPT_SSLKEYPASSWD]) = $options['ssl_key'];
$sslKey = $sslKey[0]; } else {
list($sslKey) = $options['ssl_key'];
}
} }
$sslKey = isset($sslKey) ? $sslKey: $options['ssl_key'];
if (!file_exists($sslKey)) { if (!file_exists($sslKey)) {
throw new \InvalidArgumentException( throw new \InvalidArgumentException(
"SSL private key not found: {$sslKey}" "SSL private key not found: {$sslKey}"

View File

@ -1,9 +1,10 @@
<?php <?php
namespace GuzzleHttp\Handler; namespace GuzzleHttp\Handler;
use GuzzleHttp\Exception\InvalidArgumentException;
use GuzzleHttp\Promise as P; use GuzzleHttp\Promise as P;
use GuzzleHttp\Promise\Promise; use GuzzleHttp\Promise\Promise;
use GuzzleHttp\Psr7; use GuzzleHttp\Utils;
use Psr\Http\Message\RequestInterface; use Psr\Http\Message\RequestInterface;
/** /**
@ -23,6 +24,7 @@ class CurlMultiHandler
private $active; private $active;
private $handles = []; private $handles = [];
private $delays = []; private $delays = [];
private $options = [];
/** /**
* This handler accepts the following options: * This handler accepts the following options:
@ -30,6 +32,8 @@ class CurlMultiHandler
* - handle_factory: An optional factory used to create curl handles * - handle_factory: An optional factory used to create curl handles
* - select_timeout: Optional timeout (in seconds) to block before timing * - select_timeout: Optional timeout (in seconds) to block before timing
* out while selecting curl handles. Defaults to 1 second. * out while selecting curl handles. Defaults to 1 second.
* - options: An associative array of CURLMOPT_* options and
* corresponding values for curl_multi_setopt()
* *
* @param array $options * @param array $options
*/ */
@ -45,12 +49,23 @@ class CurlMultiHandler
} else { } else {
$this->selectTimeout = 1; $this->selectTimeout = 1;
} }
$this->options = isset($options['options']) ? $options['options'] : [];
} }
public function __get($name) public function __get($name)
{ {
if ($name === '_mh') { if ($name === '_mh') {
return $this->_mh = curl_multi_init(); $this->_mh = curl_multi_init();
foreach ($this->options as $option => $value) {
// A warning is raised in case of a wrong option.
curl_multi_setopt($this->_mh, $option, $value);
}
// Further calls to _mh will return the value directly, without entering the
// __get() method at all.
return $this->_mh;
} }
throw new \BadMethodCallException(); throw new \BadMethodCallException();
@ -88,7 +103,7 @@ class CurlMultiHandler
{ {
// Add any delayed handles if needed. // Add any delayed handles if needed.
if ($this->delays) { if ($this->delays) {
$currentTime = \GuzzleHttp\_current_time(); $currentTime = Utils::currentTime();
foreach ($this->delays as $id => $delay) { foreach ($this->delays as $id => $delay) {
if ($currentTime >= $delay) { if ($currentTime >= $delay) {
unset($this->delays[$id]); unset($this->delays[$id]);
@ -140,7 +155,7 @@ class CurlMultiHandler
if (empty($easy->options['delay'])) { if (empty($easy->options['delay'])) {
curl_multi_add_handle($this->_mh, $easy->handle); curl_multi_add_handle($this->_mh, $easy->handle);
} else { } else {
$this->delays[$id] = \GuzzleHttp\_current_time() + ($easy->options['delay'] / 1000); $this->delays[$id] = Utils::currentTime() + ($easy->options['delay'] / 1000);
} }
} }
@ -192,7 +207,7 @@ class CurlMultiHandler
private function timeToNext() private function timeToNext()
{ {
$currentTime = \GuzzleHttp\_current_time(); $currentTime = Utils::currentTime();
$nextTime = PHP_INT_MAX; $nextTime = PHP_INT_MAX;
foreach ($this->delays as $time) { foreach ($this->delays as $time) {
if ($time < $nextTime) { if ($time < $nextTime) {

View File

@ -66,7 +66,7 @@ class MockHandler implements \Countable
throw new \OutOfBoundsException('Mock queue is empty'); throw new \OutOfBoundsException('Mock queue is empty');
} }
if (isset($options['delay'])) { if (isset($options['delay']) && is_numeric($options['delay'])) {
usleep($options['delay'] * 1000); usleep($options['delay'] * 1000);
} }
@ -175,6 +175,11 @@ class MockHandler implements \Countable
return count($this->queue); return count($this->queue);
} }
public function reset()
{
$this->queue = [];
}
private function invokeStats( private function invokeStats(
RequestInterface $request, RequestInterface $request,
array $options, array $options,

View File

@ -1,12 +1,13 @@
<?php <?php
namespace GuzzleHttp\Handler; namespace GuzzleHttp\Handler;
use GuzzleHttp\Exception\RequestException;
use GuzzleHttp\Exception\ConnectException; use GuzzleHttp\Exception\ConnectException;
use GuzzleHttp\Exception\RequestException;
use GuzzleHttp\Promise\FulfilledPromise; use GuzzleHttp\Promise\FulfilledPromise;
use GuzzleHttp\Promise\PromiseInterface; use GuzzleHttp\Promise\PromiseInterface;
use GuzzleHttp\Psr7; use GuzzleHttp\Psr7;
use GuzzleHttp\TransferStats; use GuzzleHttp\TransferStats;
use GuzzleHttp\Utils;
use Psr\Http\Message\RequestInterface; use Psr\Http\Message\RequestInterface;
use Psr\Http\Message\ResponseInterface; use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\StreamInterface; use Psr\Http\Message\StreamInterface;
@ -33,7 +34,7 @@ class StreamHandler
usleep($options['delay'] * 1000); usleep($options['delay'] * 1000);
} }
$startTime = isset($options['on_stats']) ? \GuzzleHttp\_current_time() : null; $startTime = isset($options['on_stats']) ? Utils::currentTime() : null;
try { try {
// Does not support the expect header. // Does not support the expect header.
@ -82,7 +83,7 @@ class StreamHandler
$stats = new TransferStats( $stats = new TransferStats(
$request, $request,
$response, $response,
\GuzzleHttp\_current_time() - $startTime, Utils::currentTime() - $startTime,
$error, $error,
[] []
); );

View File

@ -1,7 +1,9 @@
<?php <?php
namespace GuzzleHttp; namespace GuzzleHttp;
use GuzzleHttp\Promise\PromiseInterface;
use Psr\Http\Message\RequestInterface; use Psr\Http\Message\RequestInterface;
use Psr\Http\Message\ResponseInterface;
/** /**
* Creates a composed Guzzle handler function by stacking middlewares on top of * Creates a composed Guzzle handler function by stacking middlewares on top of
@ -9,7 +11,7 @@ use Psr\Http\Message\RequestInterface;
*/ */
class HandlerStack class HandlerStack
{ {
/** @var callable */ /** @var callable|null */
private $handler; private $handler;
/** @var array */ /** @var array */
@ -59,6 +61,8 @@ class HandlerStack
* *
* @param RequestInterface $request * @param RequestInterface $request
* @param array $options * @param array $options
*
* @return ResponseInterface|PromiseInterface
*/ */
public function __invoke(RequestInterface $request, array $options) public function __invoke(RequestInterface $request, array $options)
{ {

View File

@ -168,6 +168,11 @@ class MessageFormatter
); );
} }
/**
* Get headers from message as string
*
* @return string
*/
private function headers(MessageInterface $message) private function headers(MessageInterface $message)
{ {
$result = ''; $result = '';

View File

@ -1,9 +1,10 @@
<?php <?php
namespace GuzzleHttp; namespace GuzzleHttp;
use GuzzleHttp\Promise\EachPromise;
use GuzzleHttp\Promise\PromiseInterface;
use GuzzleHttp\Promise\PromisorInterface; use GuzzleHttp\Promise\PromisorInterface;
use Psr\Http\Message\RequestInterface; use Psr\Http\Message\RequestInterface;
use GuzzleHttp\Promise\EachPromise;
/** /**
* Sends an iterator of requests concurrently using a capped pool size. * Sends an iterator of requests concurrently using a capped pool size.
@ -69,6 +70,11 @@ class Pool implements PromisorInterface
$this->each = new EachPromise($requests(), $config); $this->each = new EachPromise($requests(), $config);
} }
/**
* Get promise
*
* @return PromiseInterface
*/
public function promise() public function promise()
{ {
return $this->each->promise(); return $this->each->promise();
@ -106,6 +112,11 @@ class Pool implements PromisorInterface
return $res; return $res;
} }
/**
* Execute callback(s)
*
* @return void
*/
private static function cmpCallback(array &$options, $name, array &$results) private static function cmpCallback(array &$options, $name, array &$results)
{ {
if (!isset($options[$name])) { if (!isset($options[$name])) {

View File

@ -66,6 +66,11 @@ class PrepareBodyMiddleware
return $fn(Psr7\modify_request($request, $modify), $options); return $fn(Psr7\modify_request($request, $modify), $options);
} }
/**
* Add expect header
*
* @return void
*/
private function addExpectHeader( private function addExpectHeader(
RequestInterface $request, RequestInterface $request,
array $options, array $options,

View File

@ -13,7 +13,7 @@ use Psr\Http\Message\UriInterface;
* Request redirect middleware. * Request redirect middleware.
* *
* Apply this middleware like other middleware using * Apply this middleware like other middleware using
* {@see GuzzleHttp\Middleware::redirect()}. * {@see \GuzzleHttp\Middleware::redirect()}.
*/ */
class RedirectMiddleware class RedirectMiddleware
{ {
@ -76,7 +76,7 @@ class RedirectMiddleware
/** /**
* @param RequestInterface $request * @param RequestInterface $request
* @param array $options * @param array $options
* @param ResponseInterface|PromiseInterface $response * @param ResponseInterface $response
* *
* @return ResponseInterface|PromiseInterface * @return ResponseInterface|PromiseInterface
*/ */
@ -118,6 +118,11 @@ class RedirectMiddleware
return $promise; return $promise;
} }
/**
* Enable tracking on promise.
*
* @return PromiseInterface
*/
private function withTracking(PromiseInterface $promise, $uri, $statusCode) private function withTracking(PromiseInterface $promise, $uri, $statusCode)
{ {
return $promise->then( return $promise->then(
@ -135,6 +140,13 @@ class RedirectMiddleware
); );
} }
/**
* Check for too many redirects
*
* @return void
*
* @throws TooManyRedirectsException Too many redirects.
*/
private function guardMax(RequestInterface $request, array &$options) private function guardMax(RequestInterface $request, array &$options)
{ {
$current = isset($options['__redirect_count']) $current = isset($options['__redirect_count'])
@ -172,13 +184,19 @@ class RedirectMiddleware
// would do. // would do.
$statusCode = $response->getStatusCode(); $statusCode = $response->getStatusCode();
if ($statusCode == 303 || if ($statusCode == 303 ||
($statusCode <= 302 && $request->getBody() && !$options['allow_redirects']['strict']) ($statusCode <= 302 && !$options['allow_redirects']['strict'])
) { ) {
$modify['method'] = 'GET'; $modify['method'] = 'GET';
$modify['body'] = ''; $modify['body'] = '';
} }
$modify['uri'] = $this->redirectUri($request, $response, $protocols); $uri = $this->redirectUri($request, $response, $protocols);
if (isset($options['idn_conversion']) && ($options['idn_conversion'] !== false)) {
$idnOptions = ($options['idn_conversion'] === true) ? IDNA_DEFAULT : $options['idn_conversion'];
$uri = Utils::idnUriConvert($uri, $idnOptions);
}
$modify['uri'] = $uri;
Psr7\rewind_body($request); Psr7\rewind_body($request);
// Add the Referer header if it is told to do so and only // Add the Referer header if it is told to do so and only

View File

@ -132,6 +132,14 @@ final class RequestOptions
*/ */
const HTTP_ERRORS = 'http_errors'; const HTTP_ERRORS = 'http_errors';
/**
* idn: (bool|int, default=true) A combination of IDNA_* constants for
* idn_to_ascii() PHP's function (see "options" parameter). Set to false to
* disable IDN support completely, or to true to use the default
* configuration (IDNA_DEFAULT constant).
*/
const IDN_CONVERSION = 'idn_conversion';
/** /**
* json: (mixed) Adds JSON data to a request. The provided value is JSON * json: (mixed) Adds JSON data to a request. The provided value is JSON
* encoded and a Content-Type header of application/json will be added to * encoded and a Content-Type header of application/json will be added to

View File

@ -47,11 +47,11 @@ class RetryMiddleware
* *
* @param int $retries * @param int $retries
* *
* @return int * @return int milliseconds.
*/ */
public static function exponentialDelay($retries) public static function exponentialDelay($retries)
{ {
return (int) pow(2, $retries - 1); return (int) pow(2, $retries - 1) * 1000;
} }
/** /**
@ -74,6 +74,11 @@ class RetryMiddleware
); );
} }
/**
* Execute fulfilled closure
*
* @return mixed
*/
private function onFulfilled(RequestInterface $req, array $options) private function onFulfilled(RequestInterface $req, array $options)
{ {
return function ($value) use ($req, $options) { return function ($value) use ($req, $options) {
@ -90,6 +95,11 @@ class RetryMiddleware
}; };
} }
/**
* Execute rejected closure
*
* @return callable
*/
private function onRejected(RequestInterface $req, array $options) private function onRejected(RequestInterface $req, array $options)
{ {
return function ($reason) use ($req, $options) { return function ($reason) use ($req, $options) {
@ -106,6 +116,9 @@ class RetryMiddleware
}; };
} }
/**
* @return self
*/
private function doRetry(RequestInterface $request, array $options, ResponseInterface $response = null) private function doRetry(RequestInterface $request, array $options, ResponseInterface $response = null)
{ {
$options['delay'] = call_user_func($this->delay, ++$options['retries'], $response); $options['delay'] = call_user_func($this->delay, ++$options['retries'], $response);

View File

@ -18,11 +18,11 @@ final class TransferStats
private $handlerErrorData; private $handlerErrorData;
/** /**
* @param RequestInterface $request Request that was sent. * @param RequestInterface $request Request that was sent.
* @param ResponseInterface $response Response received (if any) * @param ResponseInterface|null $response Response received (if any)
* @param float|null $transferTime Total handler transfer time. * @param float|null $transferTime Total handler transfer time.
* @param mixed $handlerErrorData Handler error data. * @param mixed $handlerErrorData Handler error data.
* @param array $handlerStats Handler specific stats. * @param array $handlerStats Handler specific stats.
*/ */
public function __construct( public function __construct(
RequestInterface $request, RequestInterface $request,
@ -93,7 +93,7 @@ final class TransferStats
/** /**
* Get the estimated time the request was being transferred by the handler. * Get the estimated time the request was being transferred by the handler.
* *
* @return float Time in seconds. * @return float|null Time in seconds.
*/ */
public function getTransferTime() public function getTransferTime()
{ {

View File

@ -0,0 +1,67 @@
<?php
namespace GuzzleHttp;
use GuzzleHttp\Exception\InvalidArgumentException;
use Psr\Http\Message\UriInterface;
final class Utils
{
/**
* Wrapper for the hrtime() or microtime() functions
* (depending on the PHP version, one of the two is used)
*
* @return float|mixed UNIX timestamp
*
* @internal
*/
public static function currentTime()
{
return function_exists('hrtime') ? hrtime(true) / 1e9 : microtime(true);
}
/**
* @param int $options
*
* @return UriInterface
* @throws InvalidArgumentException
*
* @internal
*/
public static function idnUriConvert(UriInterface $uri, $options = 0)
{
if ($uri->getHost()) {
$idnaVariant = defined('INTL_IDNA_VARIANT_UTS46') ? INTL_IDNA_VARIANT_UTS46 : 0;
$asciiHost = $idnaVariant === 0
? idn_to_ascii($uri->getHost(), $options)
: idn_to_ascii($uri->getHost(), $options, $idnaVariant, $info);
if ($asciiHost === false) {
$errorBitSet = isset($info['errors']) ? $info['errors'] : 0;
$errorConstants = array_filter(array_keys(get_defined_constants()), function ($name) {
return substr($name, 0, 11) === 'IDNA_ERROR_';
});
$errors = [];
foreach ($errorConstants as $errorConstant) {
if ($errorBitSet & constant($errorConstant)) {
$errors[] = $errorConstant;
}
}
$errorMessage = 'IDN conversion failed';
if ($errors) {
$errorMessage .= ' (errors: ' . implode(', ', $errors) . ')';
}
throw new InvalidArgumentException($errorMessage);
} else {
if ($uri->getHost() !== $asciiHost) {
// Replace URI only if the ASCII version is different
$uri = $uri->withHost($asciiHost);
}
}
}
return $uri;
}
}

View File

@ -56,7 +56,7 @@ function describe_type($input)
/** /**
* Parses an array of header lines into an associative array of headers. * Parses an array of header lines into an associative array of headers.
* *
* @param array $lines Header lines array of strings in the following * @param iterable $lines Header lines array of strings in the following
* format: "Name: Value" * format: "Name: Value"
* @return array * @return array
*/ */
@ -97,8 +97,8 @@ function debug_resource($value = null)
* *
* The returned handler is not wrapped by any default middlewares. * The returned handler is not wrapped by any default middlewares.
* *
* @throws \RuntimeException if no viable Handler is available.
* @return callable Returns the best handler for the given system. * @return callable Returns the best handler for the given system.
* @throws \RuntimeException if no viable Handler is available.
*/ */
function choose_handler() function choose_handler()
{ {
@ -332,15 +332,3 @@ function json_encode($value, $options = 0, $depth = 512)
return $json; return $json;
} }
/**
* Wrapper for the hrtime() or microtime() functions
* (depending on the PHP version, one of the two is used)
*
* @return float|mixed UNIX timestamp
* @internal
*/
function _current_time()
{
return function_exists('hrtime') ? hrtime(true) / 1e9 : microtime(true);
}

View File

@ -11,6 +11,8 @@
namespace Monolog\Formatter; namespace Monolog\Formatter;
use Monolog\Utils;
/** /**
* Class FluentdFormatter * Class FluentdFormatter
* *
@ -71,7 +73,7 @@ class FluentdFormatter implements FormatterInterface
$message['level_name'] = $record['level_name']; $message['level_name'] = $record['level_name'];
} }
return json_encode(array($tag, $record['datetime']->getTimestamp(), $message)); return Utils::jsonEncode(array($tag, $record['datetime']->getTimestamp(), $message));
} }
public function formatBatch(array $records) public function formatBatch(array $records)

View File

@ -11,6 +11,7 @@
namespace Monolog\Formatter; namespace Monolog\Formatter;
use Monolog\Logger; use Monolog\Logger;
use Monolog\Utils;
/** /**
* Formats incoming records into an HTML table * Formats incoming records into an HTML table
@ -133,9 +134,9 @@ class HtmlFormatter extends NormalizerFormatter
$data = $this->normalize($data); $data = $this->normalize($data);
if (version_compare(PHP_VERSION, '5.4.0', '>=')) { if (version_compare(PHP_VERSION, '5.4.0', '>=')) {
return json_encode($data, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE); return Utils::jsonEncode($data, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE, true);
} }
return str_replace('\\/', '/', json_encode($data)); return str_replace('\\/', '/', Utils::jsonEncode($data, null, true));
} }
} }

View File

@ -145,7 +145,7 @@ class JsonFormatter extends NormalizerFormatter
return 'Over 9 levels deep, aborting normalization'; return 'Over 9 levels deep, aborting normalization';
} }
if (is_array($data) || $data instanceof \Traversable) { if (is_array($data)) {
$normalized = array(); $normalized = array();
$count = 1; $count = 1;
@ -165,6 +165,10 @@ class JsonFormatter extends NormalizerFormatter
return $this->normalizeException($data); return $this->normalizeException($data);
} }
if (is_resource($data)) {
return parent::normalize($data);
}
return $data; return $data;
} }
@ -186,7 +190,7 @@ class JsonFormatter extends NormalizerFormatter
$data = array( $data = array(
'class' => Utils::getClass($e), 'class' => Utils::getClass($e),
'message' => $e->getMessage(), 'message' => $e->getMessage(),
'code' => $e->getCode(), 'code' => (int) $e->getCode(),
'file' => $e->getFile().':'.$e->getLine(), 'file' => $e->getFile().':'.$e->getLine(),
); );

View File

@ -163,7 +163,7 @@ class LineFormatter extends NormalizerFormatter
return $this->toJson($data, true); return $this->toJson($data, true);
} }
return str_replace('\\/', '/', @json_encode($data)); return str_replace('\\/', '/', $this->toJson($data, true));
} }
protected function replaceNewlines($str) protected function replaceNewlines($str)

View File

@ -87,7 +87,7 @@ class MongoDBFormatter implements FormatterInterface
$formattedException = array( $formattedException = array(
'class' => Utils::getClass($exception), 'class' => Utils::getClass($exception),
'message' => $exception->getMessage(), 'message' => $exception->getMessage(),
'code' => $exception->getCode(), 'code' => (int) $exception->getCode(),
'file' => $exception->getFile() . ':' . $exception->getLine(), 'file' => $exception->getFile() . ':' . $exception->getLine(),
); );

View File

@ -129,7 +129,7 @@ class NormalizerFormatter implements FormatterInterface
$data = array( $data = array(
'class' => Utils::getClass($e), 'class' => Utils::getClass($e),
'message' => $e->getMessage(), 'message' => $e->getMessage(),
'code' => $e->getCode(), 'code' => (int) $e->getCode(),
'file' => $e->getFile().':'.$e->getLine(), 'file' => $e->getFile().':'.$e->getLine(),
); );
@ -142,8 +142,8 @@ class NormalizerFormatter implements FormatterInterface
$data['faultactor'] = $e->faultactor; $data['faultactor'] = $e->faultactor;
} }
if (isset($e->detail)) { if (isset($e->detail) && (is_string($e->detail) || is_object($e->detail) || is_array($e->detail))) {
$data['detail'] = $e->detail; $data['detail'] = is_string($e->detail) ? $e->detail : reset($e->detail);
} }
} }
@ -171,127 +171,6 @@ class NormalizerFormatter implements FormatterInterface
*/ */
protected function toJson($data, $ignoreErrors = false) protected function toJson($data, $ignoreErrors = false)
{ {
// suppress json_encode errors since it's twitchy with some inputs return Utils::jsonEncode($data, null, $ignoreErrors);
if ($ignoreErrors) {
return @$this->jsonEncode($data);
}
$json = $this->jsonEncode($data);
if ($json === false) {
$json = $this->handleJsonError(json_last_error(), $data);
}
return $json;
}
/**
* @param mixed $data
* @return string JSON encoded data or null on failure
*/
private function jsonEncode($data)
{
if (version_compare(PHP_VERSION, '5.4.0', '>=')) {
return json_encode($data, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE);
}
return json_encode($data);
}
/**
* Handle a json_encode failure.
*
* If the failure is due to invalid string encoding, try to clean the
* input and encode again. If the second encoding attempt fails, the
* inital error is not encoding related or the input can't be cleaned then
* raise a descriptive exception.
*
* @param int $code return code of json_last_error function
* @param mixed $data data that was meant to be encoded
* @throws \RuntimeException if failure can't be corrected
* @return string JSON encoded data after error correction
*/
private function handleJsonError($code, $data)
{
if ($code !== JSON_ERROR_UTF8) {
$this->throwEncodeError($code, $data);
}
if (is_string($data)) {
$this->detectAndCleanUtf8($data);
} elseif (is_array($data)) {
array_walk_recursive($data, array($this, 'detectAndCleanUtf8'));
} else {
$this->throwEncodeError($code, $data);
}
$json = $this->jsonEncode($data);
if ($json === false) {
$this->throwEncodeError(json_last_error(), $data);
}
return $json;
}
/**
* Throws an exception according to a given code with a customized message
*
* @param int $code return code of json_last_error function
* @param mixed $data data that was meant to be encoded
* @throws \RuntimeException
*/
private function throwEncodeError($code, $data)
{
switch ($code) {
case JSON_ERROR_DEPTH:
$msg = 'Maximum stack depth exceeded';
break;
case JSON_ERROR_STATE_MISMATCH:
$msg = 'Underflow or the modes mismatch';
break;
case JSON_ERROR_CTRL_CHAR:
$msg = 'Unexpected control character found';
break;
case JSON_ERROR_UTF8:
$msg = 'Malformed UTF-8 characters, possibly incorrectly encoded';
break;
default:
$msg = 'Unknown error';
}
throw new \RuntimeException('JSON encoding failed: '.$msg.'. Encoding: '.var_export($data, true));
}
/**
* Detect invalid UTF-8 string characters and convert to valid UTF-8.
*
* Valid UTF-8 input will be left unmodified, but strings containing
* invalid UTF-8 codepoints will be reencoded as UTF-8 with an assumed
* original encoding of ISO-8859-15. This conversion may result in
* incorrect output if the actual encoding was not ISO-8859-15, but it
* will be clean UTF-8 output and will not rely on expensive and fragile
* detection algorithms.
*
* Function converts the input in place in the passed variable so that it
* can be used as a callback for array_walk_recursive.
*
* @param mixed &$data Input to check and convert if needed
* @private
*/
public function detectAndCleanUtf8(&$data)
{
if (is_string($data) && !preg_match('//u', $data)) {
$data = preg_replace_callback(
'/[\x80-\xFF]+/',
function ($m) { return utf8_encode($m[0]); },
$data
);
$data = str_replace(
array('¤', '¦', '¨', '´', '¸', '¼', '½', '¾'),
array('€', 'Š', 'š', 'Ž', 'ž', 'Œ', 'œ', 'Ÿ'),
$data
);
}
} }
} }

Some files were not shown because too many files have changed in this diff Show More