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 || {};
WPMailSMTP.Admin = WPMailSMTP.Admin || {};
@ -8,25 +10,14 @@ WPMailSMTP.Admin = WPMailSMTP.Admin || {};
*
* @since 1.5.0
*/
WPMailSMTP.Admin.About = WPMailSMTP.Admin.About || (function ( document, window, $ ) {
'use strict';
/**
* Private functions and properties.
*
* @since 1.5.0
*
* @type {Object}
*/
var __private = {};
WPMailSMTP.Admin.About = WPMailSMTP.Admin.About || ( function( document, window, $ ) {
/**
* Public functions and properties.
*
* @since 1.5.0
*
* @type {Object}
* @type {object}
*/
var app = {
@ -35,7 +26,7 @@ WPMailSMTP.Admin.About = WPMailSMTP.Admin.About || (function ( document, window,
*
* @since 1.5.0
*/
init: function () {
init: function() {
// Do that when DOM is ready.
$( document ).ready( app.ready );
@ -46,7 +37,7 @@ WPMailSMTP.Admin.About = WPMailSMTP.Admin.About || (function ( document, window,
*
* @since 1.5.0
*/
ready: function () {
ready: function() {
app.pageHolder = $( '.wp-mail-smtp-page-about' );
@ -60,12 +51,12 @@ WPMailSMTP.Admin.About = WPMailSMTP.Admin.About || (function ( document, window,
*
* @since 1.5.0
*/
bindActions: function () {
bindActions: function() {
/*
* 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.
@ -85,27 +76,26 @@ WPMailSMTP.Admin.About = WPMailSMTP.Admin.About || (function ( document, window,
cssClass,
statusText,
buttonText,
errorText,
successText;
$btn.addClass( 'loading disabled' );
$btn.text( wp_mail_smtp_about.plugin_processing );
if ( $btn.hasClass( 'status-inactive' ) ) {
// Activate.
task = 'about_plugin_activate';
cssClass = 'status-active button button-secondary disabled';
statusText = wp_mail_smtp_about.plugin_active;
buttonText = wp_mail_smtp_about.plugin_activated;
errorText = wp_mail_smtp_about.plugin_activate;
} else if ( $btn.hasClass( 'status-download' ) ) {
// Install & Activate.
task = 'about_plugin_install';
cssClass = 'status-active button disabled';
statusText = wp_mail_smtp_about.plugin_active;
buttonText = wp_mail_smtp_about.plugin_activated;
errorText = wp_mail_smtp_about.plugin_activate;
} else {
return;
@ -120,10 +110,10 @@ WPMailSMTP.Admin.About = WPMailSMTP.Admin.About || (function ( document, window,
};
$.post( wp_mail_smtp_about.ajax_url, data, function( res ) {
var is_install_successful;
var isInstallSuccessful;
if ( res.success ) {
is_install_successful = true;
isInstallSuccessful = true;
if ( 'about_plugin_install' === task ) {
$btn.attr( 'data-plugin', res.data.basename );
successText = res.data.msg;
@ -135,18 +125,18 @@ WPMailSMTP.Admin.About = WPMailSMTP.Admin.About || (function ( document, window,
} else {
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' )
.removeClass( 'status-active status-inactive status-download' )
.addClass( cssClass )
.removeClass( 'button button-primary button-secondary disabled' )
.text( statusText );
.removeClass( 'status-active status-inactive status-download' )
.addClass( cssClass )
.removeClass( 'button button-primary button-secondary disabled' )
.text( statusText );
$btn
.removeClass( 'status-active status-inactive status-download' )
.removeClass( 'button button-primary button-secondary disabled' )
.addClass( cssClass ).html( buttonText );
} else {
is_install_successful = false;
isInstallSuccessful = false;
if (
res.hasOwnProperty( 'data' ) &&
@ -154,10 +144,11 @@ WPMailSMTP.Admin.About = WPMailSMTP.Admin.About || (function ( document, window,
res.data[ 0 ].hasOwnProperty( 'code' ) &&
res.data[ 0 ].code === 'download_failed'
) {
// Specific server-returned error.
$plugin.find( '.actions' ).append( '<div class="msg error">' + wp_mail_smtp_about.plugin_install_error + '</div>' );
}
else {
} else {
// Generic error.
$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 );
}
if ( ! is_install_successful ) {
if ( ! isInstallSuccessful ) {
$btn.removeClass( 'disabled' );
}
$btn.removeClass( 'loading' );
// Automatically clear plugin messages after 3 seconds.
setTimeout( function () {
setTimeout( function() {
$( '.plugin-item .msg' ).remove();
}, 3000 );
}).fail( function( xhr ) {
} ).fail( function( xhr ) {
console.log( xhr.responseText );
});
});
} );
} );
}
};
// Provide access to public functions/properties.
return app;
})( document, window, jQuery );
}( document, window, jQuery ) );
// Initialize.
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 || {};
WPMailSMTP.Admin = WPMailSMTP.Admin || {};
@ -7,32 +9,22 @@ WPMailSMTP.Admin = WPMailSMTP.Admin || {};
*
* @since 1.6.0
*/
WPMailSMTP.Admin.Settings = WPMailSMTP.Admin.Settings || (function ( document, window, $ ) {
'use strict';
/**
* Private functions and properties.
*
* @since 1.6.0
*
* @type {Object}
*/
var __private = {};
WPMailSMTP.Admin.Settings = WPMailSMTP.Admin.Settings || ( function( document, window, $ ) {
/**
* Public functions and properties.
*
* @since 1.6.0
*
* @type {Object}
* @type {object}
*/
var app = {
/**
* State attribute showing if one of the plugin settings
* changed and was not yet saved.
*
* @since {VERSION}
* @since 1.9.0
*
* @type {boolean}
*/
@ -43,7 +35,7 @@ WPMailSMTP.Admin.Settings = WPMailSMTP.Admin.Settings || (function ( document, w
*
* @since 1.6.0
*/
init: function () {
init: function() {
// Do that when DOM is ready.
$( document ).ready( app.ready );
@ -54,7 +46,7 @@ WPMailSMTP.Admin.Settings = WPMailSMTP.Admin.Settings || (function ( document, w
*
* @since 1.6.0
*/
ready: function () {
ready: function() {
app.pageHolder = $( '.wp-mail-smtp-tab-settings' );
@ -69,17 +61,18 @@ WPMailSMTP.Admin.Settings = WPMailSMTP.Admin.Settings || (function ( document, w
*
* @since 1.6.0
*/
bindActions: function () {
bindActions: function() {
// 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' );
} );
$( '.wp-mail-smtp-mailer input', app.pageHolder ).click( function () {
$( '.wp-mail-smtp-mailer input', app.pageHolder ).click( function() {
var $input = $( this );
if ( $input.prop( 'disabled' ) ) {
// Educational Popup.
if ( $input.hasClass( 'educate' ) ) {
app.education.upgradeMailer( $input );
@ -90,6 +83,7 @@ WPMailSMTP.Admin.Settings = WPMailSMTP.Admin.Settings || (function ( document, w
// Deselect the current mailer.
$( '.wp-mail-smtp-mailer', app.pageHolder ).removeClass( 'active' );
// Select the correct one.
$( 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();
// 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( {
url: ajaxurl,
dataType: 'json',
type: 'POST',
data: {
action: 'wp_mail_smtp_ajax',
task: 'pro_banner_dismiss'
}
} )
.always( function () {
$( '#wp-mail-smtp-pro-banner', app.pageHolder ).fadeOut( 'fast' );
} );
url: ajaxurl,
dataType: 'json',
type: 'POST',
data: {
action: 'wp_mail_smtp_ajax',
task: 'pro_banner_dismiss'
}
} )
.always( function() {
$( '#wp-mail-smtp-pro-banner', app.pageHolder ).fadeOut( 'fast' );
} );
} );
// Dismis educational notices for certain mailers.
$( '.js-wp-mail-smtp-mailer-notice-dismiss', app.pageHolder ).on( 'click', function ( e ) {
// Dissmis educational notices for certain mailers.
$( '.js-wp-mail-smtp-mailer-notice-dismiss', app.pageHolder ).on( 'click', function( e ) {
e.preventDefault();
var $btn = $( this ),
@ -128,28 +122,28 @@ WPMailSMTP.Admin.Settings = WPMailSMTP.Admin.Settings || (function ( document, w
}
$.ajax( {
url: ajaxurl,
dataType: 'json',
type: 'POST',
data: {
action: 'wp_mail_smtp_ajax',
task: 'notice_dismiss',
notice: $notice.data( 'notice' ),
mailer: $notice.data( 'mailer' )
},
beforeSend: function () {
$btn.addClass( 'disabled' );
}
} )
.always( function () {
$notice.fadeOut( 'fast', function () {
$btn.removeClass( 'disabled' );
} );
} );
url: ajaxurl,
dataType: 'json',
type: 'POST',
data: {
action: 'wp_mail_smtp_ajax',
task: 'notice_dismiss',
notice: $notice.data( 'notice' ),
mailer: $notice.data( 'mailer' )
},
beforeSend: function() {
$btn.addClass( 'disabled' );
}
} )
.always( function() {
$notice.fadeOut( 'fast', function() {
$btn.removeClass( 'disabled' );
} );
} );
} );
// 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();
$( '#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.
$( '.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 );
} );
// 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();
var target = $( '#' + $( this ).data( 'source_id' ) ).get( 0 );
@ -177,7 +171,7 @@ WPMailSMTP.Admin.Settings = WPMailSMTP.Admin.Settings || (function ( document, w
},
education: {
upgradeMailer: function ( $input ) {
upgradeMailer: function( $input ) {
$.alert( {
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="',
content: $( '.wp-mail-smtp-mailer-options .wp-mail-smtp-mailer-option-' + $input.val() + ' .wp-mail-smtp-setting-field' ).html(),
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>' );
},
buttons: {
@ -200,7 +194,7 @@ WPMailSMTP.Admin.Settings = WPMailSMTP.Admin.Settings || (function ( document, w
text: wp_mail_smtp.education.upgrade_button,
btnClass: 'btn-confirm',
keys: [ 'enter' ],
action: function () {
action: function() {
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: {
smtp: {
bindActions: function () {
bindActions: function() {
// 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' );
} );
// 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 ),
$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() ) {
$smtpPort.val( '587' );
$( '#wp-mail-smtp-setting-row-smtp-autotls' ).addClass( 'inactive' );
}
else if ( 'ssl' === $input.val() ) {
} else if ( 'ssl' === $input.val() ) {
$smtpPort.val( '465' );
$( '#wp-mail-smtp-setting-row-smtp-autotls' ).removeClass( 'inactive' );
}
else {
} else {
$smtpPort.val( '25' );
$( '#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.
*
* @since {VERSION}
* @since 1.9.0
*/
triggerExitNotice: function () {
triggerExitNotice: function() {
var $settingPages = $( '.wp-mail-smtp-page-general:not( .wp-mail-smtp-tab-test )' );
// Display an exit notice, if settings are not saved.
$( window ).on( 'beforeunload', function () {
$( window ).on( 'beforeunload', function() {
if ( app.pluginSettingsChanged ) {
return wp_mail_smtp.text_settings_not_saved;
}
} );
// 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;
} );
// 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;
} );
}
@ -276,7 +268,7 @@ WPMailSMTP.Admin.Settings = WPMailSMTP.Admin.Settings || (function ( document, w
// Provide access to public functions/properties.
return app;
})( document, window, jQuery );
}( document, window, jQuery ) );
// Initialize.
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
* http://brm.io/jquery-match-height/
* License: MIT
*/
;(function(factory) { // eslint-disable-line no-extra-semi
'use strict';
if (typeof define === 'function' && define.amd) {
// AMD
define(['jquery'], factory);
} else if (typeof module !== 'undefined' && module.exports) {
// CommonJS
module.exports = factory(require('jquery'));
} else {
// Global
factory(jQuery);
}
})(function($) {
/*
* internal
*/
var _previousResizeWidth = -1,
_updateTimeout = -1;
/*
* _parse
* value parse utility function
*/
var _parse = function(value) {
// parse value and convert NaN to 0
return parseFloat(value) || 0;
};
/*
* _rows
* utility function returns array of jQuery selections representing each row
* (as displayed after float wrapping applied by browser)
*/
var _rows = function(elements) {
var tolerance = 1,
$elements = $(elements),
lastTop = null,
rows = [];
// group elements by their top position
$elements.each(function(){
var $that = $(this),
top = $that.offset().top - _parse($that.css('margin-top')),
lastRow = rows.length > 0 ? rows[rows.length - 1] : null;
if (lastRow === null) {
// first item on the row, so just push it
rows.push($that);
} else {
// if the row top is the same, add to the row group
if (Math.floor(Math.abs(lastTop - top)) <= tolerance) {
rows[rows.length - 1] = lastRow.add($that);
} else {
// otherwise start a new row group
rows.push($that);
}
}
// keep track of the last row top
lastTop = top;
});
return rows;
};
/*
* _parseOptions
* handle plugin options
*/
var _parseOptions = function(options) {
var opts = {
byRow: true,
property: 'height',
target: null,
remove: false
};
if (typeof options === 'object') {
return $.extend(opts, options);
}
if (typeof options === 'boolean') {
opts.byRow = options;
} else if (options === 'remove') {
opts.remove = true;
}
return opts;
};
/*
* matchHeight
* plugin definition
*/
var matchHeight = $.fn.matchHeight = function(options) {
var opts = _parseOptions(options);
// handle remove
if (opts.remove) {
var that = this;
// remove fixed height from all selected elements
this.css(opts.property, '');
// remove selected elements from all groups
$.each(matchHeight._groups, function(key, group) {
group.elements = group.elements.not(that);
});
// TODO: cleanup empty groups
return this;
}
if (this.length <= 1 && !opts.target) {
return this;
}
// keep track of this group so we can re-apply later on load and resize events
matchHeight._groups.push({
elements: this,
options: opts
});
// match each element's height to the tallest element in the selection
matchHeight._apply(this, opts);
return this;
};
/*
* plugin global options
*/
matchHeight.version = '0.7.2';
matchHeight._groups = [];
matchHeight._throttle = 80;
matchHeight._maintainScroll = false;
matchHeight._beforeUpdate = null;
matchHeight._afterUpdate = null;
matchHeight._rows = _rows;
matchHeight._parse = _parse;
matchHeight._parseOptions = _parseOptions;
/*
* matchHeight._apply
* apply matchHeight to given elements
*/
matchHeight._apply = function(elements, options) {
var opts = _parseOptions(options),
$elements = $(elements),
rows = [$elements];
// take note of scroll position
var scrollTop = $(window).scrollTop(),
htmlHeight = $('html').outerHeight(true);
// get hidden parents
var $hiddenParents = $elements.parents().filter(':hidden');
// cache the original inline style
$hiddenParents.each(function() {
var $that = $(this);
$that.data('style-cache', $that.attr('style'));
});
// temporarily must force hidden parents visible
$hiddenParents.css('display', 'block');
// get rows if using byRow, otherwise assume one row
if (opts.byRow && !opts.target) {
// must first force an arbitrary equal height so floating elements break evenly
$elements.each(function() {
var $that = $(this),
display = $that.css('display');
// temporarily force a usable display value
if (display !== 'inline-block' && display !== 'flex' && display !== 'inline-flex') {
display = 'block';
}
// cache the original inline style
$that.data('style-cache', $that.attr('style'));
$that.css({
'display': display,
'padding-top': '0',
'padding-bottom': '0',
'margin-top': '0',
'margin-bottom': '0',
'border-top-width': '0',
'border-bottom-width': '0',
'height': '100px',
'overflow': 'hidden'
});
});
// get the array of rows (based on element top position)
rows = _rows($elements);
// revert original inline styles
$elements.each(function() {
var $that = $(this);
$that.attr('style', $that.data('style-cache') || '');
});
}
$.each(rows, function(key, row) {
var $row = $(row),
targetHeight = 0;
if (!opts.target) {
// skip apply to rows with only one item
if (opts.byRow && $row.length <= 1) {
$row.css(opts.property, '');
return;
}
// iterate the row and find the max height
$row.each(function(){
var $that = $(this),
style = $that.attr('style'),
display = $that.css('display');
// temporarily force a usable display value
if (display !== 'inline-block' && display !== 'flex' && display !== 'inline-flex') {
display = 'block';
}
// ensure we get the correct actual height (and not a previously set height value)
var css = { 'display': display };
css[opts.property] = '';
$that.css(css);
// find the max height (including padding, but not margin)
if ($that.outerHeight(false) > targetHeight) {
targetHeight = $that.outerHeight(false);
}
// revert styles
if (style) {
$that.attr('style', style);
} else {
$that.css('display', '');
}
});
} else {
// if target set, use the height of the target element
targetHeight = opts.target.outerHeight(false);
}
// iterate the row and apply the height to all elements
$row.each(function(){
var $that = $(this),
verticalPadding = 0;
// don't apply to a target
if (opts.target && $that.is(opts.target)) {
return;
}
// handle padding and border correctly (required when not using 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('padding-top')) + _parse($that.css('padding-bottom'));
}
// set the height (accounting for padding and border)
$that.css(opts.property, (targetHeight - verticalPadding) + 'px');
});
});
// revert hidden parents
$hiddenParents.each(function() {
var $that = $(this);
$that.attr('style', $that.data('style-cache') || null);
});
// restore scroll position if enabled
if (matchHeight._maintainScroll) {
$(window).scrollTop((scrollTop / htmlHeight) * $('html').outerHeight(true));
}
return this;
};
/*
* matchHeight._applyDataApi
* applies matchHeight to all elements with a data-match-height attribute
*/
matchHeight._applyDataApi = function() {
var groups = {};
// generate groups by their groupId set by elements using data-match-height
$('[data-match-height], [data-mh]').each(function() {
var $this = $(this),
groupId = $this.attr('data-mh') || $this.attr('data-match-height');
if (groupId in groups) {
groups[groupId] = groups[groupId].add($this);
} else {
groups[groupId] = $this;
}
});
// apply matchHeight to each group
$.each(groups, function() {
this.matchHeight(true);
});
};
/*
* matchHeight._update
* updates matchHeight on all current groups with their correct options
*/
var _update = function(event) {
if (matchHeight._beforeUpdate) {
matchHeight._beforeUpdate(event, matchHeight._groups);
}
$.each(matchHeight._groups, function() {
matchHeight._apply(this.elements, this.options);
});
if (matchHeight._afterUpdate) {
matchHeight._afterUpdate(event, matchHeight._groups);
}
};
matchHeight._update = function(throttle, event) {
// prevent update if fired from a resize event
// where the viewport width hasn't actually changed
// fixes an event looping bug in IE8
if (event && event.type === 'resize') {
var windowWidth = $(window).width();
if (windowWidth === _previousResizeWidth) {
return;
}
_previousResizeWidth = windowWidth;
}
// throttle updates
if (!throttle) {
_update(event);
} else if (_updateTimeout === -1) {
_updateTimeout = setTimeout(function() {
_update(event);
_updateTimeout = -1;
}, matchHeight._throttle);
}
};
/*
* bind events
*/
// apply on DOM ready event
$(matchHeight._applyDataApi);
// use on or bind where supported
var on = $.fn.on ? 'on' : 'bind';
// update heights on load and resize events
$(window)[on]('load', function(event) {
matchHeight._update(false, event);
});
// throttled update heights on resize events
$(window)[on]('resize orientationchange', function(event) {
matchHeight._update(true, event);
});
});
/**
* jquery-match-height 0.7.2 by @liabru
* http://brm.io/jquery-match-height/
* License: MIT
*/
;(function(factory) { // eslint-disable-line no-extra-semi
'use strict';
if (typeof define === 'function' && define.amd) {
// AMD
define(['jquery'], factory);
} else if (typeof module !== 'undefined' && module.exports) {
// CommonJS
module.exports = factory(require('jquery'));
} else {
// Global
factory(jQuery);
}
})(function($) {
/*
* internal
*/
var _previousResizeWidth = -1,
_updateTimeout = -1;
/*
* _parse
* value parse utility function
*/
var _parse = function(value) {
// parse value and convert NaN to 0
return parseFloat(value) || 0;
};
/*
* _rows
* utility function returns array of jQuery selections representing each row
* (as displayed after float wrapping applied by browser)
*/
var _rows = function(elements) {
var tolerance = 1,
$elements = $(elements),
lastTop = null,
rows = [];
// group elements by their top position
$elements.each(function(){
var $that = $(this),
top = $that.offset().top - _parse($that.css('margin-top')),
lastRow = rows.length > 0 ? rows[rows.length - 1] : null;
if (lastRow === null) {
// first item on the row, so just push it
rows.push($that);
} else {
// if the row top is the same, add to the row group
if (Math.floor(Math.abs(lastTop - top)) <= tolerance) {
rows[rows.length - 1] = lastRow.add($that);
} else {
// otherwise start a new row group
rows.push($that);
}
}
// keep track of the last row top
lastTop = top;
});
return rows;
};
/*
* _parseOptions
* handle plugin options
*/
var _parseOptions = function(options) {
var opts = {
byRow: true,
property: 'height',
target: null,
remove: false
};
if (typeof options === 'object') {
return $.extend(opts, options);
}
if (typeof options === 'boolean') {
opts.byRow = options;
} else if (options === 'remove') {
opts.remove = true;
}
return opts;
};
/*
* matchHeight
* plugin definition
*/
var matchHeight = $.fn.matchHeight = function(options) {
var opts = _parseOptions(options);
// handle remove
if (opts.remove) {
var that = this;
// remove fixed height from all selected elements
this.css(opts.property, '');
// remove selected elements from all groups
$.each(matchHeight._groups, function(key, group) {
group.elements = group.elements.not(that);
});
// TODO: cleanup empty groups
return this;
}
if (this.length <= 1 && !opts.target) {
return this;
}
// keep track of this group so we can re-apply later on load and resize events
matchHeight._groups.push({
elements: this,
options: opts
});
// match each element's height to the tallest element in the selection
matchHeight._apply(this, opts);
return this;
};
/*
* plugin global options
*/
matchHeight.version = '0.7.2';
matchHeight._groups = [];
matchHeight._throttle = 80;
matchHeight._maintainScroll = false;
matchHeight._beforeUpdate = null;
matchHeight._afterUpdate = null;
matchHeight._rows = _rows;
matchHeight._parse = _parse;
matchHeight._parseOptions = _parseOptions;
/*
* matchHeight._apply
* apply matchHeight to given elements
*/
matchHeight._apply = function(elements, options) {
var opts = _parseOptions(options),
$elements = $(elements),
rows = [$elements];
// take note of scroll position
var scrollTop = $(window).scrollTop(),
htmlHeight = $('html').outerHeight(true);
// get hidden parents
var $hiddenParents = $elements.parents().filter(':hidden');
// cache the original inline style
$hiddenParents.each(function() {
var $that = $(this);
$that.data('style-cache', $that.attr('style'));
});
// temporarily must force hidden parents visible
$hiddenParents.css('display', 'block');
// get rows if using byRow, otherwise assume one row
if (opts.byRow && !opts.target) {
// must first force an arbitrary equal height so floating elements break evenly
$elements.each(function() {
var $that = $(this),
display = $that.css('display');
// temporarily force a usable display value
if (display !== 'inline-block' && display !== 'flex' && display !== 'inline-flex') {
display = 'block';
}
// cache the original inline style
$that.data('style-cache', $that.attr('style'));
$that.css({
'display': display,
'padding-top': '0',
'padding-bottom': '0',
'margin-top': '0',
'margin-bottom': '0',
'border-top-width': '0',
'border-bottom-width': '0',
'height': '100px',
'overflow': 'hidden'
});
});
// get the array of rows (based on element top position)
rows = _rows($elements);
// revert original inline styles
$elements.each(function() {
var $that = $(this);
$that.attr('style', $that.data('style-cache') || '');
});
}
$.each(rows, function(key, row) {
var $row = $(row),
targetHeight = 0;
if (!opts.target) {
// skip apply to rows with only one item
if (opts.byRow && $row.length <= 1) {
$row.css(opts.property, '');
return;
}
// iterate the row and find the max height
$row.each(function(){
var $that = $(this),
style = $that.attr('style'),
display = $that.css('display');
// temporarily force a usable display value
if (display !== 'inline-block' && display !== 'flex' && display !== 'inline-flex') {
display = 'block';
}
// ensure we get the correct actual height (and not a previously set height value)
var css = { 'display': display };
css[opts.property] = '';
$that.css(css);
// find the max height (including padding, but not margin)
if ($that.outerHeight(false) > targetHeight) {
targetHeight = $that.outerHeight(false);
}
// revert styles
if (style) {
$that.attr('style', style);
} else {
$that.css('display', '');
}
});
} else {
// if target set, use the height of the target element
targetHeight = opts.target.outerHeight(false);
}
// iterate the row and apply the height to all elements
$row.each(function(){
var $that = $(this),
verticalPadding = 0;
// don't apply to a target
if (opts.target && $that.is(opts.target)) {
return;
}
// handle padding and border correctly (required when not using 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('padding-top')) + _parse($that.css('padding-bottom'));
}
// set the height (accounting for padding and border)
$that.css(opts.property, (targetHeight - verticalPadding) + 'px');
});
});
// revert hidden parents
$hiddenParents.each(function() {
var $that = $(this);
$that.attr('style', $that.data('style-cache') || null);
});
// restore scroll position if enabled
if (matchHeight._maintainScroll) {
$(window).scrollTop((scrollTop / htmlHeight) * $('html').outerHeight(true));
}
return this;
};
/*
* matchHeight._applyDataApi
* applies matchHeight to all elements with a data-match-height attribute
*/
matchHeight._applyDataApi = function() {
var groups = {};
// generate groups by their groupId set by elements using data-match-height
$('[data-match-height], [data-mh]').each(function() {
var $this = $(this),
groupId = $this.attr('data-mh') || $this.attr('data-match-height');
if (groupId in groups) {
groups[groupId] = groups[groupId].add($this);
} else {
groups[groupId] = $this;
}
});
// apply matchHeight to each group
$.each(groups, function() {
this.matchHeight(true);
});
};
/*
* matchHeight._update
* updates matchHeight on all current groups with their correct options
*/
var _update = function(event) {
if (matchHeight._beforeUpdate) {
matchHeight._beforeUpdate(event, matchHeight._groups);
}
$.each(matchHeight._groups, function() {
matchHeight._apply(this.elements, this.options);
});
if (matchHeight._afterUpdate) {
matchHeight._afterUpdate(event, matchHeight._groups);
}
};
matchHeight._update = function(throttle, event) {
// prevent update if fired from a resize event
// where the viewport width hasn't actually changed
// fixes an event looping bug in IE8
if (event && event.type === 'resize') {
var windowWidth = $(window).width();
if (windowWidth === _previousResizeWidth) {
return;
}
_previousResizeWidth = windowWidth;
}
// throttle updates
if (!throttle) {
_update(event);
} else if (_updateTimeout === -1) {
_updateTimeout = setTimeout(function() {
_update(event);
_updateTimeout = -1;
}, matchHeight._throttle);
}
};
/*
* bind events
*/
// apply on DOM ready event
$(matchHeight._applyDataApi);
// use on or bind where supported
var on = $.fn.on ? 'on' : 'bind';
// update heights on load and resize events
$(window)[on]('load', function(event) {
matchHeight._update(false, event);
});
// throttled update heights on resize events
$(window)[on]('resize orientationchange', function(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 ""
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"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\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"
"X-Generator: WP-CLI 2.4.0\n"
"X-Domain: wp-mail-smtp\n"
@ -61,106 +61,115 @@ msgstr ""
#: src/Admin/Area.php:197
#: src/Admin/Area.php:198
#: src/SiteHealth.php:40
#: wp-mail-smtp-0.11.2.php:582
msgid "WP Mail SMTP"
msgstr ""
#: src/Admin/Area.php:208
#: src/Admin/Area.php:209
#: src/Admin/Area.php:795
#: wp-mail-smtp-0.11.2.php:688
#: src/Admin/Area.php:802
msgid "Settings"
msgstr ""
#: src/Admin/Area.php:216
#: src/Admin/Area.php:217
#: src/Admin/Area.php:796
#: src/Admin/Pages/About.php:627
#: src/Admin/Pages/Logs.php:40
#: src/Admin/Pages/LogsTab.php:31
msgid "Email Log"
msgstr ""
#: src/Admin/Area.php:224
#: src/Admin/Area.php:225
#: src/Admin/Area.php:226
#: src/Admin/Area.php:227
#: src/Admin/Pages/About.php:105
msgid "About Us"
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."
msgstr ""
#: src/Admin/Area.php:268
#: src/Admin/Area.php:271
msgid "Changes that you made to the settings are not saved!"
msgstr ""
#: src/Admin/Area.php:271
#: src/Admin/Area.php:274
msgid "%name% is a PRO Feature"
msgstr ""
#: src/Admin/Area.php:272
#: src/Admin/Area.php:275
msgid "Upgrade to Pro"
msgstr ""
#: src/Admin/Area.php:276
msgid "<strong>Bonus:</strong> WP Mail SMTP users get <span>20% off</span> regular price,<br>applied at checkout."
#: src/Admin/Area.php:279
msgid "<strong>Bonus:</strong> WP Mail SMTP users get <span>$50 off</span> regular price,<br>applied at checkout."
msgstr ""
#: src/Admin/Area.php:285
#: src/Admin/Area.php:288
msgid "Already purchased?"
msgstr ""
#: src/Admin/Area.php:352
#: src/Admin/Area.php:359
#: src/Admin/Area.php:355
#: src/Admin/Area.php:362
#: src/Admin/Pages/About.php:308
msgid "Activate"
msgstr ""
#: src/Admin/Area.php:353
#: src/Admin/Area.php:356
#: src/Admin/Pages/About.php:300
msgid "Activated"
msgstr ""
#: src/Admin/Area.php:354
#: src/Admin/Area.php:357
#: src/Admin/Pages/About.php:297
msgid "Active"
msgstr ""
#: src/Admin/Area.php:355
#: src/Admin/Area.php:358
#: src/Admin/Pages/About.php:305
msgid "Inactive"
msgstr ""
#: src/Admin/Area.php:356
#: src/Admin/Area.php:359
msgid "Processing..."
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."
msgstr ""
#: src/Admin/Area.php:358
#: src/Admin/Area.php:361
msgid "Install and Activate"
msgstr ""
#: src/Admin/Area.php:360
#: src/Admin/Area.php:363
msgid "Download"
msgstr ""
#. 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!"
msgstr ""
#: src/Admin/Area.php:740
#: src/Admin/Area.php:743
msgid "WP Mail SMTP Pro related message was successfully dismissed."
msgstr ""
#: src/Admin/Area.php:759
#: src/Admin/Area.php:762
msgid "Educational notice for this mailer was successfully dismissed."
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
msgid "Save Settings"
msgstr ""
@ -297,7 +306,7 @@ msgid "Get WP Mail SMTP Pro Today and Unlock all of these Powerful Features"
msgstr ""
#: 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 ""
#: src/Admin/Pages/About.php:628
@ -451,7 +460,6 @@ msgid "Test emails are allowed to be sent, regardless of this option."
msgstr ""
#. 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/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."
@ -496,7 +504,7 @@ msgid "Check this if you would like to remove ALL WP Mail SMTP data upon plugin
msgstr ""
#: src/Admin/Pages/MiscTab.php:215
#: src/Admin/Pages/SettingsTab.php:542
#: src/Admin/Pages/SettingsTab.php:540
msgid "Settings were successfully saved."
msgstr ""
@ -521,7 +529,6 @@ msgid "Mail"
msgstr ""
#: src/Admin/Pages/SettingsTab.php:92
#: wp-mail-smtp-0.11.2.php:246
msgid "From Email"
msgstr ""
@ -550,7 +557,6 @@ msgid "If checked, the From Email setting above will be used for all emails, ign
msgstr ""
#: src/Admin/Pages/SettingsTab.php:138
#: wp-mail-smtp-0.11.2.php:265
msgid "From Name"
msgstr ""
@ -571,18 +577,14 @@ msgid "If checked, the From Name setting above will be used for all emails, igno
msgstr ""
#: 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"
msgstr ""
#: src/Admin/Pages/SettingsTab.php:188
#: wp-mail-smtp-0.11.2.php:331
msgid "Set the return-path to match the From Email"
msgstr ""
#: 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."
msgstr ""
@ -591,104 +593,105 @@ msgid "If unchecked, bounce messages may be lost. Some providers may ignore this
msgstr ""
#: src/Admin/Pages/SettingsTab.php:201
#: wp-mail-smtp-0.11.2.php:280
#: wp-mail-smtp-0.11.2.php:285
msgid "Mailer"
msgstr ""
#: src/Admin/Pages/SettingsTab.php:241
#: src/Admin/Pages/SettingsTab.php:245
#: src/Admin/Pages/SettingsTab.php:242
msgid "Don't see what you're looking for?"
msgstr ""
#: src/Admin/Pages/SettingsTab.php:244
msgid "Suggest a Mailer"
msgstr ""
#: src/Admin/Pages/SettingsTab.php:274
#: src/Admin/Pages/SettingsTab.php:272
msgid "Dismiss this notice"
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!"
msgstr ""
#. 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>."
msgstr ""
#: src/Admin/Pages/SettingsTab.php:341
msgid "As a valued WP Mail SMTP Lite user you receive <strong>20% off</strong>, automatically applied at checkout!"
#: src/Admin/Pages/SettingsTab.php:339
msgid "As a valued WP Mail SMTP Lite user you receive <strong>$50 off</strong>, automatically applied at checkout!"
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"
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."
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."
msgstr ""
#: src/Admin/Pages/SettingsTab.php:413
#: src/Admin/Pages/SettingsTab.php:411
msgid "Pro Features:"
msgstr ""
#: src/Admin/Pages/SettingsTab.php:417
#: src/Admin/Pages/SettingsTab.php:415
msgid "Manage Notifications - control which emails your site sends"
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"
msgstr ""
#: src/Admin/Pages/SettingsTab.php:419
#: src/Admin/Pages/SettingsTab.php:417
msgid "Office 365 - send emails using your Office 365 account"
msgstr ""
#: src/Admin/Pages/SettingsTab.php:420
#: src/Admin/Pages/SettingsTab.php:418
msgid "Amazon SES - harness the power of AWS"
msgstr ""
#: src/Admin/Pages/SettingsTab.php:421
#: src/Admin/Pages/SettingsTab.php:419
msgid "Outlook.com - send emails using your Outlook.com account"
msgstr ""
#: src/Admin/Pages/SettingsTab.php:422
#: src/Admin/Pages/SettingsTab.php:420
msgid "Access to our world class support team"
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"
msgstr ""
#: src/Admin/Pages/SettingsTab.php:426
#: src/Admin/Pages/SettingsTab.php:424
msgid "Install WP Mail SMTP Pro plugin"
msgstr ""
#: src/Admin/Pages/SettingsTab.php:427
#: src/Admin/Pages/SettingsTab.php:425
msgid "Set up domain name verification (DNS)"
msgstr ""
#: src/Admin/Pages/SettingsTab.php:428
#: src/Admin/Pages/SettingsTab.php:426
msgid "Configure Mailgun service"
msgstr ""
#: src/Admin/Pages/SettingsTab.php:429
#: src/Admin/Pages/SettingsTab.php:427
msgid "Set up WP Mail SMTP Pro plugin"
msgstr ""
#: src/Admin/Pages/SettingsTab.php:430
#: src/Admin/Pages/SettingsTab.php:428
msgid "Test and verify email delivery"
msgstr ""
#. 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>"
msgstr ""
#: src/Admin/Pages/SettingsTab.php:456
msgid "<strong>Bonus:</strong> WP Mail SMTP users get <span class=\"price-off\">20% off regular price</span>, automatically applied at checkout."
#: src/Admin/Pages/SettingsTab.php:454
msgid "<strong>Bonus:</strong> WP Mail SMTP users get <span class=\"price-off\">$50 off regular price</span>, automatically applied at checkout."
msgstr ""
#: src/Admin/Pages/TestTab.php:37
@ -696,7 +699,6 @@ msgid "Email Test"
msgstr ""
#: src/Admin/Pages/TestTab.php:59
#: wp-mail-smtp-0.11.2.php:528
msgid "Send a Test Email"
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."
msgstr ""
#. translators: %s - WPForms.com tutorial URL.
#. translators: %s - Gmail documentation URL.
#: 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."
msgstr ""
@ -1158,7 +1160,7 @@ msgid "Additionally, you can take advantage of our White Glove Setup. Sit back a
msgstr ""
#: 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 ""
#. 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."
msgstr ""
#. translators: %1$s - WPBeginner URL for recommended WordPress hosting.
#: src/Core.php:106
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
#. translators: %1$s - WP Mail SMTP plugin name; %2$s - WPMailSMTP.com URL to a related doc.
#: src/Core.php:342
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 ""
#: src/Core.php:413
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."
#: src/Core.php:356
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 ""
#. 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."
msgstr ""
#. 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."
msgstr ""
#. 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."
msgstr ""
#. 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:"
msgstr ""
#: src/Core.php:531
#: src/Core.php:474
msgid "Consider running an email test after fixing it."
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.
#: 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 ""
#: src/Providers/Mailgun/Options.php:57
@ -1369,15 +1361,10 @@ msgid "<a href=\"%s\" rel=\"\" target=\"_blank\">More information</a> on Mailgun
msgstr ""
#: src/Providers/OptionsAbstract.php:186
#: wp-mail-smtp-0.11.2.php:355
msgid "SMTP Host"
msgstr ""
#: 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"
msgstr ""
@ -1398,8 +1385,6 @@ msgid "For most servers TLS is the recommended option. If your SMTP provider off
msgstr ""
#: src/Providers/OptionsAbstract.php:240
#: wp-mail-smtp-0.11.2.php:363
#: wp-mail-smtp-0.11.2.php:481
msgid "SMTP Port"
msgstr ""
@ -1412,8 +1397,6 @@ msgid "By default TLS encryption is automatically used if the server supports it
msgstr ""
#: src/Providers/OptionsAbstract.php:276
#: wp-mail-smtp-0.11.2.php:397
#: wp-mail-smtp-0.11.2.php:401
msgid "Authentication"
msgstr ""
@ -1477,7 +1460,7 @@ msgstr ""
#. translators: %1$s - URL to pepipost.com site.
#: 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 ""
#. 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 ""
#: src/Providers/PepipostAPI/Options.php:53
msgid "Get Pepipost Now (Free)"
msgid "Get Started with Pepipost"
msgstr ""
#: src/Providers/PepipostAPI/Options.php:61
@ -1495,14 +1478,14 @@ msgstr ""
#: src/Providers/PepipostAPI/Options.php:88
#: 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"
msgstr ""
#. translators: %s - pepipost.com link to get an API Key.
#. translators: %s - sendinblue.com link to get an API Key.
#. translators: %s - link to get an API Key.
#: 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."
msgstr ""
@ -1533,25 +1516,21 @@ msgstr ""
msgid "To send emails you will need only a %s access level for this API key."
msgstr ""
#. translators: %1$s - URL to sendinblue.com site.
#: 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
#: src/Providers/Sendinblue/Options.php:33
msgid "Sendinblue"
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"
msgstr ""
@ -1559,11 +1538,59 @@ msgstr ""
msgid "Other SMTP"
msgstr ""
#. translators: %s - URL to a related article on WPForms.com.
#. translators: %s - URL to SMTP documentation.
#: 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>."
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
msgid "Is WP Mail SMTP mailer setup complete?"
msgstr ""
@ -1621,151 +1648,16 @@ msgstr ""
msgid "%1$s \\a\\t %2$s"
msgstr ""
#: wp-mail-smtp-0.11.2.php:192
#: 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
#: wp_mail_smtp.php:135
msgid "Please deactivate the free version of the WP Mail SMTP plugin before activating WP Mail SMTP Pro."
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
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
Tested up to: 5.3
Stable tag: 1.9.0
Requires PHP: 5.3
Tested up to: 5.4
Stable tag: 2.0.0
Requires PHP: 5.5.0
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:
1. Pepipost SMTP <strong>(Recommended)</strong>
2. Sendinblue SMTP <strong>(Recommended)</strong>
3. Mailgun SMTP
4. SendGrid SMTP
5. Gmail 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>
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>
8. All Other SMTP
1. SMTP.com <strong>(Recommended)</strong>
2. Pepipost SMTP <strong>(Recommended)</strong>
3. Sendinblue SMTP
4. Mailgun SMTP
5. SendGrid SMTP
6. Gmail SMTP
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. 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.
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 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 is a recommended transactional email service.
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.
@ -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.
- 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.
@ -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.
<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. =
@ -220,6 +229,13 @@ By all means please contact us to discuss features or options you'd like to see
== 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 =
* 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.

View File

@ -57,7 +57,7 @@ class Area {
protected function hooks() {
// 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_action( 'admin_menu', array( $this, 'add_admin_options_page' ) );
@ -219,14 +219,17 @@ class Area {
self::SLUG . '-logs',
array( $this, 'display' )
);
\add_submenu_page(
self::SLUG,
\esc_html__( 'About Us', 'wp-mail-smtp' ),
\esc_html__( 'About Us', 'wp-mail-smtp' ),
'manage_options',
self::SLUG . '-about',
array( $this, 'display' )
);
if ( ! wp_mail_smtp()->is_white_labeled() ) {
\add_submenu_page(
self::SLUG,
\esc_html__( 'About Us', 'wp-mail-smtp' ),
\esc_html__( 'About Us', 'wp-mail-smtp' ),
'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_bonus' => '<p>' .
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(
'strong' => true,
'span' => true,
@ -368,7 +371,7 @@ class Area {
\wp_enqueue_script(
'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' ),
'0.7.2',
false
@ -394,7 +397,7 @@ class Area {
<div id="wp-mail-smtp-header-temp"></div>
<div id="wp-mail-smtp-header">
<!--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>
<?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.5.0 Added a link to Email Log.
* @since 2.0.0 Adjusted links. Process only the Lite plugin.
*
* @param array $links
* @param string $file
* @param array $links Existing plugin action links.
*
* @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.
if ( strpos( $file, 'wp-mail-smtp' ) === false ) {
// Do not register lite plugin action links if on pro version.
if ( wp_mail_smtp()->is_pro() ) {
return $links;
}
$settings_link = '<a href="' . esc_url( $this->get_admin_page_url() ) . '">' . esc_html__( 'Settings', 'wp-mail-smtp' ) . '</a>';
$logs_link = '<a href="' . esc_url( $this->get_admin_page_url( self::SLUG . '-logs' ) ) . '">' . esc_html__( 'Email Log', 'wp-mail-smtp' ) . '</a>';
$custom['settings'] = sprintf(
'<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">
<?php
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(
'span' => array(
'class' => array(),

View File

@ -234,18 +234,16 @@ class SettingsTab extends PageAbstract {
</div>
<?php endforeach; ?>
</div>
<!-- Suggest a mailer -->
<div class="wp-mail-smtp-mailer suggest-new">
<a href="https://wpmailsmtp.com/suggest-a-mailer" class="wp-mail-smtp-mailer-image" target="_blank" rel="noopener noreferrer">
<!-- Suggest a mailer -->
<div class="wp-mail-smtp-suggest-new-mailer">
<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' ); ?>
</a>
<div class="wp-mail-smtp-mailer-text">
<label><?php esc_html_e( 'Suggest a Mailer', 'wp-mail-smtp' ); ?></label>
</div>
</div>
</p>
</div>
</div>
</div>
@ -338,7 +336,7 @@ class SettingsTab extends PageAbstract {
<p class="desc">
<?php
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(
'strong' => array(),
'br' => array(),
@ -453,7 +451,7 @@ class SettingsTab extends PageAbstract {
<p>
<?php
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(
'strong' => array(),
'span' => array(

View File

@ -253,7 +253,7 @@ class TestTab extends PageAbstract {
<!-- Header -->
<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;">
<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>
</tr>
<!-- Content -->
@ -296,7 +296,7 @@ class TestTab extends PageAbstract {
Access to our world class support team
</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;">
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>
<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;">
@ -343,7 +343,7 @@ class TestTab extends PageAbstract {
// phpcs:disable
if ( wp_mail_smtp()->is_pro() ) {
// WP Mail SMTP Pro & WPForms paid installed.
// WP Mail SMTP Pro paid installed.
$message =
'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' ),
),
@ -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' ),
sprintf(
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' ),
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>
<?php
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(
'span' => array(
'class' => array(),

View File

@ -57,7 +57,7 @@ class Core {
$this->plugin_path = rtrim( plugin_dir_path( __DIR__ ), '/\\' );
if ( $this->is_not_loadable() ) {
$this->do_not_load();
add_action( 'admin_notices', 'wp_mail_smtp_insecure_php_version_notice' );
return;
}
@ -88,63 +88,6 @@ class Core {
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.
*
@ -153,7 +96,7 @@ class Core {
public function hooks() {
// Activation hook.
add_action( 'activate_plugin', array( $this, 'activate' ), 10, 2 );
register_activation_hook( WPMS_PLUGIN_FILE, array( $this, 'activate' ) );
// Redefine PHPMailer.
add_action( 'plugins_loaded', array( $this, 'get_processor' ) );
@ -362,7 +305,7 @@ class Core {
/**
* Get the plugin's WP Site Health object.
*
* @since {VERSION}
* @since 1.9.0
*
* @return SiteHealth
*/
@ -395,7 +338,7 @@ class Core {
) {
WP::add_admin_notice(
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' ),
array(
'a' => array(
@ -406,11 +349,11 @@ class Core {
)
),
'<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>' .
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(
'strong' => array(),
'em' => array(),
@ -618,12 +561,9 @@ class Core {
* What to do on plugin activation.
*
* @since 1.0.0
*
* @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.
* @since 2.0.0 Changed from general `plugin_activate` hook to this plugin specific activation hook.
*/
public function activate( $plugin, $network_wide ) {
public function activate() {
// Store the plugin version when initial install occurred.
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' );
}
/**
* 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
namespace WPMailSMTP;
/**
* Class Geo to work with location, domain, IPs etc.
*
* @since 1.5.0
*/
class Geo {
/**
* 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.
* Examples: example.com, localhost.
*
* @since 1.5.0
*
* @return string
*/
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 );
}
/**
* Get the domain IP address.
* Uses gethostbyname() which is quite slow, but this is done only one time.
*
* @since 1.5.0
*
* @param string $domain
*
* @return string
*/
public static function get_ip_by_domain( $domain ) {
if ( $domain === 'localhost' ) {
return '127.0.0.1';
}
return gethostbyname( $domain );
}
/**
* Get the location coordinates by IP address.
* We make a request to 3rd party services.
*
* @since 1.5.0
* @since 1.6.0 Added new geo API endpoint, provided by WPForms.
*
* @param string $ip
*
* @return array Empty array for localhost.
*/
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 ) ) {
return array();
}
$request = wp_remote_get( 'https://geo.wpforms.com/v2/geolocate/json/' . $ip );
if ( ! is_wp_error( $request ) ) {
$request = json_decode( wp_remote_retrieve_body( $request ), true );
if ( ! empty( $request['latitude'] ) && ! empty( $request['longitude'] ) ) {
$data = array(
'latitude' => sanitize_text_field( $request['latitude'] ),
'longitude' => sanitize_text_field( $request['longitude'] ),
'city' => sanitize_text_field( $request['city'] ),
'region' => sanitize_text_field( $request['region_name'] ),
'country' => sanitize_text_field( $request['country_code'] ),
'postal' => sanitize_text_field( $request['zip_code'] ),
);
return $data;
}
}
$request = wp_remote_get( 'https://ipapi.co/' . $ip . '/json' );
if ( ! is_wp_error( $request ) ) {
$request = json_decode( wp_remote_retrieve_body( $request ), true );
if ( ! empty( $request['latitude'] ) && ! empty( $request['longitude'] ) ) {
$data = array(
'latitude' => sanitize_text_field( $request['latitude'] ),
'longitude' => sanitize_text_field( $request['longitude'] ),
'city' => sanitize_text_field( $request['city'] ),
'region' => sanitize_text_field( $request['region'] ),
'country' => sanitize_text_field( $request['country'] ),
'postal' => sanitize_text_field( $request['postal'] ),
);
return $data;
}
}
$request = wp_remote_get( 'https://tools.keycdn.com/geo.json?host=' . $ip );
if ( ! is_wp_error( $request ) ) {
$request = json_decode( wp_remote_retrieve_body( $request ), true );
if ( ! empty( $request['data']['geo']['latitude'] ) && ! empty( $request['data']['geo']['longitude'] ) ) {
$data = array(
'latitude' => sanitize_text_field( $request['data']['geo']['latitude'] ),
'longitude' => sanitize_text_field( $request['data']['geo']['longitude'] ),
'city' => sanitize_text_field( $request['data']['geo']['city'] ),
'region' => sanitize_text_field( $request['data']['geo']['region_name'] ),
'country' => sanitize_text_field( $request['data']['geo']['country_code'] ),
'postal' => sanitize_text_field( $request['data']['geo']['postal_code'] ),
);
return $data;
}
}
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.
*
* @see https://www.geodatasource.com/developers/php
*
* @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 $lat2 Latitude of point 2 (in decimal degrees).
* @param float $lon2 Longitude of point 2 (in decimal degrees).
* @param string $unit Supported values: M, K, N. Miles by default.
*
* @return float|int
*/
public static function get_distance_between( $lat1, $lon1, $lat2, $lon2, $unit = 'M' ) {
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 ) );
$dist = acos( $dist );
$dist = rad2deg( $dist );
$miles = $dist * 60 * 1.1515;
$unit = strtoupper( $unit );
if ( $unit === 'K' ) {
return ( $miles * 1.609344 );
} elseif ( $unit === 'N' ) {
return ( $miles * 0.8684 );
}
return $miles;
}
}
<?php
namespace WPMailSMTP;
/**
* Class Geo to work with location, domain, IPs etc.
*
* @since 1.5.0
*/
class Geo {
/**
* 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.
* Examples: example.com, localhost.
*
* @since 1.5.0
*
* @return string
*/
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 );
}
/**
* Get the domain IP address.
* Uses gethostbyname() which is quite slow, but this is done only one time.
*
* @since 1.5.0
*
* @param string $domain
*
* @return string
*/
public static function get_ip_by_domain( $domain ) {
if ( $domain === 'localhost' ) {
return '127.0.0.1';
}
return gethostbyname( $domain );
}
/**
* Get the location coordinates by IP address.
* We make a request to 3rd party services.
*
* @since 1.5.0
* @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
*
* @return array Empty array for localhost.
*/
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 ) ) {
return array();
}
$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 ( ! empty( $request['latitude'] ) && ! empty( $request['longitude'] ) ) {
$data = array(
'latitude' => sanitize_text_field( $request['latitude'] ),
'longitude' => sanitize_text_field( $request['longitude'] ),
'city' => sanitize_text_field( $request['city'] ),
'region' => sanitize_text_field( $request['region_name'] ),
'country' => sanitize_text_field( $request['country_iso'] ),
'postal' => sanitize_text_field( $request['zip_code'] ),
);
return $data;
}
}
$request = wp_remote_get( 'https://ipapi.co/' . $ip . '/json' );
if ( ! is_wp_error( $request ) ) {
$request = json_decode( wp_remote_retrieve_body( $request ), true );
if ( ! empty( $request['latitude'] ) && ! empty( $request['longitude'] ) ) {
$data = array(
'latitude' => sanitize_text_field( $request['latitude'] ),
'longitude' => sanitize_text_field( $request['longitude'] ),
'city' => sanitize_text_field( $request['city'] ),
'region' => sanitize_text_field( $request['region'] ),
'country' => sanitize_text_field( $request['country'] ),
'postal' => sanitize_text_field( $request['postal'] ),
);
return $data;
}
}
$request = wp_remote_get( 'https://tools.keycdn.com/geo.json?host=' . $ip );
if ( ! is_wp_error( $request ) ) {
$request = json_decode( wp_remote_retrieve_body( $request ), true );
if ( ! empty( $request['data']['geo']['latitude'] ) && ! empty( $request['data']['geo']['longitude'] ) ) {
$data = array(
'latitude' => sanitize_text_field( $request['data']['geo']['latitude'] ),
'longitude' => sanitize_text_field( $request['data']['geo']['longitude'] ),
'city' => sanitize_text_field( $request['data']['geo']['city'] ),
'region' => sanitize_text_field( $request['data']['geo']['region_name'] ),
'country' => sanitize_text_field( $request['data']['geo']['country_code'] ),
'postal' => sanitize_text_field( $request['data']['geo']['postal_code'] ),
);
return $data;
}
}
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.
*
* @see https://www.geodatasource.com/developers/php
*
* @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 $lat2 Latitude of point 2 (in decimal degrees).
* @param float $lon2 Longitude of point 2 (in decimal degrees).
* @param string $unit Supported values: M, K, N. Miles by default.
*
* @return float|int
*/
public static function get_distance_between( $lat1, $lon1, $lat2, $lon2, $unit = 'M' ) {
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 ) );
$dist = acos( $dist );
$dist = rad2deg( $dist );
$miles = $dist * 60 * 1.1515;
$unit = strtoupper( $unit );
if ( $unit === 'K' ) {
return ( $miles * 1.609344 );
} elseif ( $unit === 'N' ) {
return ( $miles * 0.8684 );
}
return $miles;
}
}

View File

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

View File

@ -27,8 +27,9 @@ class Processor {
add_action( 'phpmailer_init', array( $this, 'phpmailer_init' ) );
add_filter( 'wp_mail_from', array( $this, 'filter_mail_from_email' ), 1000 );
add_filter( 'wp_mail_from_name', array( $this, 'filter_mail_from_name' ), 1000 );
// High priority number tries to ensure our plugin code executes last and respects previous hooks, if not forced.
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.
*
* @since {VERSION}
* @since 1.9.0
*
* @return \WPMailSMTP\MailCatcher
*/

View File

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

View File

@ -1,477 +1,477 @@
<?php
namespace WPMailSMTP\Providers;
use WPMailSMTP\Options;
/**
* Abstract Class ProviderAbstract to contain common providers functionality.
*
* @since 1.0.0
*/
abstract class OptionsAbstract implements OptionsInterface {
/**
* @var string
*/
private $logo_url = '';
/**
* @var string
*/
private $slug = '';
/**
* @var string
*/
private $title = '';
/**
* @var string
*/
private $description = '';
/**
* @since 1.6.0
*
* @var array
*/
private $notices = array();
/**
* @since 1.6.0
*
* @var bool
*/
private $recommended = false;
/**
* @since 1.7.0
*
* @var bool
*/
private $disabled = false;
/**
* @var string
*/
private $php = WPMS_PHP_VER;
/**
* @var Options
*/
protected $options;
/**
* ProviderAbstract constructor.
*
* @since 1.0.0
*
* @param array $params
*/
public function __construct( $params ) {
if (
empty( $params['slug'] ) ||
empty( $params['title'] )
) {
return;
}
$this->slug = sanitize_key( $params['slug'] );
$this->title = sanitize_text_field( $params['title'] );
if ( ! empty( $params['description'] ) ) {
$this->description = wp_kses_post( $params['description'] );
}
if ( ! empty( $params['notices'] ) ) {
foreach ( (array) $params['notices'] as $key => $notice ) {
$key = sanitize_key( $key );
if ( empty( $key ) ) {
continue;
}
$notice = wp_kses(
$notice,
array(
'br' => true,
'strong' => true,
'em' => true,
'a' => array(
'href' => true,
'rel' => true,
'target' => true,
),
)
);
if ( empty( $notice ) ) {
continue;
}
$this->notices[ $key ] = $notice;
}
}
if ( isset( $params['recommended'] ) ) {
$this->recommended = (bool) $params['recommended'];
}
if ( isset( $params['disabled'] ) ) {
$this->disabled = (bool) $params['disabled'];
}
if ( ! empty( $params['php'] ) ) {
$this->php = sanitize_text_field( $params['php'] );
}
if ( ! empty( $params['logo_url'] ) ) {
$this->logo_url = esc_url_raw( $params['logo_url'] );
}
$this->options = new Options();
}
/**
* @inheritdoc
*/
public function get_logo_url() {
return apply_filters( 'wp_mail_smtp_providers_provider_get_logo_url', $this->logo_url, $this );
}
/**
* @inheritdoc
*/
public function get_slug() {
return apply_filters( 'wp_mail_smtp_providers_provider_get_slug', $this->slug, $this );
}
/**
* @inheritdoc
*/
public function get_title() {
return apply_filters( 'wp_mail_smtp_providers_provider_get_title', $this->title, $this );
}
/**
* @inheritdoc
*/
public function get_description() {
return apply_filters( 'wp_mail_smtp_providers_provider_get_description', $this->description, $this );
}
/**
* Some mailers may display a notice above its options.
*
* @since 1.6.0
*
* @param string $type
*
* @return string
*/
public function get_notice( $type ) {
$type = sanitize_key( $type );
return apply_filters( 'wp_mail_smtp_providers_provider_get_notice', isset( $this->notices[ $type ] ) ? $this->notices[ $type ] : '', $this );
}
/**
* @inheritdoc
*/
public function get_php_version() {
return apply_filters( 'wp_mail_smtp_providers_provider_get_php_version', $this->php, $this );
}
/**
* @inheritdoc
*/
public function display_options() {
?>
<!-- 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 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>
</div>
<div class="wp-mail-smtp-setting-field">
<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' ) ); ?>"
<?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"
/>
</div>
</div>
<!-- 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 class="wp-mail-smtp-setting-label">
<label><?php esc_html_e( 'Encryption', 'wp-mail-smtp' ); ?></label>
</div>
<div class="wp-mail-smtp-setting-field">
<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"
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 checked( 'none', $this->options->get( $this->get_slug(), 'encryption' ) ); ?>
/>
<?php esc_html_e( 'None', 'wp-mail-smtp' ); ?>
</label>
<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"
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 checked( 'ssl', $this->options->get( $this->get_slug(), 'encryption' ) ); ?>
/>
<?php esc_html_e( 'SSL', 'wp-mail-smtp' ); ?>
</label>
<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"
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 checked( 'tls', $this->options->get( $this->get_slug(), 'encryption' ) ); ?>
/>
<?php esc_html_e( 'TLS', 'wp-mail-smtp' ); ?>
</label>
<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' ); ?>
</p>
</div>
</div>
<!-- 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 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>
</div>
<div class="wp-mail-smtp-setting-field">
<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' ) ); ?>"
<?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"
/>
</div>
</div>
<!-- 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 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>
</div>
<div class="wp-mail-smtp-setting-field">
<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"
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 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-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>
</label>
<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' ); ?>
</p>
</div>
</div>
<!-- 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 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>
</div>
<div class="wp-mail-smtp-setting-field">
<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"
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 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-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>
</label>
</div>
</div>
<!-- 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 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>
</div>
<div class="wp-mail-smtp-setting-field">
<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' ) ); ?>"
<?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"
/>
</div>
</div>
<!-- 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 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>
</div>
<div class="wp-mail-smtp-setting-field">
<?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"/>
<?php $this->display_const_set_message( 'WPMS_SMTP_PASS' ); ?>
<p class="desc">
<?php
printf(
/* 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' ),
'<code>define( \'WPMS_SMTP_PASS\', \'your_old_password\' );</code>'
);
?>
<br>
<?php
printf(
/* 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' ),
'<code>wp-config.php</code>',
'<code>WPMS_ON</code>'
);
?>
</p>
<pre>
define( 'WPMS_ON', false );
</pre>
<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' ); ?>
</p>
<?php else : ?>
<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' ) ); ?>"
id="wp-mail-smtp-setting-<?php echo esc_attr( $this->get_slug() ); ?>-pass" spellcheck="false" autocomplete="new-password"
/>
<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' ); ?>
<br>
<?php
printf(
/* translators: %s - wp-config.php. */
esc_html__( 'To do this add the lines below to your %s file:', 'wp-mail-smtp' ),
'<code>wp-config.php</code>'
);
?>
</p>
<pre>
define( 'WPMS_ON', true );
define( 'WPMS_SMTP_PASS', 'your_password' );
</pre>
<?php endif; ?>
</div>
</div>
<?php
}
/**
* Whether this mailer is recommended or not.
*
* @since 1.6.0
*
* @return bool
*/
public function is_recommended() {
return (bool) apply_filters( 'wp_mail_smtp_providers_provider_is_recommended', $this->recommended, $this );
}
/**
* Whether this mailer is disabled or not.
* Used for displaying Pro mailers inside Lite plugin.
*
* @since 1.7.0
*
* @return bool
*/
public function is_disabled() {
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.
* Valid for those, that use SDK.
*
* @since 1.0.0
*
* @return bool
*/
public function is_php_correct() {
return version_compare( phpversion(), $this->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.
*
* @since 1.0.0
*/
protected function display_php_warning() {
?>
<blockquote>
<?php
printf(
/* 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( $this->get_title() ),
esc_html( $this->php ),
esc_html( phpversion() )
);
?>
<br>
<?php esc_html_e( 'Meanwhile you can switch to some other mailers.', 'wp-mail-smtp' ); ?>
</blockquote>
<?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.
*
* @since 1.5.0
*/
protected function display_ssl_warning() {
?>
<blockquote>
<?php
printf(
/* 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( $this->get_title() )
);
?>
<br>
<?php esc_html_e( 'Meanwhile you can switch to some other mailers.', 'wp-mail-smtp' ); ?>
</blockquote>
<?php
}
/**
* Display a message of a constant that was set inside wp-config.php file.
*
* @since 1.5.0
*
* @param string $constant Constant name.
*/
protected function display_const_set_message( $constant ) {
?>
<p class="desc">
<?php
printf( /* translators: %1$s - constant name, %2$s - file name. */
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>wp-config.php</code>'
);
?>
</p>
<?php
}
}
<?php
namespace WPMailSMTP\Providers;
use WPMailSMTP\Options;
/**
* Abstract Class ProviderAbstract to contain common providers functionality.
*
* @since 1.0.0
*/
abstract class OptionsAbstract implements OptionsInterface {
/**
* @var string
*/
private $logo_url = '';
/**
* @var string
*/
private $slug = '';
/**
* @var string
*/
private $title = '';
/**
* @var string
*/
private $description = '';
/**
* @since 1.6.0
*
* @var array
*/
private $notices = array();
/**
* @since 1.6.0
*
* @var bool
*/
private $recommended = false;
/**
* @since 1.7.0
*
* @var bool
*/
private $disabled = false;
/**
* @var string
*/
private $php = WPMS_PHP_VER;
/**
* @var Options
*/
protected $options;
/**
* ProviderAbstract constructor.
*
* @since 1.0.0
*
* @param array $params
*/
public function __construct( $params ) {
if (
empty( $params['slug'] ) ||
empty( $params['title'] )
) {
return;
}
$this->slug = sanitize_key( $params['slug'] );
$this->title = sanitize_text_field( $params['title'] );
if ( ! empty( $params['description'] ) ) {
$this->description = wp_kses_post( $params['description'] );
}
if ( ! empty( $params['notices'] ) ) {
foreach ( (array) $params['notices'] as $key => $notice ) {
$key = sanitize_key( $key );
if ( empty( $key ) ) {
continue;
}
$notice = wp_kses(
$notice,
array(
'br' => true,
'strong' => true,
'em' => true,
'a' => array(
'href' => true,
'rel' => true,
'target' => true,
),
)
);
if ( empty( $notice ) ) {
continue;
}
$this->notices[ $key ] = $notice;
}
}
if ( isset( $params['recommended'] ) ) {
$this->recommended = (bool) $params['recommended'];
}
if ( isset( $params['disabled'] ) ) {
$this->disabled = (bool) $params['disabled'];
}
if ( ! empty( $params['php'] ) ) {
$this->php = sanitize_text_field( $params['php'] );
}
if ( ! empty( $params['logo_url'] ) ) {
$this->logo_url = esc_url_raw( $params['logo_url'] );
}
$this->options = new Options();
}
/**
* @inheritdoc
*/
public function get_logo_url() {
return apply_filters( 'wp_mail_smtp_providers_provider_get_logo_url', $this->logo_url, $this );
}
/**
* @inheritdoc
*/
public function get_slug() {
return apply_filters( 'wp_mail_smtp_providers_provider_get_slug', $this->slug, $this );
}
/**
* @inheritdoc
*/
public function get_title() {
return apply_filters( 'wp_mail_smtp_providers_provider_get_title', $this->title, $this );
}
/**
* @inheritdoc
*/
public function get_description() {
return apply_filters( 'wp_mail_smtp_providers_provider_get_description', $this->description, $this );
}
/**
* Some mailers may display a notice above its options.
*
* @since 1.6.0
*
* @param string $type
*
* @return string
*/
public function get_notice( $type ) {
$type = sanitize_key( $type );
return apply_filters( 'wp_mail_smtp_providers_provider_get_notice', isset( $this->notices[ $type ] ) ? $this->notices[ $type ] : '', $this );
}
/**
* @inheritdoc
*/
public function get_php_version() {
return apply_filters( 'wp_mail_smtp_providers_provider_get_php_version', $this->php, $this );
}
/**
* @inheritdoc
*/
public function display_options() {
?>
<!-- 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 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>
</div>
<div class="wp-mail-smtp-setting-field">
<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' ) ); ?>"
<?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"
/>
</div>
</div>
<!-- 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 class="wp-mail-smtp-setting-label">
<label><?php esc_html_e( 'Encryption', 'wp-mail-smtp' ); ?></label>
</div>
<div class="wp-mail-smtp-setting-field">
<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"
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 checked( 'none', $this->options->get( $this->get_slug(), 'encryption' ) ); ?>
/>
<?php esc_html_e( 'None', 'wp-mail-smtp' ); ?>
</label>
<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"
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 checked( 'ssl', $this->options->get( $this->get_slug(), 'encryption' ) ); ?>
/>
<?php esc_html_e( 'SSL', 'wp-mail-smtp' ); ?>
</label>
<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"
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 checked( 'tls', $this->options->get( $this->get_slug(), 'encryption' ) ); ?>
/>
<?php esc_html_e( 'TLS', 'wp-mail-smtp' ); ?>
</label>
<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' ); ?>
</p>
</div>
</div>
<!-- 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 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>
</div>
<div class="wp-mail-smtp-setting-field">
<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' ) ); ?>"
<?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"
/>
</div>
</div>
<!-- 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 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>
</div>
<div class="wp-mail-smtp-setting-field">
<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"
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 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-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>
</label>
<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' ); ?>
</p>
</div>
</div>
<!-- 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 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>
</div>
<div class="wp-mail-smtp-setting-field">
<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"
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 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-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>
</label>
</div>
</div>
<!-- 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 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>
</div>
<div class="wp-mail-smtp-setting-field">
<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' ) ); ?>"
<?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"
/>
</div>
</div>
<!-- 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 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>
</div>
<div class="wp-mail-smtp-setting-field">
<?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"/>
<?php $this->display_const_set_message( 'WPMS_SMTP_PASS' ); ?>
<p class="desc">
<?php
printf(
/* 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' ),
'<code>define( \'WPMS_SMTP_PASS\', \'your_old_password\' );</code>'
);
?>
<br>
<?php
printf(
/* 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' ),
'<code>wp-config.php</code>',
'<code>WPMS_ON</code>'
);
?>
</p>
<pre>
define( 'WPMS_ON', false );
</pre>
<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' ); ?>
</p>
<?php else : ?>
<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' ) ); ?>"
id="wp-mail-smtp-setting-<?php echo esc_attr( $this->get_slug() ); ?>-pass" spellcheck="false" autocomplete="new-password"
/>
<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' ); ?>
<br>
<?php
printf(
/* translators: %s - wp-config.php. */
esc_html__( 'To do this add the lines below to your %s file:', 'wp-mail-smtp' ),
'<code>wp-config.php</code>'
);
?>
</p>
<pre>
define( 'WPMS_ON', true );
define( 'WPMS_SMTP_PASS', 'your_password' );
</pre>
<?php endif; ?>
</div>
</div>
<?php
}
/**
* Whether this mailer is recommended or not.
*
* @since 1.6.0
*
* @return bool
*/
public function is_recommended() {
return (bool) apply_filters( 'wp_mail_smtp_providers_provider_is_recommended', $this->recommended, $this );
}
/**
* Whether this mailer is disabled or not.
* Used for displaying Pro mailers inside Lite plugin.
*
* @since 1.7.0
*
* @return bool
*/
public function is_disabled() {
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.
* Valid for those, that use SDK.
*
* @since 1.0.0
*
* @return bool
*/
public function is_php_correct() {
return version_compare( phpversion(), $this->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.
*
* @since 1.0.0
*/
protected function display_php_warning() {
?>
<blockquote>
<?php
printf(
/* 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( $this->get_title() ),
esc_html( $this->php ),
esc_html( phpversion() )
);
?>
<br>
<?php esc_html_e( 'Meanwhile you can switch to some other mailers.', 'wp-mail-smtp' ); ?>
</blockquote>
<?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.
*
* @since 1.5.0
*/
protected function display_ssl_warning() {
?>
<blockquote>
<?php
printf(
/* 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( $this->get_title() )
);
?>
<br>
<?php esc_html_e( 'Meanwhile you can switch to some other mailers.', 'wp-mail-smtp' ); ?>
</blockquote>
<?php
}
/**
* Display a message of a constant that was set inside wp-config.php file.
*
* @since 1.5.0
*
* @param string $constant Constant name.
*/
protected function display_const_set_message( $constant ) {
?>
<p class="desc">
<?php
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' ),
'<code>' . esc_attr( $constant ) . '</code>',
'<code>wp-config.php</code>'
);
?>
</p>
<?php
}
}

View File

@ -50,7 +50,7 @@ class Options extends OptionsAbstract {
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">' .
esc_html__( 'Get Pepipost Now (Free)', 'wp-mail-smtp' ) .
esc_html__( 'Get Started with Pepipost', 'wp-mail-smtp' ) .
'</a></p>';
}
@ -103,7 +103,7 @@ class Options extends OptionsAbstract {
<p class="desc">
<?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' ),
'<a href="https://app.pepipost.com/app/settings/integration" target="_blank" rel="noopener noreferrer">' .
esc_html__( 'Get the API Key', 'wp-mail-smtp' ) .

View File

@ -1,44 +1,44 @@
<?php
namespace WPMailSMTP\Providers\SMTP;
use WPMailSMTP\Providers\OptionsAbstract;
/**
* Class SMTP.
*
* @since 1.0.0
*/
class Options extends OptionsAbstract {
/**
* SMTP constructor.
*
* @since 1.0.0
*/
public function __construct() {
parent::__construct(
array(
'logo_url' => wp_mail_smtp()->assets_url . '/images/providers/smtp.svg',
'slug' => 'smtp',
'title' => esc_html__( 'Other SMTP', 'wp-mail-smtp' ),
'description' => sprintf(
wp_kses(
/* translators: %s - URL to a related article on WPForms.com. */
__( '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(
'br' => array(),
'a' => array(
'href' => array(),
'rel' => array(),
'target' => array(),
),
)
),
'https://wpmailsmtp.com/docs/how-to-set-up-the-other-smtp-mailer-in-wp-mail-smtp/'
),
)
);
}
}
<?php
namespace WPMailSMTP\Providers\SMTP;
use WPMailSMTP\Providers\OptionsAbstract;
/**
* Class SMTP.
*
* @since 1.0.0
*/
class Options extends OptionsAbstract {
/**
* SMTP constructor.
*
* @since 1.0.0
*/
public function __construct() {
parent::__construct(
array(
'logo_url' => wp_mail_smtp()->assets_url . '/images/providers/smtp.svg',
'slug' => 'smtp',
'title' => esc_html__( 'Other SMTP', 'wp-mail-smtp' ),
'description' => sprintf(
wp_kses(
/* 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' ),
array(
'br' => array(),
'a' => array(
'href' => array(),
'rel' => array(),
'target' => array(),
),
)
),
'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() {
$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(
array(
'logo_url' => wp_mail_smtp()->assets_url . '/images/providers/sendinblue.svg',
'slug' => self::SLUG,
'title' => esc_html__( 'Sendinblue', 'wp-mail-smtp' ),
'description' => $description,
'recommended' => true,
'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">
<?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' ),
'<a href="https://account.sendinblue.com/advanced/api" target="_blank" rel="noopener noreferrer">' .
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.
*
* @since {VERSION}
* @since 1.9.0
*/
class SiteHealth {
@ -15,7 +15,7 @@ class SiteHealth {
*
* @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';
@ -24,14 +24,14 @@ class SiteHealth {
* 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.
*
* @since {VERSION}
* @since 1.9.0
*/
const DEBUG_INFO_SLUG = 'wp_mail_smtp';
/**
* Translatable string for the plugin label.
*
* @since {VERSION}
* @since 1.9.0
*
* @return string
*/
@ -43,7 +43,7 @@ class SiteHealth {
/**
* Initialize the site heath functionality.
*
* @since {VERSION}
* @since 1.9.0
*/
public function init() {
@ -55,7 +55,7 @@ class SiteHealth {
* Register plugin WP site health tests.
* 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.
*
@ -75,7 +75,7 @@ class SiteHealth {
* Register plugin WP Site Health debug information.
* 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.
*
@ -109,7 +109,7 @@ class SiteHealth {
/**
* 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() {

View File

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

View File

@ -4,4 +4,4 @@
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',
'a0edc8309cc5e1d60e3047b5df6b7052' => $vendorDir . '/guzzlehttp/psr7/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',
'decc78cc4436b1292c6c0d151b19445c' => $vendorDir . '/phpseclib/phpseclib/phpseclib/bootstrap.php',
);

View File

@ -8,6 +8,9 @@ $baseDir = dirname($vendorDir);
return array(
'phpseclib\\' => array($vendorDir . '/phpseclib/phpseclib/phpseclib'),
'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'),
'Psr\\Log\\' => array($vendorDir . '/psr/log/Psr/Log'),
'Psr\\Http\\Message\\' => array($vendorDir . '/psr/http-message/src'),

View File

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

View File

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

View File

@ -19,7 +19,8 @@
* Service definition for Gmail (v1).
*
* <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>
* 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. */
const 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. */
const GMAIL_COMPOSE =
"https://www.googleapis.com/auth/gmail.compose";
@ -85,8 +98,8 @@ class Google_Service_Gmail extends Google_Service
{
parent::__construct($client);
$this->rootUrl = $rootUrl ?: 'https://www.googleapis.com/';
$this->servicePath = 'gmail/v1/users/';
$this->batchPath = 'batch/gmail/v1';
$this->servicePath = '';
$this->batchPath = 'batch';
$this->version = 'v1';
$this->serviceName = 'gmail';
@ -97,7 +110,7 @@ class Google_Service_Gmail extends Google_Service
array(
'methods' => array(
'getProfile' => array(
'path' => '{userId}/profile',
'path' => 'gmail/v1/users/{userId}/profile',
'httpMethod' => 'GET',
'parameters' => array(
'userId' => array(
@ -107,7 +120,7 @@ class Google_Service_Gmail extends Google_Service
),
),
),'stop' => array(
'path' => '{userId}/stop',
'path' => 'gmail/v1/users/{userId}/stop',
'httpMethod' => 'POST',
'parameters' => array(
'userId' => array(
@ -117,7 +130,7 @@ class Google_Service_Gmail extends Google_Service
),
),
),'watch' => array(
'path' => '{userId}/watch',
'path' => 'gmail/v1/users/{userId}/watch',
'httpMethod' => 'POST',
'parameters' => array(
'userId' => array(
@ -137,7 +150,7 @@ class Google_Service_Gmail extends Google_Service
array(
'methods' => array(
'create' => array(
'path' => '{userId}/drafts',
'path' => 'gmail/v1/users/{userId}/drafts',
'httpMethod' => 'POST',
'parameters' => array(
'userId' => array(
@ -147,7 +160,7 @@ class Google_Service_Gmail extends Google_Service
),
),
),'delete' => array(
'path' => '{userId}/drafts/{id}',
'path' => 'gmail/v1/users/{userId}/drafts/{id}',
'httpMethod' => 'DELETE',
'parameters' => array(
'userId' => array(
@ -162,7 +175,7 @@ class Google_Service_Gmail extends Google_Service
),
),
),'get' => array(
'path' => '{userId}/drafts/{id}',
'path' => 'gmail/v1/users/{userId}/drafts/{id}',
'httpMethod' => 'GET',
'parameters' => array(
'userId' => array(
@ -181,7 +194,7 @@ class Google_Service_Gmail extends Google_Service
),
),
),'list' => array(
'path' => '{userId}/drafts',
'path' => 'gmail/v1/users/{userId}/drafts',
'httpMethod' => 'GET',
'parameters' => array(
'userId' => array(
@ -193,10 +206,6 @@ class Google_Service_Gmail extends Google_Service
'location' => 'query',
'type' => 'boolean',
),
'maxResults' => array(
'location' => 'query',
'type' => 'integer',
),
'pageToken' => array(
'location' => 'query',
'type' => 'string',
@ -205,9 +214,13 @@ class Google_Service_Gmail extends Google_Service
'location' => 'query',
'type' => 'string',
),
'maxResults' => array(
'location' => 'query',
'type' => 'integer',
),
),
),'send' => array(
'path' => '{userId}/drafts/send',
'path' => 'gmail/v1/users/{userId}/drafts/send',
'httpMethod' => 'POST',
'parameters' => array(
'userId' => array(
@ -217,7 +230,7 @@ class Google_Service_Gmail extends Google_Service
),
),
),'update' => array(
'path' => '{userId}/drafts/{id}',
'path' => 'gmail/v1/users/{userId}/drafts/{id}',
'httpMethod' => 'PUT',
'parameters' => array(
'userId' => array(
@ -242,7 +255,7 @@ class Google_Service_Gmail extends Google_Service
array(
'methods' => array(
'list' => array(
'path' => '{userId}/history',
'path' => 'gmail/v1/users/{userId}/history',
'httpMethod' => 'GET',
'parameters' => array(
'userId' => array(
@ -250,10 +263,9 @@ class Google_Service_Gmail extends Google_Service
'type' => 'string',
'required' => true,
),
'historyTypes' => array(
'pageToken' => array(
'location' => 'query',
'type' => 'string',
'repeated' => true,
),
'labelId' => array(
'location' => 'query',
@ -263,9 +275,10 @@ class Google_Service_Gmail extends Google_Service
'location' => 'query',
'type' => 'integer',
),
'pageToken' => array(
'historyTypes' => array(
'location' => 'query',
'type' => 'string',
'repeated' => true,
),
'startHistoryId' => array(
'location' => 'query',
@ -283,7 +296,7 @@ class Google_Service_Gmail extends Google_Service
array(
'methods' => array(
'create' => array(
'path' => '{userId}/labels',
'path' => 'gmail/v1/users/{userId}/labels',
'httpMethod' => 'POST',
'parameters' => array(
'userId' => array(
@ -293,7 +306,7 @@ class Google_Service_Gmail extends Google_Service
),
),
),'delete' => array(
'path' => '{userId}/labels/{id}',
'path' => 'gmail/v1/users/{userId}/labels/{id}',
'httpMethod' => 'DELETE',
'parameters' => array(
'userId' => array(
@ -308,7 +321,7 @@ class Google_Service_Gmail extends Google_Service
),
),
),'get' => array(
'path' => '{userId}/labels/{id}',
'path' => 'gmail/v1/users/{userId}/labels/{id}',
'httpMethod' => 'GET',
'parameters' => array(
'userId' => array(
@ -323,7 +336,7 @@ class Google_Service_Gmail extends Google_Service
),
),
),'list' => array(
'path' => '{userId}/labels',
'path' => 'gmail/v1/users/{userId}/labels',
'httpMethod' => 'GET',
'parameters' => array(
'userId' => array(
@ -333,7 +346,7 @@ class Google_Service_Gmail extends Google_Service
),
),
),'patch' => array(
'path' => '{userId}/labels/{id}',
'path' => 'gmail/v1/users/{userId}/labels/{id}',
'httpMethod' => 'PATCH',
'parameters' => array(
'userId' => array(
@ -348,7 +361,7 @@ class Google_Service_Gmail extends Google_Service
),
),
),'update' => array(
'path' => '{userId}/labels/{id}',
'path' => 'gmail/v1/users/{userId}/labels/{id}',
'httpMethod' => 'PUT',
'parameters' => array(
'userId' => array(
@ -373,7 +386,7 @@ class Google_Service_Gmail extends Google_Service
array(
'methods' => array(
'batchDelete' => array(
'path' => '{userId}/messages/batchDelete',
'path' => 'gmail/v1/users/{userId}/messages/batchDelete',
'httpMethod' => 'POST',
'parameters' => array(
'userId' => array(
@ -383,7 +396,7 @@ class Google_Service_Gmail extends Google_Service
),
),
),'batchModify' => array(
'path' => '{userId}/messages/batchModify',
'path' => 'gmail/v1/users/{userId}/messages/batchModify',
'httpMethod' => 'POST',
'parameters' => array(
'userId' => array(
@ -393,7 +406,7 @@ class Google_Service_Gmail extends Google_Service
),
),
),'delete' => array(
'path' => '{userId}/messages/{id}',
'path' => 'gmail/v1/users/{userId}/messages/{id}',
'httpMethod' => 'DELETE',
'parameters' => array(
'userId' => array(
@ -408,7 +421,7 @@ class Google_Service_Gmail extends Google_Service
),
),
),'get' => array(
'path' => '{userId}/messages/{id}',
'path' => 'gmail/v1/users/{userId}/messages/{id}',
'httpMethod' => 'GET',
'parameters' => array(
'userId' => array(
@ -421,18 +434,18 @@ class Google_Service_Gmail extends Google_Service
'type' => 'string',
'required' => true,
),
'format' => array(
'location' => 'query',
'type' => 'string',
),
'metadataHeaders' => array(
'location' => 'query',
'type' => 'string',
'repeated' => true,
),
'format' => array(
'location' => 'query',
'type' => 'string',
),
),
),'import' => array(
'path' => '{userId}/messages/import',
'path' => 'gmail/v1/users/{userId}/messages/import',
'httpMethod' => 'POST',
'parameters' => array(
'userId' => array(
@ -440,7 +453,7 @@ class Google_Service_Gmail extends Google_Service
'type' => 'string',
'required' => true,
),
'deleted' => array(
'processForCalendar' => array(
'location' => 'query',
'type' => 'boolean',
),
@ -452,13 +465,13 @@ class Google_Service_Gmail extends Google_Service
'location' => 'query',
'type' => 'boolean',
),
'processForCalendar' => array(
'deleted' => array(
'location' => 'query',
'type' => 'boolean',
),
),
),'insert' => array(
'path' => '{userId}/messages',
'path' => 'gmail/v1/users/{userId}/messages',
'httpMethod' => 'POST',
'parameters' => array(
'userId' => array(
@ -466,17 +479,17 @@ class Google_Service_Gmail extends Google_Service
'type' => 'string',
'required' => true,
),
'deleted' => array(
'location' => 'query',
'type' => 'boolean',
),
'internalDateSource' => array(
'location' => 'query',
'type' => 'string',
),
'deleted' => array(
'location' => 'query',
'type' => 'boolean',
),
),
),'list' => array(
'path' => '{userId}/messages',
'path' => 'gmail/v1/users/{userId}/messages',
'httpMethod' => 'GET',
'parameters' => array(
'userId' => array(
@ -488,26 +501,26 @@ class Google_Service_Gmail extends Google_Service
'location' => 'query',
'type' => 'boolean',
),
'pageToken' => array(
'location' => 'query',
'type' => 'string',
),
'labelIds' => array(
'location' => 'query',
'type' => 'string',
'repeated' => true,
),
'maxResults' => array(
'location' => 'query',
'type' => 'integer',
),
'pageToken' => array(
'location' => 'query',
'type' => 'string',
),
'q' => array(
'location' => 'query',
'type' => 'string',
),
'maxResults' => array(
'location' => 'query',
'type' => 'integer',
),
),
),'modify' => array(
'path' => '{userId}/messages/{id}/modify',
'path' => 'gmail/v1/users/{userId}/messages/{id}/modify',
'httpMethod' => 'POST',
'parameters' => array(
'userId' => array(
@ -522,7 +535,7 @@ class Google_Service_Gmail extends Google_Service
),
),
),'send' => array(
'path' => '{userId}/messages/send',
'path' => 'gmail/v1/users/{userId}/messages/send',
'httpMethod' => 'POST',
'parameters' => array(
'userId' => array(
@ -532,7 +545,7 @@ class Google_Service_Gmail extends Google_Service
),
),
),'trash' => array(
'path' => '{userId}/messages/{id}/trash',
'path' => 'gmail/v1/users/{userId}/messages/{id}/trash',
'httpMethod' => 'POST',
'parameters' => array(
'userId' => array(
@ -547,7 +560,7 @@ class Google_Service_Gmail extends Google_Service
),
),
),'untrash' => array(
'path' => '{userId}/messages/{id}/untrash',
'path' => 'gmail/v1/users/{userId}/messages/{id}/untrash',
'httpMethod' => 'POST',
'parameters' => array(
'userId' => array(
@ -572,7 +585,7 @@ class Google_Service_Gmail extends Google_Service
array(
'methods' => array(
'get' => array(
'path' => '{userId}/messages/{messageId}/attachments/{id}',
'path' => 'gmail/v1/users/{userId}/messages/{messageId}/attachments/{id}',
'httpMethod' => 'GET',
'parameters' => array(
'userId' => array(
@ -602,7 +615,7 @@ class Google_Service_Gmail extends Google_Service
array(
'methods' => array(
'getAutoForwarding' => array(
'path' => '{userId}/settings/autoForwarding',
'path' => 'gmail/v1/users/{userId}/settings/autoForwarding',
'httpMethod' => 'GET',
'parameters' => array(
'userId' => array(
@ -612,7 +625,7 @@ class Google_Service_Gmail extends Google_Service
),
),
),'getImap' => array(
'path' => '{userId}/settings/imap',
'path' => 'gmail/v1/users/{userId}/settings/imap',
'httpMethod' => 'GET',
'parameters' => array(
'userId' => array(
@ -622,7 +635,7 @@ class Google_Service_Gmail extends Google_Service
),
),
),'getLanguage' => array(
'path' => '{userId}/settings/language',
'path' => 'gmail/v1/users/{userId}/settings/language',
'httpMethod' => 'GET',
'parameters' => array(
'userId' => array(
@ -632,7 +645,7 @@ class Google_Service_Gmail extends Google_Service
),
),
),'getPop' => array(
'path' => '{userId}/settings/pop',
'path' => 'gmail/v1/users/{userId}/settings/pop',
'httpMethod' => 'GET',
'parameters' => array(
'userId' => array(
@ -642,7 +655,7 @@ class Google_Service_Gmail extends Google_Service
),
),
),'getVacation' => array(
'path' => '{userId}/settings/vacation',
'path' => 'gmail/v1/users/{userId}/settings/vacation',
'httpMethod' => 'GET',
'parameters' => array(
'userId' => array(
@ -652,7 +665,7 @@ class Google_Service_Gmail extends Google_Service
),
),
),'updateAutoForwarding' => array(
'path' => '{userId}/settings/autoForwarding',
'path' => 'gmail/v1/users/{userId}/settings/autoForwarding',
'httpMethod' => 'PUT',
'parameters' => array(
'userId' => array(
@ -662,7 +675,7 @@ class Google_Service_Gmail extends Google_Service
),
),
),'updateImap' => array(
'path' => '{userId}/settings/imap',
'path' => 'gmail/v1/users/{userId}/settings/imap',
'httpMethod' => 'PUT',
'parameters' => array(
'userId' => array(
@ -672,7 +685,7 @@ class Google_Service_Gmail extends Google_Service
),
),
),'updateLanguage' => array(
'path' => '{userId}/settings/language',
'path' => 'gmail/v1/users/{userId}/settings/language',
'httpMethod' => 'PUT',
'parameters' => array(
'userId' => array(
@ -682,7 +695,7 @@ class Google_Service_Gmail extends Google_Service
),
),
),'updatePop' => array(
'path' => '{userId}/settings/pop',
'path' => 'gmail/v1/users/{userId}/settings/pop',
'httpMethod' => 'PUT',
'parameters' => array(
'userId' => array(
@ -692,7 +705,7 @@ class Google_Service_Gmail extends Google_Service
),
),
),'updateVacation' => array(
'path' => '{userId}/settings/vacation',
'path' => 'gmail/v1/users/{userId}/settings/vacation',
'httpMethod' => 'PUT',
'parameters' => array(
'userId' => array(
@ -712,7 +725,7 @@ class Google_Service_Gmail extends Google_Service
array(
'methods' => array(
'create' => array(
'path' => '{userId}/settings/delegates',
'path' => 'gmail/v1/users/{userId}/settings/delegates',
'httpMethod' => 'POST',
'parameters' => array(
'userId' => array(
@ -722,7 +735,7 @@ class Google_Service_Gmail extends Google_Service
),
),
),'delete' => array(
'path' => '{userId}/settings/delegates/{delegateEmail}',
'path' => 'gmail/v1/users/{userId}/settings/delegates/{delegateEmail}',
'httpMethod' => 'DELETE',
'parameters' => array(
'userId' => array(
@ -737,7 +750,7 @@ class Google_Service_Gmail extends Google_Service
),
),
),'get' => array(
'path' => '{userId}/settings/delegates/{delegateEmail}',
'path' => 'gmail/v1/users/{userId}/settings/delegates/{delegateEmail}',
'httpMethod' => 'GET',
'parameters' => array(
'userId' => array(
@ -752,7 +765,7 @@ class Google_Service_Gmail extends Google_Service
),
),
),'list' => array(
'path' => '{userId}/settings/delegates',
'path' => 'gmail/v1/users/{userId}/settings/delegates',
'httpMethod' => 'GET',
'parameters' => array(
'userId' => array(
@ -772,7 +785,7 @@ class Google_Service_Gmail extends Google_Service
array(
'methods' => array(
'create' => array(
'path' => '{userId}/settings/filters',
'path' => 'gmail/v1/users/{userId}/settings/filters',
'httpMethod' => 'POST',
'parameters' => array(
'userId' => array(
@ -782,7 +795,7 @@ class Google_Service_Gmail extends Google_Service
),
),
),'delete' => array(
'path' => '{userId}/settings/filters/{id}',
'path' => 'gmail/v1/users/{userId}/settings/filters/{id}',
'httpMethod' => 'DELETE',
'parameters' => array(
'userId' => array(
@ -797,7 +810,7 @@ class Google_Service_Gmail extends Google_Service
),
),
),'get' => array(
'path' => '{userId}/settings/filters/{id}',
'path' => 'gmail/v1/users/{userId}/settings/filters/{id}',
'httpMethod' => 'GET',
'parameters' => array(
'userId' => array(
@ -812,7 +825,7 @@ class Google_Service_Gmail extends Google_Service
),
),
),'list' => array(
'path' => '{userId}/settings/filters',
'path' => 'gmail/v1/users/{userId}/settings/filters',
'httpMethod' => 'GET',
'parameters' => array(
'userId' => array(
@ -832,7 +845,7 @@ class Google_Service_Gmail extends Google_Service
array(
'methods' => array(
'create' => array(
'path' => '{userId}/settings/forwardingAddresses',
'path' => 'gmail/v1/users/{userId}/settings/forwardingAddresses',
'httpMethod' => 'POST',
'parameters' => array(
'userId' => array(
@ -842,7 +855,7 @@ class Google_Service_Gmail extends Google_Service
),
),
),'delete' => array(
'path' => '{userId}/settings/forwardingAddresses/{forwardingEmail}',
'path' => 'gmail/v1/users/{userId}/settings/forwardingAddresses/{forwardingEmail}',
'httpMethod' => 'DELETE',
'parameters' => array(
'userId' => array(
@ -857,7 +870,7 @@ class Google_Service_Gmail extends Google_Service
),
),
),'get' => array(
'path' => '{userId}/settings/forwardingAddresses/{forwardingEmail}',
'path' => 'gmail/v1/users/{userId}/settings/forwardingAddresses/{forwardingEmail}',
'httpMethod' => 'GET',
'parameters' => array(
'userId' => array(
@ -872,7 +885,7 @@ class Google_Service_Gmail extends Google_Service
),
),
),'list' => array(
'path' => '{userId}/settings/forwardingAddresses',
'path' => 'gmail/v1/users/{userId}/settings/forwardingAddresses',
'httpMethod' => 'GET',
'parameters' => array(
'userId' => array(
@ -892,7 +905,7 @@ class Google_Service_Gmail extends Google_Service
array(
'methods' => array(
'create' => array(
'path' => '{userId}/settings/sendAs',
'path' => 'gmail/v1/users/{userId}/settings/sendAs',
'httpMethod' => 'POST',
'parameters' => array(
'userId' => array(
@ -902,7 +915,7 @@ class Google_Service_Gmail extends Google_Service
),
),
),'delete' => array(
'path' => '{userId}/settings/sendAs/{sendAsEmail}',
'path' => 'gmail/v1/users/{userId}/settings/sendAs/{sendAsEmail}',
'httpMethod' => 'DELETE',
'parameters' => array(
'userId' => array(
@ -917,7 +930,7 @@ class Google_Service_Gmail extends Google_Service
),
),
),'get' => array(
'path' => '{userId}/settings/sendAs/{sendAsEmail}',
'path' => 'gmail/v1/users/{userId}/settings/sendAs/{sendAsEmail}',
'httpMethod' => 'GET',
'parameters' => array(
'userId' => array(
@ -932,7 +945,7 @@ class Google_Service_Gmail extends Google_Service
),
),
),'list' => array(
'path' => '{userId}/settings/sendAs',
'path' => 'gmail/v1/users/{userId}/settings/sendAs',
'httpMethod' => 'GET',
'parameters' => array(
'userId' => array(
@ -942,7 +955,7 @@ class Google_Service_Gmail extends Google_Service
),
),
),'patch' => array(
'path' => '{userId}/settings/sendAs/{sendAsEmail}',
'path' => 'gmail/v1/users/{userId}/settings/sendAs/{sendAsEmail}',
'httpMethod' => 'PATCH',
'parameters' => array(
'userId' => array(
@ -957,7 +970,7 @@ class Google_Service_Gmail extends Google_Service
),
),
),'update' => array(
'path' => '{userId}/settings/sendAs/{sendAsEmail}',
'path' => 'gmail/v1/users/{userId}/settings/sendAs/{sendAsEmail}',
'httpMethod' => 'PUT',
'parameters' => array(
'userId' => array(
@ -972,7 +985,7 @@ class Google_Service_Gmail extends Google_Service
),
),
),'verify' => array(
'path' => '{userId}/settings/sendAs/{sendAsEmail}/verify',
'path' => 'gmail/v1/users/{userId}/settings/sendAs/{sendAsEmail}/verify',
'httpMethod' => 'POST',
'parameters' => array(
'userId' => array(
@ -997,7 +1010,7 @@ class Google_Service_Gmail extends Google_Service
array(
'methods' => array(
'delete' => array(
'path' => '{userId}/settings/sendAs/{sendAsEmail}/smimeInfo/{id}',
'path' => 'gmail/v1/users/{userId}/settings/sendAs/{sendAsEmail}/smimeInfo/{id}',
'httpMethod' => 'DELETE',
'parameters' => array(
'userId' => array(
@ -1017,7 +1030,7 @@ class Google_Service_Gmail extends Google_Service
),
),
),'get' => array(
'path' => '{userId}/settings/sendAs/{sendAsEmail}/smimeInfo/{id}',
'path' => 'gmail/v1/users/{userId}/settings/sendAs/{sendAsEmail}/smimeInfo/{id}',
'httpMethod' => 'GET',
'parameters' => array(
'userId' => array(
@ -1037,7 +1050,7 @@ class Google_Service_Gmail extends Google_Service
),
),
),'insert' => array(
'path' => '{userId}/settings/sendAs/{sendAsEmail}/smimeInfo',
'path' => 'gmail/v1/users/{userId}/settings/sendAs/{sendAsEmail}/smimeInfo',
'httpMethod' => 'POST',
'parameters' => array(
'userId' => array(
@ -1052,7 +1065,7 @@ class Google_Service_Gmail extends Google_Service
),
),
),'list' => array(
'path' => '{userId}/settings/sendAs/{sendAsEmail}/smimeInfo',
'path' => 'gmail/v1/users/{userId}/settings/sendAs/{sendAsEmail}/smimeInfo',
'httpMethod' => 'GET',
'parameters' => array(
'userId' => array(
@ -1067,7 +1080,7 @@ class Google_Service_Gmail extends Google_Service
),
),
),'setDefault' => array(
'path' => '{userId}/settings/sendAs/{sendAsEmail}/smimeInfo/{id}/setDefault',
'path' => 'gmail/v1/users/{userId}/settings/sendAs/{sendAsEmail}/smimeInfo/{id}/setDefault',
'httpMethod' => 'POST',
'parameters' => array(
'userId' => array(
@ -1097,7 +1110,7 @@ class Google_Service_Gmail extends Google_Service
array(
'methods' => array(
'delete' => array(
'path' => '{userId}/threads/{id}',
'path' => 'gmail/v1/users/{userId}/threads/{id}',
'httpMethod' => 'DELETE',
'parameters' => array(
'userId' => array(
@ -1112,7 +1125,7 @@ class Google_Service_Gmail extends Google_Service
),
),
),'get' => array(
'path' => '{userId}/threads/{id}',
'path' => 'gmail/v1/users/{userId}/threads/{id}',
'httpMethod' => 'GET',
'parameters' => array(
'userId' => array(
@ -1125,18 +1138,18 @@ class Google_Service_Gmail extends Google_Service
'type' => 'string',
'required' => true,
),
'format' => array(
'location' => 'query',
'type' => 'string',
),
'metadataHeaders' => array(
'location' => 'query',
'type' => 'string',
'repeated' => true,
),
'format' => array(
'location' => 'query',
'type' => 'string',
),
),
),'list' => array(
'path' => '{userId}/threads',
'path' => 'gmail/v1/users/{userId}/threads',
'httpMethod' => 'GET',
'parameters' => array(
'userId' => array(
@ -1144,30 +1157,30 @@ class Google_Service_Gmail extends Google_Service
'type' => 'string',
'required' => true,
),
'includeSpamTrash' => array(
'pageToken' => array(
'location' => 'query',
'type' => 'boolean',
'type' => 'string',
),
'labelIds' => array(
'location' => 'query',
'type' => 'string',
'repeated' => true,
),
'maxResults' => array(
'location' => 'query',
'type' => 'integer',
),
'pageToken' => array(
'location' => 'query',
'type' => 'string',
),
'q' => array(
'location' => 'query',
'type' => 'string',
),
'maxResults' => array(
'location' => 'query',
'type' => 'integer',
),
'includeSpamTrash' => array(
'location' => 'query',
'type' => 'boolean',
),
),
),'modify' => array(
'path' => '{userId}/threads/{id}/modify',
'path' => 'gmail/v1/users/{userId}/threads/{id}/modify',
'httpMethod' => 'POST',
'parameters' => array(
'userId' => array(
@ -1182,7 +1195,7 @@ class Google_Service_Gmail extends Google_Service
),
),
),'trash' => array(
'path' => '{userId}/threads/{id}/trash',
'path' => 'gmail/v1/users/{userId}/threads/{id}/trash',
'httpMethod' => 'POST',
'parameters' => array(
'userId' => array(
@ -1197,7 +1210,7 @@ class Google_Service_Gmail extends Google_Service
),
),
),'untrash' => array(
'path' => '{userId}/threads/{id}/untrash',
'path' => 'gmail/v1/users/{userId}/threads/{id}/untrash',
'httpMethod' => 'POST',
'parameters' => 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
* results.
* @opt_param string maxResults Maximum number of drafts to return.
* @opt_param string pageToken Page token to retrieve a specific page of results
* in the list.
* @opt_param string q Only return draft messages matching the specified query.
* Supports the same query format as the Gmail search box. For example,
* "from:someuser@example.com rfc822msgid: is:unread".
* @opt_param string maxResults Maximum number of drafts to return.
* @return Google_Service_Gmail_ListDraftsResponse
*/
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.
* @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
* 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
* specified startHistoryId. The supplied startHistoryId should be obtained from
* 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
* 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
* 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
* updates to retrieve and you can store the returned historyId for a future
* 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");
}
/**
* Updates the specified label. This method supports patch semantics.
* (labels.patch)
* Patch the specified label. (labels.patch)
*
* @param string $userId The user's email address. The special value me can be
* used to indicate the authenticated user.

View File

@ -26,7 +26,7 @@
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)
*
* @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
* 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
* 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 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
* include headers specified.
* @opt_param string format The format to return the message in.
* @return Google_Service_Gmail_Message
*/
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 array $optParams Optional parameters.
*
* @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
* accounts.
* @opt_param bool processForCalendar Process calendar invites in the email and
* add any extracted meetings to the Google Calendar for this user.
* @opt_param string internalDateSource Source for Gmail's internal date of the
* message.
* @opt_param bool neverMarkSpam Ignore the Gmail spam classifier decision and
* never mark this email as SPAM in the mailbox.
* @opt_param bool processForCalendar Process calendar invites in the email and
* add any extracted meetings to the Google Calendar for this user.
* @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
* accounts.
* @return Google_Service_Gmail_Message
*/
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 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
* only visible in Google Vault to a Vault administrator. Only used for G Suite
* accounts.
* @opt_param string internalDateSource Source for Gmail's internal date of the
* message.
* @return Google_Service_Gmail_Message
*/
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
* 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
* 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.
* Supports the same query format as the Gmail search box. For example,
* "from:someuser@example.com rfc822msgid: is:unread". Parameter cannot be used
* when accessing the api using the gmail.metadata scope.
* "from:someuser@example.com rfc822msgid:somemsgid@example.com is:unread".
* 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
*/
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.
* (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.
* @param array $optParams Optional parameters.
* @return Google_Service_Gmail_AutoForwarding
@ -43,7 +43,7 @@ class Google_Service_Gmail_Resource_UsersSettings extends Google_Service_Resourc
/**
* 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.
* @param array $optParams Optional parameters.
* @return Google_Service_Gmail_ImapSettings
@ -57,7 +57,7 @@ class Google_Service_Gmail_Resource_UsersSettings extends Google_Service_Resourc
/**
* 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.
* @param array $optParams Optional parameters.
* @return Google_Service_Gmail_LanguageSettings
@ -71,7 +71,7 @@ class Google_Service_Gmail_Resource_UsersSettings extends Google_Service_Resourc
/**
* 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.
* @param array $optParams Optional parameters.
* @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)
*
* @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.
* @param array $optParams Optional parameters.
* @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");
}
/**
* 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.
*
* This method is only available to service account clients that have been
* 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.
* @param Google_Service_Gmail_AutoForwarding $postBody
* @param array $optParams Optional parameters.
@ -118,7 +118,7 @@ class Google_Service_Gmail_Resource_UsersSettings extends Google_Service_Resourc
/**
* 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.
* @param Google_Service_Gmail_ImapSettings $postBody
* @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
* 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.
* @param Google_Service_Gmail_LanguageSettings $postBody
* @param array $optParams Optional parameters.
@ -154,7 +154,7 @@ class Google_Service_Gmail_Resource_UsersSettings extends Google_Service_Resourc
/**
* 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.
* @param Google_Service_Gmail_PopSettings $postBody
* @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)
*
* @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.
* @param Google_Service_Gmail_VacationSettings $postBody
* @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,
* without sending any verification email. The delegate user must be a member of
* the same G Suite organization as the delegator user.
* without sending any verification email. The delegate user must be a member
* 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,
* 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
* 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.
* @param Google_Service_Gmail_Delegate $postBody
* @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
* 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.
* @param string $delegateEmail The email address of the user to be removed as a
* 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
* 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.
* @param string $delegateEmail The email address of the user whose delegate
* 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
* 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.
* @param array $optParams Optional parameters.
* @return Google_Service_Gmail_ListDelegatesResponse

View File

@ -26,7 +26,7 @@
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
* will be set to pending; otherwise, the resource will be created with
* 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
* 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.
* @param Google_Service_Gmail_ForwardingAddress $postBody
* @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
* 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.
* @param string $forwardingEmail The forwarding address to be deleted.
* @param array $optParams Optional parameters.
@ -67,7 +67,7 @@ class Google_Service_Gmail_Resource_UsersSettingsForwardingAddresses extends Goo
/**
* 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.
* @param string $forwardingEmail The forwarding address to be retrieved.
* @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.
* (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.
* @param array $optParams Optional parameters.
* @return Google_Service_Gmail_ListForwardingAddressesResponse

View File

@ -26,18 +26,18 @@
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
* 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
* verification status will be set to pending; otherwise, the resource will be
* created with verification status set to accepted. If a signature is provided,
* Gmail will sanitize the HTML before saving it with the alias.
* created with verification status set to accepted. If a signature is
* provided, Gmail will sanitize the HTML before saving it with the alias.
*
* This method is only available to service account clients that have been
* 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.
* @param Google_Service_Gmail_SendAs $postBody
* @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");
}
/**
* 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.
*
* This method is only available to service account clients that have been
* 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.
* @param string $sendAsEmail The send-as alias to be deleted.
* @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));
}
/**
* 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)
*
* @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.
* @param string $sendAsEmail The send-as alias to be retrieved.
* @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");
}
/**
* 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
* "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.
* @param array $optParams Optional parameters.
* @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");
}
/**
* Updates a send-as alias. If a signature is provided, Gmail will sanitize the
* HTML before saving it with the alias.
* Patch the specified send-as alias. (sendAs.patch)
*
* Addresses other than the primary address for the account can only be updated
* 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
* @param string $userId User's email address. The special value "me" can be
* used to indicate the authenticated user.
* @param string $sendAsEmail The send-as alias to be updated.
* @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");
}
/**
* 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.
*
* Addresses other than the primary address for the account can only be updated
* by service account clients that have been delegated domain-wide authority.
* (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.
* @param string $sendAsEmail The send-as alias to be updated.
* @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
* 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.
* @param string $sendAsEmail The send-as alias to be verified.
* @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 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
* include headers specified.
* @opt_param string format The format to return the messages in.
* @return Google_Service_Gmail_Thread
*/
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.
* @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
* 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.
* Supports the same query format as the Gmail search box. For example,
* "from:someuser@example.com rfc822msgid: is:unread". Parameter cannot be used
* 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
*/
public function listUsersThreads($userId, $optParams = array())

View File

@ -38,7 +38,7 @@ use Monolog\Handler\SyslogHandler as MonologSyslogHandler;
*/
class Google_Client
{
const LIBVER = "2.2.3";
const LIBVER = "2.4.1";
const USER_AGENT_SUFFIX = "google-api-php-client/";
const OAUTH2_REVOKE_URI = 'https://oauth2.googleapis.com/revoke';
const OAUTH2_TOKEN_URI = 'https://oauth2.googleapis.com/token';
@ -142,6 +142,10 @@ class Google_Client
// Service class used in Google_Client::verifyIdToken.
// Explicitly pass this in to avoid setting JWT::$leeway
'jwt' => null,
// Setting api_format_v2 will return more detailed error messages
// from certain APIs.
'api_format_v2' => false
],
$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
* @throws InvalidArgumentException
*/
@ -789,12 +804,31 @@ class Google_Client
*/
public function execute(RequestInterface $request, $expectedClass = null)
{
$request = $request->withHeader(
'User-Agent',
$this->config['application_name']
. " " . self::USER_AGENT_SUFFIX
. $this->getLibraryVersion()
);
$request = $request
->withHeader(
'User-Agent',
sprintf(
'%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
// this is where most of the grunt work is done
@ -1056,6 +1090,18 @@ class Google_Client
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()
{
$options = ['exceptions' => false];

View File

@ -67,9 +67,11 @@ class Google_Http_MediaFileUpload
private $httpResultCode;
/**
* @param $mimeType string
* @param $data string The bytes you want to upload.
* @param $resumable bool
* @param Google_Client $client
* @param RequestInterface $request
* @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.
* only used if resumable=True
*/

View File

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

View File

@ -17,6 +17,8 @@
namespace Google\Auth;
use DateTime;
use Exception;
use Firebase\JWT\ExpiredException;
use Firebase\JWT\JWT;
use Firebase\JWT\SignatureInvalidException;
@ -25,9 +27,16 @@ use Google\Auth\HttpHandler\HttpClientCache;
use Google\Auth\HttpHandler\HttpHandlerFactory;
use GuzzleHttp\Psr7;
use GuzzleHttp\Psr7\Request;
use InvalidArgumentException;
use phpseclib\Crypt\RSA;
use phpseclib\Math\BigInteger;
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.
@ -37,6 +46,8 @@ use Psr\Cache\CacheItemPoolInterface;
class AccessToken
{
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_HTTPS = 'https://accounts.google.com';
const OAUTH2_REVOKE_URI = 'https://oauth2.googleapis.com/revoke';
@ -59,19 +70,9 @@ class AccessToken
callable $httpHandler = 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
?: HttpHandlerFactory::build(HttpClientCache::getHttpClient());
$this->cache = $cache ?: new MemoryCacheItemPool();
$this->configureJwtService();
// set phpseclib constants if applicable
$this->setPhpsecConstants();
}
/**
@ -85,87 +86,215 @@ class AccessToken
* Configuration options.
*
* @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
* to retrieve certificates, if not cached. This value should only be
* provided in limited circumstances in which you are sure of the
* 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.
* @throws \InvalidArgumentException If certs could not be retrieved from a local file.
* @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 certs could not be retrieved from a local file.
* @throws InvalidArgumentException If received certs are in an invalid format.
* @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 = [])
{
$audience = isset($options['audience'])
? $options['audience']
: null;
$issuer = isset($options['issuer'])
? $options['issuer']
: null;
$certsLocation = isset($options['certsLocation'])
? $options['certsLocation']
: self::FEDERATED_SIGNON_CERT_URL;
unset($options['audience'], $options['certsLocation']);
$cacheKey = isset($options['cacheKey'])
? $options['cacheKey']
: $this->getCacheKeyFromCertLocation($certsLocation);
$throwException = isset($options['throwException'])
? $options['throwException']
: false; // for backwards compatibility
// Check signature against each available cert.
// allow the loop to complete unless a known bad result is encountered.
$certs = $this->getFederatedSignOnCerts($certsLocation, $options);
foreach ($certs as $cert) {
$rsa = new RSA();
$rsa->loadKey([
'n' => new BigInteger($this->callJwtStatic('urlsafeB64Decode', [
$cert['n']
]), 256),
'e' => new BigInteger($this->callJwtStatic('urlsafeB64Decode', [
$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
$certs = $this->getCerts($certsLocation, $cacheKey, $options);
$alg = $this->determineAlg($certs);
if (!in_array($alg, ['RS256', 'ES256'])) {
throw new InvalidArgumentException(
'unrecognized "alg" in certs, expected ES256 or RS256');
}
try {
if ($alg == 'RS256') {
return $this->verifyRs256($token, $certs, $audience, $issuer);
}
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;
}
/**
* 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
* token, if a token isn't provided.
*
* @param string|array $token The token (access token or a refresh token) that should be revoked.
* @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 = [])
{
@ -198,11 +327,11 @@ class AccessToken
* @param string $location The location from which to retrieve certs.
* @param array $options [optional] Configuration options.
* @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;
$gotNewCerts = false;
@ -213,15 +342,20 @@ class AccessToken
}
if (!isset($certs['keys'])) {
throw new \InvalidArgumentException(
'federated sign-on certs expects "keys" to be set'
if ($location !== self::IAP_CERT_URL) {
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.
// Don't want to cache bad data.
if ($gotNewCerts) {
$cacheItem->expiresAt(new \DateTime('+1 hour'));
$cacheItem->expiresAt(new DateTime('+1 hour'));
$cacheItem->set($certs);
$this->cache->save($cacheItem);
}
@ -234,17 +368,16 @@ class AccessToken
*
* @param $url string location
* @param array $options [optional] Configuration options.
* @throws \RuntimeException
* @return array certificates
* @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 InvalidArgumentException If certs could not be retrieved from a local file.
* @throws RuntimeException If certs could not be retrieved from a remote location.
*/
private function retrieveCertsFromLocation($url, array $options = [])
{
// If we're retrieving a local file, just grab it.
if (strpos($url, 'http') !== 0) {
if (!file_exists($url)) {
throw new \InvalidArgumentException(sprintf(
throw new InvalidArgumentException(sprintf(
'Failed to retrieve verification certificates from path: %s.',
$url
));
@ -260,26 +393,30 @@ class AccessToken
return json_decode((string) $response->getBody(), true);
}
throw new \RuntimeException(sprintf(
throw new RuntimeException(sprintf(
'Failed to retrieve verification certificates: "%s".',
$response->getBody()->getContents()
), $response->getStatusCode());
}
/**
* Set required defaults for JWT.
*/
private function configureJwtService()
private function checkAndInitializePhpsec()
{
$class = class_exists('Firebase\JWT\JWT')
? 'Firebase\JWT\JWT'
: '\JWT';
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;
// @codeCoverageIgnoreStart
if (!class_exists('phpseclib\Crypt\RSA')) {
throw new RuntimeException('Please require phpseclib/phpseclib v2 to use this utility.');
}
// @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';
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 Google\Auth\Credentials\AppIdentityCredentials;
use Google\Auth\Credentials\GCECredentials;
use Google\Auth\Credentials\ServiceAccountCredentials;
use Google\Auth\HttpHandler\HttpClientCache;
use Google\Auth\HttpHandler\HttpHandlerFactory;
use Google\Auth\Middleware\AuthTokenMiddleware;
use Google\Auth\Subscriber\AuthTokenSubscriber;
use GuzzleHttp\Client;
use InvalidArgumentException;
use Psr\Cache\CacheItemPoolInterface;
/**
@ -121,8 +123,9 @@ class ApplicationDefaultCredentials
}
/**
* Obtains the default FetchAuthTokenInterface implementation to use
* in this environment.
* Obtains an AuthTokenMiddleware which will fetch an access token to use in
* 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
* this does not fallback to the Compute Engine defaults.
@ -165,7 +168,97 @@ class ApplicationDefaultCredentials
}
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)) {
$creds = new FetchAuthTokenCache($creds, $cacheConfig, $cache);

View File

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

View File

@ -24,6 +24,7 @@ namespace Google\Auth\Credentials;
*/
use google\appengine\api\app_identity\AppIdentityService;
use Google\Auth\CredentialsLoader;
use Google\Auth\ProjectIdProviderInterface;
use Google\Auth\SignBlobInterface;
/**
@ -32,35 +33,42 @@ use Google\Auth\SignBlobInterface;
* It can be used to authorize requests using the AuthTokenMiddleware or
* AuthTokenSubscriber, but will only succeed if being run on App Engine:
*
* use Google\Auth\Credentials\AppIdentityCredentials;
* use Google\Auth\Middleware\AuthTokenMiddleware;
* use GuzzleHttp\Client;
* use GuzzleHttp\HandlerStack;
* Example:
* ```
* use Google\Auth\Credentials\AppIdentityCredentials;
* use Google\Auth\Middleware\AuthTokenMiddleware;
* use GuzzleHttp\Client;
* use GuzzleHttp\HandlerStack;
*
* $gae = new AppIdentityCredentials('https://www.googleapis.com/auth/books');
* $middleware = new AuthTokenMiddleware($gae);
* $stack = HandlerStack::create();
* $stack->push($middleware);
* $gae = new AppIdentityCredentials('https://www.googleapis.com/auth/books');
* $middleware = new AuthTokenMiddleware($gae);
* $stack = HandlerStack::create();
* $stack->push($middleware);
*
* $client = new Client([
* 'handler' => $stack,
* 'base_uri' => 'https://www.googleapis.com/books/v1',
* 'auth' => 'google_auth'
* ]);
* $client = new Client([
* 'handler' => $stack,
* 'base_uri' => 'https://www.googleapis.com/books/v1',
* '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.
*
* @array
* @var array
*/
protected $lastReceivedToken;
/**
* Array of OAuth2 scopes to be requested.
*
* @var array
*/
private $scope;
@ -69,6 +77,9 @@ class AppIdentityCredentials extends CredentialsLoader implements SignBlobInterf
*/
private $clientName;
/**
* @param array $scope One or more scopes.
*/
public function __construct($scope = array())
{
$this->scope = $scope;
@ -143,6 +154,25 @@ class AppIdentityCredentials extends CredentialsLoader implements SignBlobInterf
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.
*

View File

@ -21,11 +21,13 @@ use Google\Auth\CredentialsLoader;
use Google\Auth\HttpHandler\HttpClientCache;
use Google\Auth\HttpHandler\HttpHandlerFactory;
use Google\Auth\Iam;
use Google\Auth\ProjectIdProviderInterface;
use Google\Auth\SignBlobInterface;
use GuzzleHttp\Exception\ClientException;
use GuzzleHttp\Exception\RequestException;
use GuzzleHttp\Exception\ServerException;
use GuzzleHttp\Psr7\Request;
use InvalidArgumentException;
/**
* GCECredentials supports authorization on Google Compute Engine.
@ -51,7 +53,9 @@ use GuzzleHttp\Psr7\Request;
*
* $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';
@ -68,11 +72,21 @@ class GCECredentials extends CredentialsLoader implements SignBlobInterface
*/
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.
*/
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.
*/
@ -111,10 +125,15 @@ class GCECredentials extends CredentialsLoader implements SignBlobInterface
protected $lastReceivedToken;
/**
* @var string
* @var string|null
*/
private $clientName;
/**
* @var string|null
*/
private $projectId;
/**
* @var Iam|null
*/
@ -125,15 +144,26 @@ class GCECredentials extends CredentialsLoader implements SignBlobInterface
*/
private $tokenUri;
/**
* @var string
*/
private $targetAudience;
/**
* @param Iam $iam [optional] An IAM instance.
* @param string|array $scope [optional] the scope of the access request,
* 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;
if ($scope && $targetAudience) {
throw new InvalidArgumentException(
'Scope and targetAudience cannot both be supplied');
}
$tokenUri = self::getTokenUri();
if ($scope) {
if (is_string($scope)) {
@ -143,6 +173,13 @@ class GCECredentials extends CredentialsLoader implements SignBlobInterface
$scope = implode(',', $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;
@ -172,6 +209,18 @@ class GCECredentials extends CredentialsLoader implements SignBlobInterface
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
* 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.
*
* @param callable $httpHandler callback which delivers psr7 request
*
* @return true if this a GCEInstance false otherwise
* @return bool True if this a GCEInstance, false otherwise
*/
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
*
* @return array A set of auth related metadata, containing the following
* keys:
* @return array A set of auth related metadata, based on the token type.
*
* Access tokens have the following keys:
* - access_token (string)
* - expires_in (int)
* - token_type (string)
* ID tokens have the following keys:
* - id_token (string)
*
* @throws \Exception
*/
@ -255,8 +306,13 @@ class GCECredentials extends CredentialsLoader implements SignBlobInterface
return array(); // return an empty array with no access token
}
$json = $this->getFromMetadata($httpHandler, $this->tokenUri);
if (null === $json = json_decode($json, true)) {
$response = $this->getFromMetadata($httpHandler, $this->tokenUri);
if ($this->targetAudience) {
return ['id_token' => $response];
}
if (null === $json = json_decode($response, true)) {
throw new \Exception('Invalid JSON response');
}
@ -351,6 +407,36 @@ class GCECredentials extends CredentialsLoader implements SignBlobInterface
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.
*

View File

@ -18,9 +18,12 @@
namespace Google\Auth\Credentials;
use Google\Auth\CredentialsLoader;
use Google\Auth\GetQuotaProjectInterface;
use Google\Auth\OAuth2;
use Google\Auth\ProjectIdProviderInterface;
use Google\Auth\ServiceAccountSignerTrait;
use Google\Auth\SignBlobInterface;
use InvalidArgumentException;
/**
* ServiceAccountCredentials supports authorization using a Google service
@ -55,7 +58,10 @@ use Google\Auth\SignBlobInterface;
*
* $res = $client->get('myproject/taskqueues/myqueue');
*/
class ServiceAccountCredentials extends CredentialsLoader implements SignBlobInterface
class ServiceAccountCredentials extends CredentialsLoader implements
GetQuotaProjectInterface,
SignBlobInterface,
ProjectIdProviderInterface
{
use ServiceAccountSignerTrait;
@ -66,6 +72,18 @@ class ServiceAccountCredentials extends CredentialsLoader implements SignBlobInt
*/
protected $auth;
/**
* The quota project associated with the JSON credentials
*
* @var string
*/
protected $quotaProject;
/*
* @var string|null
*/
protected $projectId;
/**
* Create a new ServiceAccountCredentials.
*
@ -75,11 +93,13 @@ class ServiceAccountCredentials extends CredentialsLoader implements SignBlobInt
* as an associative array
* @param string $sub an email address account to impersonate, in situations when
* the service account has been delegated domain wide access.
* @param string $targetAudience The audience for the ID token.
*/
public function __construct(
$scope,
$jsonKey,
$sub = null
$sub = null,
$targetAudience = null
) {
if (is_string($jsonKey)) {
if (!file_exists($jsonKey)) {
@ -98,6 +118,17 @@ class ServiceAccountCredentials extends CredentialsLoader implements SignBlobInt
throw new \InvalidArgumentException(
'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([
'audience' => self::TOKEN_CREDENTIAL_URI,
'issuer' => $jsonKey['client_email'],
@ -106,7 +137,12 @@ class ServiceAccountCredentials extends CredentialsLoader implements SignBlobInt
'signingKey' => $jsonKey['private_key'],
'sub' => $sub,
'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();
}
/**
* 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.
*
@ -195,4 +244,14 @@ class ServiceAccountCredentials extends CredentialsLoader implements SignBlobInt
{
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;
use Google\Auth\CredentialsLoader;
use Google\Auth\GetQuotaProjectInterface;
use Google\Auth\OAuth2;
use Google\Auth\ProjectIdProviderInterface;
use Google\Auth\ServiceAccountSignerTrait;
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
* 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;
@ -42,6 +47,11 @@ class ServiceAccountJwtAccessCredentials extends CredentialsLoader implements Si
*/
protected $auth;
/**
* The quota project associated with the JSON credentials
*/
protected $quotaProject;
/**
* Create a new ServiceAccountJwtAccessCredentials.
*
@ -67,12 +77,19 @@ class ServiceAccountJwtAccessCredentials extends CredentialsLoader implements Si
throw new \InvalidArgumentException(
'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([
'issuer' => $jsonKey['client_email'],
'sub' => $jsonKey['client_email'],
'signingAlgorithm' => 'RS256',
'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();
}
/**
* 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.
*
@ -147,4 +177,14 @@ class ServiceAccountJwtAccessCredentials extends CredentialsLoader implements Si
{
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;
use Google\Auth\CredentialsLoader;
use Google\Auth\GetQuotaProjectInterface;
use Google\Auth\OAuth2;
/**
@ -31,7 +32,7 @@ use Google\Auth\OAuth2;
*
* @see [Application Default Credentials](http://goo.gl/mkAHpZ)
*/
class UserRefreshCredentials extends CredentialsLoader
class UserRefreshCredentials extends CredentialsLoader implements GetQuotaProjectInterface
{
const CLOUD_SDK_CLIENT_ID =
'764086051850-6qr4p6gpi6hn506pt8ejuq83di341hur.apps.googleusercontent.com';
@ -45,6 +46,11 @@ class UserRefreshCredentials extends CredentialsLoader
*/
protected $auth;
/**
* The quota project associated with the JSON credentials
*/
protected $quotaProject;
/**
* Create a new UserRefreshCredentials.
*
@ -85,7 +91,11 @@ class UserRefreshCredentials extends CredentialsLoader
'scope' => $scope,
'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
&& is_null($this->quotaProject)
&& getenv(self::SUPPRESS_CLOUD_SDK_CREDS_WARNING_ENV) !== 'true') {
trigger_error(
'Your application has authenticated using end user credentials '
@ -134,4 +144,14 @@ class UserRefreshCredentials extends CredentialsLoader
{
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
* FetchAuthTokenInterface
*/
class FetchAuthTokenCache implements FetchAuthTokenInterface, SignBlobInterface
class FetchAuthTokenCache implements
FetchAuthTokenInterface,
GetQuotaProjectInterface,
SignBlobInterface,
ProjectIdProviderInterface
{
use CacheTrait;
@ -139,4 +143,37 @@ class FetchAuthTokenCache implements FetchAuthTokenInterface, SignBlobInterface
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;
use Google\Auth\FetchAuthTokenInterface;
use Google\Auth\GetQuotaProjectInterface;
use Psr\Http\Message\RequestInterface;
/**
@ -101,6 +102,13 @@ class AuthTokenMiddleware
$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);
};
}
@ -122,5 +130,16 @@ class AuthTokenMiddleware
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;
use Google\Auth\FetchAuthTokenInterface;
use Google\Auth\GetQuotaProjectInterface;
use GuzzleHttp\Event\BeforeEvent;
use GuzzleHttp\Event\RequestEvents;
use GuzzleHttp\Event\SubscriberInterface;
@ -114,5 +115,19 @@ class AuthTokenSubscriber implements SubscriberInterface
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;
use GuzzleHttp\Cookie\CookieJar;
use GuzzleHttp\Exception\InvalidArgumentException;
use GuzzleHttp\Promise;
use GuzzleHttp\Psr7;
use Psr\Http\Message\UriInterface;
use Psr\Http\Message\RequestInterface;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\UriInterface;
/**
* @method ResponseInterface get(string|UriInterface $uri, array $options = [])
@ -75,6 +76,12 @@ class Client implements ClientInterface
$this->configureDefaults($config);
}
/**
* @param string $method
* @param array $args
*
* @return Promise\PromiseInterface
*/
public function __call($method, $args)
{
if (count($args) < 1) {
@ -89,6 +96,14 @@ class Client implements ClientInterface
: $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 = [])
{
// 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 = [])
{
$options[RequestOptions::SYNCHRONOUS] = true;
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 = [])
{
$options = $this->prepareDefaults($options);
@ -125,12 +163,37 @@ class Client implements ClientInterface
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 = [])
{
$options[RequestOptions::SYNCHRONOUS] = true;
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)
{
return $option === null
@ -138,6 +201,11 @@ class Client implements ClientInterface
: (isset($this->config[$option]) ? $this->config[$option] : null);
}
/**
* @param string|null $uri
*
* @return UriInterface
*/
private function buildUri($uri, array $config)
{
// 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);
}
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;
}
@ -154,6 +227,7 @@ class Client implements ClientInterface
* Configures the default options for a client.
*
* @param array $config
* @return void
*/
private function configureDefaults(array $config)
{
@ -162,7 +236,8 @@ class Client implements ClientInterface
'http_errors' => true,
'decode_content' => true,
'verify' => true,
'cookies' => false
'cookies' => false,
'idn_conversion' => true,
];
// 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
// process due to the fact that PHP has no reliable mechanism to
// 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');
}
@ -225,7 +300,7 @@ class Client implements ClientInterface
if (array_key_exists('headers', $options)) {
// Allows default headers to be unset.
if ($options['headers'] === null) {
$defaults['_conditional'] = null;
$defaults['_conditional'] = [];
unset($options['headers']);
} elseif (!is_array($options['headers'])) {
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
* as-is without merging in default options.
*
* @param RequestInterface $request
* @param array $options
* @param array $options See \GuzzleHttp\RequestOptions.
*
* @return Promise\PromiseInterface
*/
@ -271,6 +345,7 @@ class Client implements ClientInterface
}
$request = $this->applyOptions($request, $options);
/** @var HandlerStack $handler */
$handler = $options['handler'];
try {
@ -411,6 +486,11 @@ class Client implements ClientInterface
return $request;
}
/**
* Throw Exception with pre-set message.
* @return void
* @throws InvalidArgumentException Invalid body.
*/
private function invalidBody()
{
throw new \InvalidArgumentException('Passing in the "body" request '

View File

@ -1,8 +1,8 @@
<?php
namespace GuzzleHttp;
use GuzzleHttp\Promise\PromiseInterface;
use GuzzleHttp\Exception\GuzzleException;
use GuzzleHttp\Promise\PromiseInterface;
use Psr\Http\Message\RequestInterface;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\UriInterface;
@ -12,7 +12,10 @@ use Psr\Http\Message\UriInterface;
*/
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.

View File

@ -94,8 +94,8 @@ class CookieJar implements CookieJarInterface
*/
public function getCookieByName($name)
{
// don't allow a null name
if ($name === null) {
// don't allow a non string name
if ($name === null || !is_scalar($name)) {
return null;
}
foreach ($this->cookies as $cookie) {
@ -103,6 +103,8 @@ class CookieJar implements CookieJarInterface
return $cookie;
}
}
return null;
}
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
* removed.
*
* @param string $domain Clears cookies matching a domain
* @param string $path Clears cookies matching a domain and path
* @param string $name Clears cookies matching a domain, path, and name
* @param string|null $domain Clears cookies matching a domain
* @param string|null $path Clears cookies matching a domain and path
* @param string|null $name Clears cookies matching a domain, path, and name
*
* @return CookieJarInterface
*/

View File

@ -1,9 +1,9 @@
<?php
namespace GuzzleHttp\Exception;
use GuzzleHttp\Promise\PromiseInterface;
use Psr\Http\Message\RequestInterface;
use Psr\Http\Message\ResponseInterface;
use GuzzleHttp\Promise\PromiseInterface;
use Psr\Http\Message\UriInterface;
/**
@ -14,7 +14,7 @@ class RequestException extends TransferException
/** @var RequestInterface */
private $request;
/** @var ResponseInterface */
/** @var ResponseInterface|null */
private $response;
/** @var array */
@ -124,42 +124,17 @@ class RequestException extends TransferException
*/
public static function getResponseBodySummary(ResponseInterface $response)
{
$body = $response->getBody();
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;
return \GuzzleHttp\Psr7\get_message_body_summary($response);
}
/**
* 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
*
* @return UriInterface
*/
private static function obfuscateUri($uri)
private static function obfuscateUri(UriInterface $uri)
{
$userInfo = $uri->getUserInfo();

View File

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

View File

@ -1,9 +1,10 @@
<?php
namespace GuzzleHttp\Handler;
use GuzzleHttp\Exception\InvalidArgumentException;
use GuzzleHttp\Promise as P;
use GuzzleHttp\Promise\Promise;
use GuzzleHttp\Psr7;
use GuzzleHttp\Utils;
use Psr\Http\Message\RequestInterface;
/**
@ -23,6 +24,7 @@ class CurlMultiHandler
private $active;
private $handles = [];
private $delays = [];
private $options = [];
/**
* This handler accepts the following options:
@ -30,6 +32,8 @@ class CurlMultiHandler
* - handle_factory: An optional factory used to create curl handles
* - select_timeout: Optional timeout (in seconds) to block before timing
* 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
*/
@ -45,12 +49,23 @@ class CurlMultiHandler
} else {
$this->selectTimeout = 1;
}
$this->options = isset($options['options']) ? $options['options'] : [];
}
public function __get($name)
{
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();
@ -88,7 +103,7 @@ class CurlMultiHandler
{
// Add any delayed handles if needed.
if ($this->delays) {
$currentTime = \GuzzleHttp\_current_time();
$currentTime = Utils::currentTime();
foreach ($this->delays as $id => $delay) {
if ($currentTime >= $delay) {
unset($this->delays[$id]);
@ -140,7 +155,7 @@ class CurlMultiHandler
if (empty($easy->options['delay'])) {
curl_multi_add_handle($this->_mh, $easy->handle);
} 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()
{
$currentTime = \GuzzleHttp\_current_time();
$currentTime = Utils::currentTime();
$nextTime = PHP_INT_MAX;
foreach ($this->delays as $time) {
if ($time < $nextTime) {

View File

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

View File

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

View File

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

View File

@ -1,9 +1,10 @@
<?php
namespace GuzzleHttp;
use GuzzleHttp\Promise\EachPromise;
use GuzzleHttp\Promise\PromiseInterface;
use GuzzleHttp\Promise\PromisorInterface;
use Psr\Http\Message\RequestInterface;
use GuzzleHttp\Promise\EachPromise;
/**
* 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);
}
/**
* Get promise
*
* @return PromiseInterface
*/
public function promise()
{
return $this->each->promise();
@ -106,6 +112,11 @@ class Pool implements PromisorInterface
return $res;
}
/**
* Execute callback(s)
*
* @return void
*/
private static function cmpCallback(array &$options, $name, array &$results)
{
if (!isset($options[$name])) {

View File

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

View File

@ -13,7 +13,7 @@ use Psr\Http\Message\UriInterface;
* Request redirect middleware.
*
* Apply this middleware like other middleware using
* {@see GuzzleHttp\Middleware::redirect()}.
* {@see \GuzzleHttp\Middleware::redirect()}.
*/
class RedirectMiddleware
{
@ -76,7 +76,7 @@ class RedirectMiddleware
/**
* @param RequestInterface $request
* @param array $options
* @param ResponseInterface|PromiseInterface $response
* @param ResponseInterface $response
*
* @return ResponseInterface|PromiseInterface
*/
@ -118,6 +118,11 @@ class RedirectMiddleware
return $promise;
}
/**
* Enable tracking on promise.
*
* @return PromiseInterface
*/
private function withTracking(PromiseInterface $promise, $uri, $statusCode)
{
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)
{
$current = isset($options['__redirect_count'])
@ -172,13 +184,19 @@ class RedirectMiddleware
// would do.
$statusCode = $response->getStatusCode();
if ($statusCode == 303 ||
($statusCode <= 302 && $request->getBody() && !$options['allow_redirects']['strict'])
($statusCode <= 302 && !$options['allow_redirects']['strict'])
) {
$modify['method'] = 'GET';
$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);
// 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';
/**
* 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
* encoded and a Content-Type header of application/json will be added to

View File

@ -47,11 +47,11 @@ class RetryMiddleware
*
* @param int $retries
*
* @return int
* @return int milliseconds.
*/
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)
{
return function ($value) use ($req, $options) {
@ -90,6 +95,11 @@ class RetryMiddleware
};
}
/**
* Execute rejected closure
*
* @return callable
*/
private function onRejected(RequestInterface $req, array $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)
{
$options['delay'] = call_user_func($this->delay, ++$options['retries'], $response);

View File

@ -18,11 +18,11 @@ final class TransferStats
private $handlerErrorData;
/**
* @param RequestInterface $request Request that was sent.
* @param ResponseInterface $response Response received (if any)
* @param float|null $transferTime Total handler transfer time.
* @param mixed $handlerErrorData Handler error data.
* @param array $handlerStats Handler specific stats.
* @param RequestInterface $request Request that was sent.
* @param ResponseInterface|null $response Response received (if any)
* @param float|null $transferTime Total handler transfer time.
* @param mixed $handlerErrorData Handler error data.
* @param array $handlerStats Handler specific stats.
*/
public function __construct(
RequestInterface $request,
@ -93,7 +93,7 @@ final class TransferStats
/**
* 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()
{

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.
*
* @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"
* @return array
*/
@ -97,8 +97,8 @@ function debug_resource($value = null)
*
* 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.
* @throws \RuntimeException if no viable Handler is available.
*/
function choose_handler()
{
@ -332,15 +332,3 @@ function json_encode($value, $options = 0, $depth = 512)
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;
use Monolog\Utils;
/**
* Class FluentdFormatter
*
@ -71,7 +73,7 @@ class FluentdFormatter implements FormatterInterface
$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)

View File

@ -11,6 +11,7 @@
namespace Monolog\Formatter;
use Monolog\Logger;
use Monolog\Utils;
/**
* Formats incoming records into an HTML table
@ -133,9 +134,9 @@ class HtmlFormatter extends NormalizerFormatter
$data = $this->normalize($data);
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';
}
if (is_array($data) || $data instanceof \Traversable) {
if (is_array($data)) {
$normalized = array();
$count = 1;
@ -165,6 +165,10 @@ class JsonFormatter extends NormalizerFormatter
return $this->normalizeException($data);
}
if (is_resource($data)) {
return parent::normalize($data);
}
return $data;
}
@ -186,7 +190,7 @@ class JsonFormatter extends NormalizerFormatter
$data = array(
'class' => Utils::getClass($e),
'message' => $e->getMessage(),
'code' => $e->getCode(),
'code' => (int) $e->getCode(),
'file' => $e->getFile().':'.$e->getLine(),
);

View File

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

View File

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

View File

@ -129,7 +129,7 @@ class NormalizerFormatter implements FormatterInterface
$data = array(
'class' => Utils::getClass($e),
'message' => $e->getMessage(),
'code' => $e->getCode(),
'code' => (int) $e->getCode(),
'file' => $e->getFile().':'.$e->getLine(),
);
@ -142,8 +142,8 @@ class NormalizerFormatter implements FormatterInterface
$data['faultactor'] = $e->faultactor;
}
if (isset($e->detail)) {
$data['detail'] = $e->detail;
if (isset($e->detail) && (is_string($e->detail) || is_object($e->detail) || is_array($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)
{
// suppress json_encode errors since it's twitchy with some inputs
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
);
}
return Utils::jsonEncode($data, null, $ignoreErrors);
}
}

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