96e37147 by Jeff Balicki

plugins

Signed-off-by: Jeff <jeff@gotenzing.com>
1 parent 19caef7d
Showing 169 changed files with 4804 additions and 0 deletions
MC4WP: Mailchimp for WordPress
======================
![PHP status](https://github.com/ibericode/mailchimp-for-wordpress/workflows/PHP/badge.svg)
![ESLint status](https://github.com/ibericode/mailchimp-for-wordpress/workflows/ESLint/badge.svg)
![Active installs](https://img.shields.io/wordpress/plugin/installs/mailchimp-for-wp.svg)
![Downloads](https://img.shields.io/wordpress/plugin/dt/mailchimp-for-wp.svg)
[![Rating](https://img.shields.io/wordpress/plugin/r/mailchimp-for-wp.svg)](https://wordpress.org/support/plugin/mailchimp-for-wp/reviews/)
[![License: GPLv3](https://img.shields.io/badge/License-GPLv3-blue.svg)](https://www.gnu.org/licenses/gpl-3.0)
Here, you can browse the source code of the [MC4WP: Mailchimp for WordPress Plugin](https://wordpress.org/plugins/mailchimp-for-wp/), find and discuss open issues or contribute code to the plugin.
Requirements
--------------
- PHP version 7.2 or higher
- WordPress version 4.6 or higher
Installation
------------
If you just want to install this plugin on your WordPress site, please download and install the latest version from WordPress.org: [Mailchimp for WordPress plugin on WordPress.org](https://wordpress.org/plugins/mailchimp-for-wp/).
To install the development version, take the following steps:
1. Clone the GitHub repository:
```
git clone https://github.com/ibericode/mailchimp-for-wordpress.git mailchimp-for-wp
```
1. Install Composer dependencies:
```sh
composer install
```
1. Install NPM dependencies:
```
npm install
```
1. Generate plugin asset files:
```
npm run build
```
1. Activate the plugin in your WordPress admin panel.
Bugs
----
If you think you've found a bug, [please open an issue here](https://github.com/ibericode/mailchimp-for-wordpress/issues?state=open)!
Translations
-------------
You can help [help translate Mailchimp for WordPress](https://translate.wordpress.org/projects/wp-plugins/mailchimp-for-wp/stable/) on WordPress.org.
Support
-------
This is a developer's portal for the Mailchimp for WordPress plugin and should not be used for support.
Please visit the [Mailchimp for WordPress support forum on WordPress.org](https://wordpress.org/support/plugin/mailchimp-for-wp).
If you need priority support, [upgrade to Mailchimp for WordPress Premium](https://www.mc4wp.com/).
Developers
----------
Looking for code snippets? Have a look at the [sample code snippets directory](https://github.com/ibericode/mailchimp-for-wordpress/tree/master/sample-code-snippets) for a collection of modification examples.
.mc4wp-checkbox-__INTEGRATION_SLUG__{clear:both;width:auto;display:block;position:static}.mc4wp-checkbox-__INTEGRATION_SLUG__ input{float:none;vertical-align:middle;-webkit-appearance:checkbox;width:auto;max-width:21px;margin:0 6px 0 0;padding:0;position:static;display:inline-block!important}.mc4wp-checkbox-__INTEGRATION_SLUG__ label{float:none;cursor:pointer;width:auto;margin:0 0 16px;display:block;position:static}
\ No newline at end of file
.mc4wp-form input[name^=_mc4wp_honey]{display:none!important}.mc4wp-form-basic{margin:1em 0}.mc4wp-form-basic label,.mc4wp-form-basic input{box-sizing:border-box;cursor:auto;vertical-align:baseline;width:auto;height:auto;line-height:normal;display:block}.mc4wp-form-basic label:after,.mc4wp-form-basic input:after{content:"";clear:both;display:table}.mc4wp-form-basic label{margin-bottom:6px;font-weight:700;display:block}.mc4wp-form-basic input[type=text],.mc4wp-form-basic input[type=email],.mc4wp-form-basic input[type=tel],.mc4wp-form-basic input[type=url],.mc4wp-form-basic input[type=date],.mc4wp-form-basic textarea,.mc4wp-form-basic select{width:100%;max-width:480px;min-height:32px}.mc4wp-form-basic input[type=number]{min-width:40px}.mc4wp-form-basic input[type=checkbox],.mc4wp-form-basic input[type=radio]{border:0;width:13px;height:13px;margin:0 6px 0 0;padding:0;display:inline-block;position:relative}.mc4wp-form-basic input[type=checkbox]{-webkit-appearance:checkbox;-moz-appearance:checkbox;appearance:checkbox}.mc4wp-form-basic input[type=radio]{-webkit-appearance:radio;-moz-appearance:radio;appearance:radio}.mc4wp-form-basic input[type=submit],.mc4wp-form-basic button,.mc4wp-form-basic input[type=button]{cursor:pointer;-webkit-appearance:none;-moz-appearance:none;appearance:none;display:inline-block}.mc4wp-form-basic label>span,.mc4wp-form-basic li>label{font-weight:400}.mc4wp-alert{color:#c09853;clear:both}.mc4wp-success{color:#468847}.mc4wp-notice{color:#3a87ad}.mc4wp-error{color:#cd5c5c}.rtl .mc4wp-form-basic input[type=checkbox],.rtl .mc4wp-form-basic input[type=radio]{margin:0 0 0 6px}
\ No newline at end of file
.mc4wp-form input[name^=_mc4wp_honey]{display:none!important}.mc4wp-form-theme{margin:1em 0}.mc4wp-form-theme label,.mc4wp-form-theme input{box-sizing:border-box;cursor:auto;vertical-align:baseline;width:auto;height:auto;line-height:normal;display:block}.mc4wp-form-theme label:after,.mc4wp-form-theme input:after{content:"";clear:both;display:table}.mc4wp-form-theme label{margin-bottom:6px;font-weight:700;display:block}.mc4wp-form-theme input[type=text],.mc4wp-form-theme input[type=email],.mc4wp-form-theme input[type=tel],.mc4wp-form-theme input[type=url],.mc4wp-form-theme input[type=date],.mc4wp-form-theme textarea,.mc4wp-form-theme select{vertical-align:middle;text-shadow:none;background:#fff;border:1px solid #ccc;border-radius:2px;outline:0;width:100%;max-width:480px;height:auto;min-height:32px;padding:8px 16px;line-height:1.42857;color:#555!important}.mc4wp-form-theme textarea{height:auto}.mc4wp-form-theme input[readonly],.mc4wp-form-theme input[disabled]{background-color:#eee}.mc4wp-form-theme input[type=number]{min-width:40px}.mc4wp-form-theme input[type=checkbox],.mc4wp-form-theme input[type=radio]{border:0;width:13px;height:13px;margin:0 6px 0 0;padding:0;display:inline-block;position:relative}.mc4wp-form-theme input[type=checkbox]{-webkit-appearance:checkbox;-moz-appearance:checkbox;appearance:checkbox}.mc4wp-form-theme input[type=radio]{-webkit-appearance:radio;-moz-appearance:radio;appearance:radio}.mc4wp-form-theme button,.mc4wp-form-theme input[type=submit],.mc4wp-form-theme input[type=button]{cursor:pointer;-webkit-appearance:none;-moz-appearance:none;appearance:none;text-align:center;white-space:nowrap;vertical-align:middle;user-select:none;text-shadow:none;filter:none;background:0 0;border:1px solid #0000;border-radius:2px;width:auto;height:auto;padding:8px 16px;font-weight:400;line-height:1.42857;display:inline-block}.mc4wp-form-theme button:hover,.mc4wp-form-theme input[type=submit]:hover,.mc4wp-form-theme input[type=button]:hover,.mc4wp-form-theme button:focus,.mc4wp-form-theme input[type=submit]:focus,.mc4wp-form-theme input[type=button]:focus{color:#333;background:0 0;outline:0;text-decoration:none}.mc4wp-form-theme label>span,.mc4wp-form-theme li>label{font-weight:400}.mc4wp-alert{color:#c09853;clear:both}.mc4wp-success{color:#468847}.mc4wp-notice{color:#3a87ad}.mc4wp-error{color:#cd5c5c}.rtl .mc4wp-form-theme input[type=checkbox],.rtl .mc4wp-form-theme input[type=radio]{margin:0 0 0 6px}.mc4wp-form-theme-dark button,.mc4wp-form-theme-dark input[type=submit],.mc4wp-form-theme-dark input[type=button]{border-color:#1e1e1e;color:#fff!important;background-color:#444!important}.mc4wp-form-theme-dark button:hover,.mc4wp-form-theme-dark input[type=submit]:hover,.mc4wp-form-theme-dark input[type=button]:hover,.mc4wp-form-theme-dark button:focus,.mc4wp-form-theme-dark input[type=submit]:focus,.mc4wp-form-theme-dark input[type=button]:focus{border-color:#000;color:#fff!important;background-color:#1e1e1e!important}.mc4wp-form-theme-dark input[type=text]:focus,.mc4wp-form-theme-dark input[type=email]:focus,.mc4wp-form-theme-dark input[type=tel]:focus,.mc4wp-form-theme-dark input[type=url]:focus,.mc4wp-form-theme-dark input[type=date]:focus,.mc4wp-form-theme-dark textarea:focus,.mc4wp-form-theme-dark select:focus{border-color:#6a6a6a}.mc4wp-form-theme-light button,.mc4wp-form-theme-light input[type=submit],.mc4wp-form-theme-light input[type=button]{border-color:#d9d9d9;color:#000!important;background-color:#fff!important}.mc4wp-form-theme-light button:hover,.mc4wp-form-theme-light input[type=submit]:hover,.mc4wp-form-theme-light input[type=button]:hover,.mc4wp-form-theme-light button:focus,.mc4wp-form-theme-light input[type=submit]:focus,.mc4wp-form-theme-light input[type=button]:focus{border-color:#b3b3b3;color:#000!important;background-color:#d9d9d9!important}.mc4wp-form-theme-light input[type=text]:focus,.mc4wp-form-theme-light input[type=email]:focus,.mc4wp-form-theme-light input[type=tel]:focus,.mc4wp-form-theme-light input[type=url]:focus,.mc4wp-form-theme-light input[type=date]:focus,.mc4wp-form-theme-light textarea:focus,.mc4wp-form-theme-light select:focus{border-color:#d9d9d9}.mc4wp-form-theme-red button,.mc4wp-form-theme-red input[type=submit],.mc4wp-form-theme-red input[type=button]{border-color:#b52b27;color:#fff!important;background-color:#d9534f!important}.mc4wp-form-theme-red button:hover,.mc4wp-form-theme-red input[type=submit]:hover,.mc4wp-form-theme-red input[type=button]:hover,.mc4wp-form-theme-red button:focus,.mc4wp-form-theme-red input[type=submit]:focus,.mc4wp-form-theme-red input[type=button]:focus{border-color:#761c19;color:#fff!important;background-color:#b52b27!important}.mc4wp-form-theme-red input[type=text]:focus,.mc4wp-form-theme-red input[type=email]:focus,.mc4wp-form-theme-red input[type=tel]:focus,.mc4wp-form-theme-red input[type=url]:focus,.mc4wp-form-theme-red input[type=date]:focus,.mc4wp-form-theme-red textarea:focus,.mc4wp-form-theme-red select:focus{border-color:#e7908e}.mc4wp-form-theme-blue button,.mc4wp-form-theme-blue input[type=submit],.mc4wp-form-theme-blue input[type=button]{border-color:#2a6496;color:#fff!important;background-color:#428bca!important}.mc4wp-form-theme-blue button:hover,.mc4wp-form-theme-blue input[type=submit]:hover,.mc4wp-form-theme-blue input[type=button]:hover,.mc4wp-form-theme-blue button:focus,.mc4wp-form-theme-blue input[type=submit]:focus,.mc4wp-form-theme-blue input[type=button]:focus{border-color:#193c5a;color:#fff!important;background-color:#2a6496!important}.mc4wp-form-theme-blue input[type=text]:focus,.mc4wp-form-theme-blue input[type=email]:focus,.mc4wp-form-theme-blue input[type=tel]:focus,.mc4wp-form-theme-blue input[type=url]:focus,.mc4wp-form-theme-blue input[type=date]:focus,.mc4wp-form-theme-blue textarea:focus,.mc4wp-form-theme-blue select:focus{border-color:#7eb0db}.mc4wp-form-theme-green button,.mc4wp-form-theme-green input[type=submit],.mc4wp-form-theme-green input[type=button]{border-color:#3d8b3d;color:#fff!important;background-color:#5cb85c!important}.mc4wp-form-theme-green button:hover,.mc4wp-form-theme-green input[type=submit]:hover,.mc4wp-form-theme-green input[type=button]:hover,.mc4wp-form-theme-green button:focus,.mc4wp-form-theme-green input[type=submit]:focus,.mc4wp-form-theme-green input[type=button]:focus{border-color:#255625;color:#fff!important;background-color:#3d8b3d!important}.mc4wp-form-theme-green input[type=text]:focus,.mc4wp-form-theme-green input[type=email]:focus,.mc4wp-form-theme-green input[type=tel]:focus,.mc4wp-form-theme-green input[type=url]:focus,.mc4wp-form-theme-green input[type=date]:focus,.mc4wp-form-theme-green textarea:focus,.mc4wp-form-theme-green select:focus{border-color:#91cf91}
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
width="16"
height="16"
viewBox="0 0 16 16"
version="1.1">
<g
fill="#a0a5aa">
<path
opacity="1"
fill="#a0a5aa"
fill-opacity="1"
stroke="none"
d="M 8.0097656 0.052734375 A 8 8 0 0 0 0.009765625 8.0527344 A 8 8 0 0 0 8.0097656 16.052734 A 8 8 0 0 0 16.009766 8.0527344 A 8 8 0 0 0 8.0097656 0.052734375 z M 9.2597656 4.171875 C 9.3205456 4.171875 9.9296146 5.0233822 10.611328 6.0664062 C 11.293041 7.1094313 12.296018 8.5331666 12.841797 9.2285156 L 13.833984 10.492188 L 13.316406 11.041016 C 13.031321 11.342334 12.708299 11.587891 12.599609 11.587891 C 12.253798 11.587891 11.266634 10.490156 10.349609 9.0859375 C 9.8610009 8.3377415 9.4126385 7.7229 9.3515625 7.71875 C 9.2904825 7.71455 9.2402344 8.3477011 9.2402344 9.1269531 L 9.2402344 10.544922 L 8.5839844 10.982422 C 8.2233854 11.223015 7.8735746 11.418294 7.8066406 11.417969 C 7.7397106 11.417644 7.4861075 10.997223 7.2421875 10.482422 C 6.9982675 9.9676199 6.6560079 9.3946444 6.4824219 9.2089844 L 6.1679688 8.8710938 L 6.0664062 9.34375 C 5.7203313 10.974656 5.6693219 11.090791 5.0917969 11.505859 C 4.5805569 11.873288 4.2347982 12.017623 4.1914062 11.882812 C 4.1839062 11.859632 4.1482681 11.574497 4.1113281 11.25 C 3.9708341 10.015897 3.5347399 8.7602861 2.8105469 7.5019531 C 2.5672129 7.0791451 2.5711235 7.0651693 2.9765625 6.8320312 C 3.2046215 6.7008903 3.5466561 6.4845105 3.7363281 6.3515625 C 4.0587811 6.1255455 4.1076376 6.1466348 4.4941406 6.6679688 C 4.8138896 7.0992628 4.9275606 7.166285 4.9941406 6.96875 C 5.0960956 6.666263 6.181165 5.8574219 6.484375 5.8574219 C 6.600668 5.8574219 6.8857635 6.1981904 7.1171875 6.6152344 C 7.3486105 7.0322784 7.5790294 7.3728809 7.6308594 7.3730469 C 7.7759584 7.3735219 7.9383234 5.8938023 7.8339844 5.5195312 C 7.7605544 5.2561423 7.8865035 5.0831575 8.4453125 4.6796875 C 8.8327545 4.3999485 9.1989846 4.171875 9.2597656 4.171875 z "
id="path5822" />
</g>
</svg>
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="64"
height="64"
viewBox="0 0 64 64"
version="1.1"
id="SVGRoot"
inkscape:version="0.92.4 5da689c313, 2019-01-14"
sodipodi:docname="mc4wp-logo-red-on-white.svg">
<g
inkscape:groupmode="layer"
id="layer2"
inkscape:label="Layer 2">
<circle
style="opacity:1;fill:#ffffff;fill-opacity:1;stroke:none;stroke-opacity:1"
id="path5822"
cx="32"
cy="32"
r="32" />
</g>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1">
<path
style="fill:#cc4444;fill-opacity:1;stroke:none;"
d="m 16,47.324799 c -0.02985,-0.09271 -0.175159,-1.230558 -0.322927,-2.528543 -0.561978,-4.936413 -2.305204,-9.961206 -5.201976,-14.994537 -0.9733359,-1.691234 -0.9585997,-1.750867 0.663154,-2.683422 0.912236,-0.524562 2.279359,-1.38885 3.038049,-1.920641 1.289813,-0.904069 1.486868,-0.821985 3.032878,1.26335 1.278999,1.725178 1.731406,1.998919 1.997727,1.208779 0.407819,-1.209946 4.748289,-4.450438 5.96113,-4.450438 0.465172,0 1.603153,1.364871 2.528847,3.033047 0.925694,1.668177 1.852705,3.03359 2.060024,3.034253 0.580399,0.0019 1.2257,-5.915967 0.808345,-7.413054 -0.293707,-1.053553 0.21226,-1.748685 2.447515,-3.362568 1.549769,-1.118954 3.016679,-2.034461 3.2598,-2.034461 0.243121,0 2.673101,3.413534 5.399956,7.585632 2.726854,4.172097 6.744105,9.861321 8.927221,12.642719 l 3.969305,5.057088 -2.073345,2.191405 c -1.140339,1.205272 -2.429057,2.191404 -2.863817,2.191404 -1.383243,0 -5.331006,-4.389741 -8.999106,-10.006614 -1.954436,-2.992783 -3.753407,-5.455006 -3.997711,-5.471606 -0.244305,-0.0166 -0.44419,2.520101 -0.44419,5.637112 v 5.667295 l -2.62254,1.749768 c -1.442397,0.962371 -2.841596,1.748706 -3.109332,1.747409 -0.267735,-0.0013 -1.285075,-1.687162 -2.260756,-3.746367 -0.97568,-2.059206 -2.342064,-4.351629 -3.036409,-5.094272 l -1.262444,-1.350262 -0.401863,1.893807 c -1.3843,6.523625 -1.59298,6.985894 -3.90308,8.646166 C 17.549496,47.286963 16.173566,47.864041 16,47.324799 Z"
id="path4520"
inkscape:connector-curvature="0" />
</g>
</svg>
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="64"
height="64"
viewBox="0 0 64 64"
version="1.1"
id="SVGRoot"
inkscape:version="0.92.4 5da689c313, 2019-01-14"
sodipodi:docname="mc4wp-logo-white-on-red.svg">
<g
inkscape:groupmode="layer"
id="layer2"
inkscape:label="Layer 2">
<circle
style="opacity:1;fill:#cc4444;fill-opacity:1;stroke:none;stroke-opacity:1"
id="path5822"
cx="32"
cy="32"
r="32" />
</g>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1">
<path
style="fill:#ffffff;fill-opacity:1;stroke:none;"
d="m 16,47.324799 c -0.02985,-0.09271 -0.175159,-1.230558 -0.322927,-2.528543 -0.561978,-4.936413 -2.305204,-9.961206 -5.201976,-14.994537 -0.9733359,-1.691234 -0.9585997,-1.750867 0.663154,-2.683422 0.912236,-0.524562 2.279359,-1.38885 3.038049,-1.920641 1.289813,-0.904069 1.486868,-0.821985 3.032878,1.26335 1.278999,1.725178 1.731406,1.998919 1.997727,1.208779 0.407819,-1.209946 4.748289,-4.450438 5.96113,-4.450438 0.465172,0 1.603153,1.364871 2.528847,3.033047 0.925694,1.668177 1.852705,3.03359 2.060024,3.034253 0.580399,0.0019 1.2257,-5.915967 0.808345,-7.413054 -0.293707,-1.053553 0.21226,-1.748685 2.447515,-3.362568 1.549769,-1.118954 3.016679,-2.034461 3.2598,-2.034461 0.243121,0 2.673101,3.413534 5.399956,7.585632 2.726854,4.172097 6.744105,9.861321 8.927221,12.642719 l 3.969305,5.057088 -2.073345,2.191405 c -1.140339,1.205272 -2.429057,2.191404 -2.863817,2.191404 -1.383243,0 -5.331006,-4.389741 -8.999106,-10.006614 -1.954436,-2.992783 -3.753407,-5.455006 -3.997711,-5.471606 -0.244305,-0.0166 -0.44419,2.520101 -0.44419,5.637112 v 5.667295 l -2.62254,1.749768 c -1.442397,0.962371 -2.841596,1.748706 -3.109332,1.747409 -0.267735,-0.0013 -1.285075,-1.687162 -2.260756,-3.746367 -0.97568,-2.059206 -2.342064,-4.351629 -3.036409,-5.094272 l -1.262444,-1.350262 -0.401863,1.893807 c -1.3843,6.523625 -1.59298,6.985894 -3.90308,8.646166 C 17.549496,47.286963 16.173566,47.864041 16,47.324799 Z"
id="path4520"
inkscape:connector-curvature="0" />
</g>
</svg>
This diff could not be displayed because it is too large.
(()=>{const e=window.wp.i18n.__,{registerBlockType:t}=window.wp.blocks,{SelectControl:i}=window.wp.components,o=window.mc4wp_forms;t("mailchimp-for-wp/form",{title:e("Mailchimp for WordPress Form"),description:e("Block showing a Mailchimp for WordPress sign-up form"),category:"widgets",attributes:{id:{type:"int"}},icon:React.createElement("svg",{width:"16",height:"16",viewBox:"0 0 16 16",version:"1.1"},React.createElement("path",{opacity:"1",fill:"#a0a5aa",fillOpacity:"1",stroke:"none",d:"M 8.0097656 0.052734375 A 8 8 0 0 0 0.009765625 8.0527344 A 8 8 0 0 0 8.0097656 16.052734 A 8 8 0 0 0 16.009766 8.0527344 A 8 8 0 0 0 8.0097656 0.052734375 z M 9.2597656 4.171875 C 9.3205456 4.171875 9.9296146 5.0233822 10.611328 6.0664062 C 11.293041 7.1094313 12.296018 8.5331666 12.841797 9.2285156 L 13.833984 10.492188 L 13.316406 11.041016 C 13.031321 11.342334 12.708299 11.587891 12.599609 11.587891 C 12.253798 11.587891 11.266634 10.490156 10.349609 9.0859375 C 9.8610009 8.3377415 9.4126385 7.7229 9.3515625 7.71875 C 9.2904825 7.71455 9.2402344 8.3477011 9.2402344 9.1269531 L 9.2402344 10.544922 L 8.5839844 10.982422 C 8.2233854 11.223015 7.8735746 11.418294 7.8066406 11.417969 C 7.7397106 11.417644 7.4861075 10.997223 7.2421875 10.482422 C 6.9982675 9.9676199 6.6560079 9.3946444 6.4824219 9.2089844 L 6.1679688 8.8710938 L 6.0664062 9.34375 C 5.7203313 10.974656 5.6693219 11.090791 5.0917969 11.505859 C 4.5805569 11.873288 4.2347982 12.017623 4.1914062 11.882812 C 4.1839062 11.859632 4.1482681 11.574497 4.1113281 11.25 C 3.9708341 10.015897 3.5347399 8.7602861 2.8105469 7.5019531 C 2.5672129 7.0791451 2.5711235 7.0651693 2.9765625 6.8320312 C 3.2046215 6.7008903 3.5466561 6.4845105 3.7363281 6.3515625 C 4.0587811 6.1255455 4.1076376 6.1466348 4.4941406 6.6679688 C 4.8138896 7.0992628 4.9275606 7.166285 4.9941406 6.96875 C 5.0960956 6.666263 6.181165 5.8574219 6.484375 5.8574219 C 6.600668 5.8574219 6.8857635 6.1981904 7.1171875 6.6152344 C 7.3486105 7.0322784 7.5790294 7.3728809 7.6308594 7.3730469 C 7.7759584 7.3735219 7.9383234 5.8938023 7.8339844 5.5195312 C 7.7605544 5.2561423 7.8865035 5.0831575 8.4453125 4.6796875 C 8.8327545 4.3999485 9.1989846 4.171875 9.2597656 4.171875 z "})),supports:{html:!1},edit:function(t){const r=o.map((e=>({label:e.name,value:e.id})));return void 0===t.attributes.id&&o.length>0&&t.setAttributes({id:o[0].id}),React.createElement("div",{style:{backgroundColor:"#f8f9f9",padding:"14px"}},React.createElement(i,{label:e("Mailchimp for WordPress Sign-up Form"),value:t.attributes.id,options:r,onChange:e=>{t.setAttributes({id:e})}}))},save:function(e){return null}})})();
\ No newline at end of file
(()=>{var e={1419:e=>{e.exports=function(e){const t=window.pageXOffset||document.documentElement.scrollLeft,o=function(e){const t=document.body,o=document.documentElement,n=e.getBoundingClientRect(),r=o.clientHeight,i=Math.max(t.scrollHeight,t.offsetHeight,o.clientHeight,o.scrollHeight,o.offsetHeight),c=n.bottom-r/2-n.height/2,s=i-r;return Math.min(c+window.pageYOffset,s)}(e);window.scrollTo(t,o)}}},t={};function o(n){var r=t[n];if(void 0!==r)return r.exports;var i=t[n]={exports:{}};return e[n](i,i.exports,o),i.exports}o.n=e=>{var t=e&&e.__esModule?()=>e.default:()=>e;return o.d(t,{a:t}),t},o.d=(e,t)=>{for(var n in t)o.o(t,n)&&!o.o(e,n)&&Object.defineProperty(e,n,{enumerable:!0,get:t[n]})},o.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),(()=>{"use strict";var e=o(1419),t=o.n(e);const n=window.mc4wp_submitted_form,r=window.mc4wp.forms;if(n){const e=document.getElementById(n.element_id);!function(e,o,i,c){const s=Date.now(),d=document.body.clientHeight;i&&e.setData(c),window.scrollY<=10&&n.auto_scroll&&t()(e.element),window.addEventListener("load",(function(){r.trigger("submitted",[e]),i?r.trigger("error",[e,i]):(r.trigger("success",[e,c]),r.trigger(o,[e,c]),"updated_subscriber"===o&&r.trigger("subscribed",[e,c,!0]));const l=Date.now()-s;n.auto_scroll&&l>1e3&&l<2e3&&document.body.clientHeight!==d&&t()(e.element)}))}(r.getByElement(e),n.event,n.errors,n.data)}})()})();
\ No newline at end of file
(()=>{var e={9885:e=>{function t(){this.listeners={}}t.prototype.emit=function(e,t){this.listeners[e]=this.listeners[e]??[],this.listeners[e].forEach((e=>e.apply(null,t)))},t.prototype.on=function(e,t){this.listeners[e]=this.listeners[e]??[],this.listeners[e].push(t)},e.exports=t},5626:()=>{function e(e){const t=!!e.getAttribute("data-show-if"),n=t?e.getAttribute("data-show-if").split(":"):e.getAttribute("data-hide-if").split(":"),r=n[0],i=(n.length>1?n[1]:"*").split("|"),o=function(e,t){const n=[],r=e.querySelectorAll('input[name="'+t+'"],select[name="'+t+'"],textarea[name="'+t+'"]');for(let e=0;e<r.length;e++)("radio"!==r[e].type&&"checkbox"!==r[e].type||r[e].checked)&&n.push(r[e].value);return n}(function(e){let t=e;for(;t.parentElement;)if(t=t.parentElement,"FORM"===t.tagName)return t;return null}(e),r);let s=!1;for(let e=0;e<o.length&&!s;e++)s=i.indexOf(o[e])>-1||i.indexOf("*")>-1&&o[e].length>0;e.style.display=t?s?"":"none":s?"none":"";const a=e.querySelectorAll("input,select,textarea");for(let e=0;e<a.length;e++)(s||t)&&a[e].getAttribute("data-was-required")&&(a[e].required=!0,a[e].removeAttribute("data-was-required")),s&&t||!a[e].required||(a[e].setAttribute("data-was-required","true"),a[e].required=!1)}function t(){const t=document.querySelectorAll(".mc4wp-form [data-show-if],.mc4wp-form [data-hide-if]");for(let n=0;n<t.length;n++)e(t[n])}function n(t){if(!t.target||!t.target.form||t.target.form.className.indexOf("mc4wp-form")<0)return;const n=t.target.form.querySelectorAll("[data-show-if],[data-hide-if]");for(let t=0;t<n.length;t++)e(n[t])}document.addEventListener("keyup",n,!0),document.addEventListener("change",n,!0),document.addEventListener("mc4wp-refresh",t,!0),window.addEventListener("load",t),t()},6942:(e,t,n)=>{const r=n(2076),i=n(6564),o=function(e,t){this.id=e,this.element=t||document.createElement("form"),this.name=this.element.getAttribute("data-name")||"Form #"+this.id,this.errors=[],this.started=!1};o.prototype.setData=function(e){try{i(this.element,e)}catch(e){console.error(e)}},o.prototype.getData=function(){return r(this.element,{hash:!0,empty:!0})},o.prototype.getSerializedData=function(){return r(this.element,{hash:!1,empty:!0})},o.prototype.setResponse=function(e){this.element.querySelector(".mc4wp-response").innerHTML=e},o.prototype.reset=function(){this.setResponse(""),this.element.querySelector(".mc4wp-form-fields").style.display="",this.element.reset()},e.exports=o},9685:(e,t,n)=>{const r=n(6942),i=[],o=new(n(9885));function s(e,t){t=t||parseInt(e.getAttribute("data-id"))||0;const n=new r(t,e);return i.push(n),n}e.exports={get:function(e){e=parseInt(e);for(let t=0;t<i.length;t++)if(i[t].id===e)return i[t];return s(document.querySelector(".mc4wp-form-"+e),e)},getByElement:function(e){const t=e.form||e;for(let e=0;e<i.length;e++)if(i[e].element===t)return i[e];return s(t)},on:function(e,t){o.on(e,t)},trigger:function(e,t){"submit"===e||e.indexOf(".submit")>0?(o.emit(t[0].id+"."+e,t),o.emit(e,t)):window.setTimeout((function(){o.emit(t[0].id+"."+e,t),o.emit(e,t)}),10)}}},2076:e=>{var t=/^(?:submit|button|image|reset|file)$/i,n=/^(?:input|select|textarea|keygen)/i,r=/(\[[^\[\]]*\])/g;function i(e,t,n){if(0===t.length)return n;var r=t.shift(),o=r.match(/^\[(.+?)\]$/);if("[]"===r)return e=e||[],Array.isArray(e)?e.push(i(null,t,n)):(e._values=e._values||[],e._values.push(i(null,t,n))),e;if(o){var s=o[1],a=+s;isNaN(a)?(e=e||{})[s]=i(e[s],t,n):(e=e||[])[a]=i(e[a],t,n)}else e[r]=i(e[r],t,n);return e}function o(e,t,n){if(t.match(r))i(e,function(e){var t=[],n=new RegExp(r),i=/^([^\[\]]*)/.exec(e);for(i[1]&&t.push(i[1]);null!==(i=n.exec(e));)t.push(i[1]);return t}(t),n);else{var o=e[t];o?(Array.isArray(o)||(e[t]=[o]),e[t].push(n)):e[t]=n}return e}function s(e,t,n){return n=n.replace(/(\r)?\n/g,"\r\n"),n=(n=encodeURIComponent(n)).replace(/%20/g,"+"),e+(e?"&":"")+encodeURIComponent(t)+"="+n}e.exports=function(e,r){"object"!=typeof r?r={hash:!!r}:void 0===r.hash&&(r.hash=!0);for(var i=r.hash?{}:"",a=r.serializer||(r.hash?o:s),c=e&&e.elements?e.elements:[],l=Object.create(null),u=0;u<c.length;++u){var f=c[u];if((r.disabled||!f.disabled)&&f.name&&n.test(f.nodeName)&&!t.test(f.type)){var d=f.name,h=f.value;if("checkbox"!==f.type&&"radio"!==f.type||f.checked||(h=void 0),r.empty){if("checkbox"!==f.type||f.checked||(h=""),"radio"===f.type&&(l[f.name]||f.checked?f.checked&&(l[f.name]=!0):l[f.name]=!1),null==h&&"radio"==f.type)continue}else if(!h)continue;if("select-multiple"!==f.type)i=a(i,d,h);else{h=[];for(var p=f.options,m=!1,g=0;g<p.length;++g){var y=p[g],v=r.empty&&!y.value,w=y.value||v;y.selected&&w&&(m=!0,i=r.hash&&"[]"!==d.slice(d.length-2)?a(i,d+"[]",y.value):a(i,d,y.value))}!m&&r.empty&&(i=a(i,d,""))}}}if(r.empty)for(var d in l)l[d]||(i=a(i,d,""));return i}},6564:e=>{e.exports&&(e.exports=function e(t,n,r){for(const i in n){if(!n.hasOwnProperty(i))continue;const o=i;let s=n[i];if(void 0===s&&(s=""),null===s&&(s=""),void 0!==r&&(o=r+"["+i+"]"),s.constructor===Array)o+="[]";else if("object"==typeof s){e(t,s,o);continue}const a=t.elements.namedItem(o);if(!a)continue;const c=a.type||a[0].type;switch(c){default:a.value=s;break;case"radio":case"checkbox":{const e=s.constructor===Array?s:[s];for(let t=0;t<a.length;t++)a[t].checked=e.indexOf(a[t].value)>-1}break;case"select-multiple":{const e=s.constructor===Array?s:[s];for(let t=0;t<a.options.length;t++)a.options[t].selected=e.indexOf(a.options[t].value)>-1}break;case"select":case"select-one":a.value=s.toString()||s;break;case"date":a.value=new Date(s).toISOString().split("T")[0]}const l=new Event("change",{bubbles:!0});switch(c){default:a.dispatchEvent(l);break;case"radio":case"checkbox":for(let e=0;e<a.length;e++)a[e].checked&&a[e].dispatchEvent(l)}}})}},t={};function n(r){var i=t[r];if(void 0!==i)return i.exports;var o=t[r]={exports:{}};return e[r](o,o.exports,n),o.exports}const r=window.mc4wp||{},i=n(9685);function o(e,t){document.addEventListener(e,(e=>{if(!e.target)return;const n=e.target;("string"==typeof n.className&&n.className.indexOf("mc4wp-form")>-1||"function"==typeof n.matches&&n.matches(".mc4wp-form *"))&&t.call(e,e)}),!0)}n(5626),o("submit",(function(e){if(e.defaultPrevented)return;const t=i.getByElement(e.target);i.trigger("submit",[t,e])})),o("focus",(function(e){const t=i.getByElement(e.target);t.started||(i.trigger("started",[t,e]),t.started=!0)})),o("change",(function(e){const t=i.getByElement(e.target);i.trigger("change",[t,e])})),r.listeners&&([].forEach.call(r.listeners,(function(e){i.on(e.event,e.callback)})),delete r.listeners),r.forms=i,window.mc4wp=r})();
\ No newline at end of file
(()=>{const e=window.mc4wp_vars.ajaxurl,t=window.mc4wp.settings,n=document.getElementById("notice-additional-fields");function i(){const t=[].filter.call(document.querySelectorAll(".mc4wp-list-input"),(e=>e.checked)).map((e=>e.value)).join(","),i=["EMAIL","FNAME","NAME","LNAME"];let l=!1;window.fetch(`${e}?action=mc4wp_get_list_details&ids=${t}`).then((e=>e.json())).then((e=>{e.forEach((e=>{e.merge_fields.forEach((e=>{e.required&&i.indexOf(e.tag)<0&&(l=!0)}))}))})).finally((()=>{n.style.display=l?"":"none"}))}n&&(i(),t.on("selectedLists.change",i))})();
\ No newline at end of file
<?php
require __DIR__ . '/includes/functions.php';
require __DIR__ . '/includes/deprecated-functions.php';
require __DIR__ . '/includes/forms/functions.php';
require __DIR__ . '/includes/forms/admin-functions.php';
require __DIR__ . '/includes/integrations/functions.php';
// require API class manually because our classloader is case-sensitive
require __DIR__ . '/includes/api/class-api-v3.php';
// load other classes dynamically
spl_autoload_register(function ($class) {
static $classmap = array(
'MC4WP_API_Connection_Exception' => __DIR__ . '/includes/api/class-connection-exception.php',
'MC4WP_API_Exception' => __DIR__ . '/includes/api/class-exception.php',
'MC4WP_API_Resource_Not_Found_Exception' => __DIR__ . '/includes/api/class-resource-not-found-exception.php',
'MC4WP_API_V3' => __DIR__ . '/includes/api/class-api-v3.php',
'MC4WP_API_V3_Client' => __DIR__ . '/includes/api/class-api-v3-client.php',
'MC4WP_Admin' => __DIR__ . '/includes/admin/class-admin.php',
'MC4WP_Admin_Ads' => __DIR__ . '/includes/admin/class-ads.php',
'MC4WP_Admin_Ajax' => __DIR__ . '/includes/admin/class-admin-ajax.php',
'MC4WP_Admin_Messages' => __DIR__ . '/includes/admin/class-admin-messages.php',
'MC4WP_Admin_Review_Notice' => __DIR__ . '/includes/admin/class-review-notice.php',
'MC4WP_Admin_Texts' => __DIR__ . '/includes/admin/class-admin-texts.php',
'MC4WP_Admin_Tools' => __DIR__ . '/includes/admin/class-admin-tools.php',
'MC4WP_AffiliateWP_Integration' => __DIR__ . '/integrations/affiliatewp/class-affiliatewp.php',
'MC4WP_BuddyPress_Integration' => __DIR__ . '/integrations/buddypress/class-buddypress.php',
'MC4WP_Comment_Form_Integration' => __DIR__ . '/integrations/wp-comment-form/class-comment-form.php',
'MC4WP_Contact_Form_7_Integration' => __DIR__ . '/integrations/contact-form-7/class-contact-form-7.php',
'MC4WP_Container' => __DIR__ . '/includes/class-container.php',
'MC4WP_Custom_Integration' => __DIR__ . '/integrations/custom/class-custom.php',
'MC4WP_Debug_Log' => __DIR__ . '/includes/class-debug-log.php',
'MC4WP_Debug_Log_Reader' => __DIR__ . '/includes/class-debug-log-reader.php',
'MC4WP_Dynamic_Content_Tags' => __DIR__ . '/includes/class-dynamic-content-tags.php',
'MC4WP_Easy_Digital_Downloads_Integration' => __DIR__ . '/integrations/easy-digital-downloads/class-easy-digital-downloads.php',
'MC4WP_Events_Manager_Integration' => __DIR__ . '/integrations/events-manager/class-events-manager.php',
'MC4WP_Field_Formatter' => __DIR__ . '/includes/class-field-formatter.php',
'MC4WP_Field_Guesser' => __DIR__ . '/includes/class-field-guesser.php',
'MC4WP_Form' => __DIR__ . '/includes/forms/class-form.php',
'MC4WP_Form_AMP' => __DIR__ . '/includes/forms/class-form-amp.php',
'MC4WP_Form_Asset_Manager' => __DIR__ . '/includes/forms/class-asset-manager.php',
'MC4WP_Form_Element' => __DIR__ . '/includes/forms/class-form-element.php',
'MC4WP_Form_Listener' => __DIR__ . '/includes/forms/class-form-listener.php',
'MC4WP_Form_Manager' => __DIR__ . '/includes/forms/class-form-manager.php',
'MC4WP_Form_Notice' => __DIR__ . '/includes/forms/class-form-message.php',
'MC4WP_Form_Output_Manager' => __DIR__ . '/includes/forms/class-output-manager.php',
'MC4WP_Form_Previewer' => __DIR__ . '/includes/forms/class-form-previewer.php',
'MC4WP_Form_Tags' => __DIR__ . '/includes/forms/class-form-tags.php',
'MC4WP_Form_Widget' => __DIR__ . '/includes/forms/class-widget.php',
'MC4WP_Forms_Admin' => __DIR__ . '/includes/forms/class-admin.php',
'MC4WP_Give_Integration' => __DIR__ . '/integrations/give/class-give.php',
'MC4WP_Gravity_Forms_Field' => __DIR__ . '/integrations/gravity-forms/class-field.php',
'MC4WP_Gravity_Forms_Integration' => __DIR__ . '/integrations/gravity-forms/class-gravity-forms.php',
'MC4WP_Integration' => __DIR__ . '/includes/integrations/class-integration.php',
'MC4WP_Integration_Admin' => __DIR__ . '/includes/integrations/class-admin.php',
'MC4WP_Integration_Fixture' => __DIR__ . '/includes/integrations/class-integration-fixture.php',
'MC4WP_Integration_Manager' => __DIR__ . '/includes/integrations/class-integration-manager.php',
'MC4WP_Integration_Tags' => __DIR__ . '/includes/integrations/class-integration-tags.php',
'MC4WP_List_Data_Mapper' => __DIR__ . '/includes/class-list-data-mapper.php',
'MC4WP_MailChimp' => __DIR__ . '/includes/class-mailchimp.php',
'MC4WP_MailChimp_Subscriber' => __DIR__ . '/includes/class-mailchimp-subscriber.php',
'MC4WP_MemberPress_Integration' => __DIR__ . '/integrations/memberpress/class-memberpress.php',
'MC4WP_Ninja_Forms_Action' => __DIR__ . '/integrations/ninja-forms/class-action.php',
'MC4WP_Ninja_Forms_Field' => __DIR__ . '/integrations/ninja-forms/class-field.php',
'MC4WP_Ninja_Forms_Integration' => __DIR__ . '/integrations/ninja-forms/class-ninja-forms.php',
'MC4WP_Ninja_Forms_V2_Integration' => __DIR__ . '/integrations/ninja-forms-2/class-ninja-forms.php',
'MC4WP_Plugin' => __DIR__ . '/includes/class-plugin.php',
'MC4WP_Queue' => __DIR__ . '/includes/class-queue.php',
'MC4WP_Queue_Job' => __DIR__ . '/includes/class-queue-job.php',
'MC4WP_Registration_Form_Integration' => __DIR__ . '/integrations/wp-registration-form/class-registration-form.php',
'MC4WP_Tools' => __DIR__ . '/includes/class-tools.php',
'MC4WP_Upgrade_Routines' => __DIR__ . '/includes/admin/class-upgrade-routines.php',
'MC4WP_User_Integration' => __DIR__ . '/includes/integrations/class-user-integration.php',
'MC4WP_WPForms_Field' => __DIR__ . '/integrations/wpforms/class-field.php',
'MC4WP_WPForms_Integration' => __DIR__ . '/integrations/wpforms/class-wpforms.php',
'MC4WP_WooCommerce_Integration' => __DIR__ . '/integrations/woocommerce/class-woocommerce.php',
);
if (isset($classmap[$class])) {
require $classmap[$class];
}
});
<?php
$email_label = esc_html__('Email address', 'mailchimp-for-wp');
$email_placeholder_attr = esc_attr__('Your email address', 'mailchimp-for-wp');
$signup_button_value = esc_attr__('Sign up', 'mailchimp-for-wp');
$content = "<p>\n\t<label for=\"email\">{$email_label}: \n";
$content .= "\t\t<input type=\"email\" id=\"email\" name=\"EMAIL\" placeholder=\"{$email_placeholder_attr}\" required>\n</label>\n</p>\n\n";
$content .= "<p>\n\t<input type=\"submit\" value=\"{$signup_button_value}\">\n</p>";
return $content;
<?php
return array(
'subscribed' => array(
'type' => 'success',
'text' => esc_html__('Thank you, your sign-up request was successful! Please check your email inbox to confirm.', 'mailchimp-for-wp'),
),
'updated' => array(
'type' => 'success',
'text' => esc_html__('Thank you, your records have been updated!', 'mailchimp-for-wp'),
),
'unsubscribed' => array(
'type' => 'success',
'text' => esc_html__('You were successfully unsubscribed.', 'mailchimp-for-wp'),
),
'not_subscribed' => array(
'type' => 'notice',
'text' => esc_html__('Given email address is not subscribed.', 'mailchimp-for-wp'),
),
'error' => array(
'type' => 'error',
'text' => esc_html__('Oops. Something went wrong. Please try again later.', 'mailchimp-for-wp'),
),
'invalid_email' => array(
'type' => 'error',
'text' => esc_html__('Please provide a valid email address.', 'mailchimp-for-wp'),
),
'already_subscribed' => array(
'type' => 'notice',
'text' => esc_html__('Given email address is already subscribed, thank you!', 'mailchimp-for-wp'),
),
'required_field_missing' => array(
'type' => 'error',
'text' => esc_html__('Please fill in the required fields.', 'mailchimp-for-wp'),
),
'no_lists_selected' => array(
'type' => 'error',
'text' => esc_html__('Please select at least one list.', 'mailchimp-for-wp'),
),
);
<?php
return array(
'css' => 0,
'double_optin' => 1,
'hide_after_success' => 0,
'lists' => array(),
'redirect' => '',
'replace_interests' => 1,
'required_fields' => '',
'update_existing' => 0,
'subscriber_tags' => '',
);
<?php
return array(
'api_key' => '',
'allow_usage_tracking' => 0,
'debug_log_level' => 'warning',
);
<?php
class MC4WP_Admin_Ajax
{
/**
* @var MC4WP_Admin_Tools
*/
protected $tools;
/**
* MC4WP_Admin_Ajax constructor.
*
* @param MC4WP_Admin_Tools $tools
*/
public function __construct(MC4WP_Admin_Tools $tools)
{
$this->tools = $tools;
}
/**
* Hook AJAX actions
*/
public function add_hooks()
{
add_action('wp_ajax_mc4wp_renew_mailchimp_lists', array( $this, 'refresh_mailchimp_lists' ));
add_action('wp_ajax_mc4wp_get_list_details', array( $this, 'get_list_details' ));
}
/**
* Empty lists cache & fetch lists again.
*/
public function refresh_mailchimp_lists()
{
if (! $this->tools->is_user_authorized()) {
wp_send_json_error();
return;
}
check_ajax_referer('mc4wp-ajax');
$mailchimp = new MC4WP_MailChimp();
$success = $mailchimp->refresh_lists();
wp_send_json($success);
}
/**
* Retrieve details (merge fields and interest categories) for one or multiple lists in Mailchimp
* @throws MC4WP_API_Exception
*/
public function get_list_details()
{
if (! $this->tools->is_user_authorized()) {
wp_send_json_error();
return;
}
$list_ids = (array) explode(',', $_GET['ids']);
$data = array();
$mailchimp = new MC4WP_MailChimp();
foreach ($list_ids as $list_id) {
$data[] = (object) array(
'id' => $list_id,
'merge_fields' => $mailchimp->get_list_merge_fields($list_id),
'interest_categories' => $mailchimp->get_list_interest_categories($list_id),
'marketing_permissions' => $mailchimp->get_list_marketing_permissions($list_id),
);
}
if (isset($_GET['format']) && $_GET['format'] === 'html') {
$merge_fields = $data[0]->merge_fields;
$interest_categories = $data[0]->interest_categories;
$marketing_permissions = $data[0]->marketing_permissions;
require MC4WP_PLUGIN_DIR . '/includes/views/parts/lists-overview-details.php';
} else {
wp_send_json($data);
}
exit;
}
}
<?php
/**
* Class MC4WP_Admin_Messages
*
* @ignore
* @since 3.0
*/
class MC4WP_Admin_Messages
{
/**
* @var array
*/
protected $bag;
/**
* @var bool
*/
protected $dirty = false;
/**
* Add hooks
*/
public function add_hooks()
{
add_action('admin_notices', array( $this, 'show' ));
register_shutdown_function(array( $this, 'save' ));
}
private function load()
{
if (is_null($this->bag)) {
$this->bag = get_option('mc4wp_flash_messages', array());
}
}
// empty flash bag
private function reset()
{
$this->bag = array();
$this->dirty = true;
}
/**
* Flash a message (shows on next pageload)
*
* @param $message
* @param string $type
*/
public function flash($message, $type = 'success')
{
$this->load();
$this->bag[] = array(
'text' => $message,
'type' => $type,
);
$this->dirty = true;
}
/**
* Show queued flash messages
*/
public function show()
{
$this->load();
foreach ($this->bag as $message) {
echo sprintf('<div class="notice notice-%s is-dismissible"><p>%s</p></div>', $message['type'], $message['text']);
}
$this->reset();
}
/**
* Save queued messages
*
* @hooked `shutdown`
*/
public function save()
{
if ($this->dirty) {
update_option('mc4wp_flash_messages', $this->bag, false);
}
}
}
<?php
/**
* Class MC4WP_Admin_Texts
*
* @ignore
* @since 3.0
*/
class MC4WP_Admin_Texts
{
/**
* @var string
*/
protected $plugin_file;
/**
* @param string $plugin_file
*/
public function __construct($plugin_file)
{
$this->plugin_file = $plugin_file;
}
/**
* Add hooks
*/
public function add_hooks()
{
global $pagenow;
add_filter('admin_footer_text', array( $this, 'footer_text' ));
// Hooks for Plugins overview page
if ($pagenow === 'plugins.php') {
add_filter('plugin_action_links_' . $this->plugin_file, array( $this, 'add_plugin_settings_link' ), 10, 2);
add_filter('plugin_row_meta', array( $this, 'add_plugin_meta_links' ), 10, 2);
}
}
/**
* Ask for a plugin review in the WP Admin footer, if this is one of the plugin pages.
*
* @param string $text
*
* @return string
*/
public function footer_text($text)
{
if (! empty($_GET['page']) && strpos($_GET['page'], 'mailchimp-for-wp') === 0) {
$text = sprintf('If you enjoy using <strong>Mailchimp for WordPress</strong>, please <a href="%s" target="_blank">leave us a ★★★★★ plugin review on WordPress.org</a>.', 'https://wordpress.org/support/plugin/mailchimp-for-wp/reviews/#new-post');
}
return $text;
}
/**
* Add the settings link to the Plugins overview
*
* @param array $links
* @param $file
*
* @return array
*/
public function add_plugin_settings_link($links, $file)
{
if ($file !== $this->plugin_file) {
return $links;
}
$settings_link = sprintf('<a href="%s">%s</a>', admin_url('admin.php?page=mailchimp-for-wp'), esc_html__('Settings', 'mailchimp-for-wp'));
array_unshift($links, $settings_link);
return $links;
}
/**
* Adds meta links to the plugin in the WP Admin > Plugins screen
*
* @param array $links
* @param string $file
*
* @return array
*/
public function add_plugin_meta_links($links, $file)
{
if ($file !== $this->plugin_file) {
return $links;
}
$links[] = '<a href="https://www.mc4wp.com/kb/#utm_source=wp-plugin&utm_medium=mailchimp-for-wp&utm_campaign=plugins-page">' . esc_html__('Documentation', 'mailchimp-for-wp') . '</a>';
/**
* Filters meta links shown on the Plugins overview page
*
* This takes an array of strings
*
* @since 3.0
* @param array $links
* @ignore
*/
$links = apply_filters('mc4wp_admin_plugin_meta_links', $links);
return $links;
}
}
<?php
class MC4WP_Admin_Tools
{
/**
* @return string
*/
public function get_plugin_page()
{
if (empty($_GET['page'])) {
return '';
}
$prefix = 'mailchimp-for-wp';
$page = ltrim(substr($_GET['page'], strlen($prefix)), '-');
return $page;
}
/**
* @param string $page
*
* @return bool
*/
public function on_plugin_page($page = null)
{
// any settings page
if (is_null($page)) {
return isset($_GET['page']) && strpos($_GET['page'], 'mailchimp-for-wp') === 0;
}
// specific page
return $this->get_plugin_page() === $page;
}
/**
* Does the logged-in user have the required capability?
*
* @return bool
*/
public function is_user_authorized()
{
return current_user_can($this->get_required_capability());
}
/**
* Get required capability to access settings page and view dashboard widgets.
*
* @return string
*/
public function get_required_capability()
{
$capability = 'manage_options';
/**
* Filters the required user capability to access the Mailchimp for WordPress' settings pages, view the dashboard widgets.
*
* Defaults to `manage_options`
*
* @since 3.0
* @param string $capability
* @see https://codex.wordpress.org/Roles_and_Capabilities
*/
$capability = (string) apply_filters('mc4wp_admin_required_capability', $capability);
return $capability;
}
}
<?php
/**
* Class MC4WP_Admin_Ads
*
* @ignore
* @access private
*/
class MC4WP_Admin_Ads
{
/**
* @return bool Adds hooks
*/
public function add_hooks()
{
// don't hook if Premium is activated
if (defined('MC4WP_PREMIUM_VERSION')) {
return false;
}
add_filter('mc4wp_admin_plugin_meta_links', array( $this, 'plugin_meta_links' ));
add_action('mc4wp_admin_form_after_behaviour_settings_rows', array( $this, 'after_form_settings_rows' ));
add_action('mc4wp_admin_form_after_appearance_settings_rows', array( $this, 'after_form_appearance_settings_rows' ));
add_action('mc4wp_admin_sidebar', array( $this, 'admin_sidebar' ));
add_action('mc4wp_admin_footer', array( $this, 'admin_footer' ));
add_action('mc4wp_admin_other_settings', array( $this, 'ecommerce' ), 90);
add_filter('mc4wp_admin_menu_items', array( $this, 'add_menu_item' ));
add_action('mc4wp_admin_after_woocommerce_integration_settings', array( $this, 'ecommerce' ));
return true;
}
public function add_menu_item($items)
{
$items['extensions'] = array(
'title' => __('Add-ons', 'mailchimp-for-wp'),
'text' => __('Add-ons', 'mailchimp-for-wp'),
'slug' => 'extensions',
'callback' => array( $this, 'show_extensions_page' ),
'position' => 100,
);
return $items;
}
/**
* Add text row to "Form > Appearance" tab.
*/
public function after_form_appearance_settings_rows()
{
echo '<tr>';
echo '<td colspan="2">';
echo '<p class="description">';
echo sprintf(__('Want to customize the style of your form? <a href="%s">Try our Styles Builder</a> & edit the look of your forms with just a few clicks.', 'mailchimp-for-wp'), 'https://www.mc4wp.com/premium-features/#utm_source=wp-plugin&utm_medium=mailchimp-for-wp&utm_campaign=form-settings-link');
echo '</p>';
echo '</td>';
echo '</tr>';
}
/**
* Add text row to "Form > Settings" tab.
*/
public function after_form_settings_rows()
{
echo '<tr>';
echo '<td colspan="2">';
echo '<p class="description">';
if (rand(1, 2) === 1) {
echo sprintf(__('Be notified whenever someone subscribes? <a href="%s">Mailchimp for WordPress Premium</a> allows you to set up email notifications for your forms.', 'mailchimp-for-wp'), 'https://www.mc4wp.com/premium-features/#utm_source=wp-plugin&utm_medium=mailchimp-for-wp&utm_campaign=footer-link');
} else {
echo sprintf(__('Increased conversions? <a href="%s">Mailchimp for WordPress Premium</a> submits forms without reloading the entire page, resulting in a much better experience for your visitors.', 'mailchimp-for-wp'), 'https://www.mc4wp.com/premium-features/#utm_source=wp-plugin&utm_medium=mailchimp-for-wp&utm_campaign=form-settings-link');
}
echo '</p>';
echo '</td>';
echo '</tr>';
}
/**
* @param array $links
*
* @return array
*/
public function plugin_meta_links($links)
{
$links[] = '<a href="https://www.mc4wp.com/premium-features/#utm_source=wp-plugin&utm_medium=mailchimp-for-wp&utm_campaign=plugins-upgrade-link">' . __('Upgrade to Premium', 'mailchimp-for-wp') . '</a>';
return $links;
}
/**
* Add several texts to admin footer.
*/
public function admin_footer()
{
if (isset($_GET['view']) && $_GET['view'] === 'edit-form') {
// WPML & Polylang specific message
if (defined('ICL_LANGUAGE_CODE')) {
echo '<p class="description">' . sprintf(__('Do you want translated forms for all of your languages? <a href="%s">Try Mailchimp for WordPress Premium</a>, which does just that plus more.', 'mailchimp-for-wp'), 'https://www.mc4wp.com/premium-features/#utm_source=wp-plugin&utm_medium=mailchimp-for-wp&utm_campaign=footer-link') . '</p>';
return;
}
// General "edit form" message
echo '<p class="description">' . sprintf(__('Do you want to create more than one form? Our Premium add-on does just that! <a href="%s">Have a look at all Premium benefits</a>.', 'mailchimp-for-wp'), 'https://www.mc4wp.com/premium-features/#utm_source=wp-plugin&utm_medium=mailchimp-for-wp&utm_campaign=footer-link') . '</p>';
return;
}
// General message
echo '<p class="description">' . sprintf(__('Are you enjoying this plugin? The Premium add-on unlocks several powerful features. <a href="%s">Find out about all benefits now</a>.', 'mailchimp-for-wp'), 'https://www.mc4wp.com/premium-features/#utm_source=wp-plugin&utm_medium=mailchimp-for-wp&utm_campaign=footer-link') . '</p>';
}
/**
* Add email opt-in form to sidebar
*/
public function admin_sidebar()
{
echo '<style>.mc4wp-premium-box {
background: #fff8c5;
border: 1px solid #d4a72c66;
padding: 1em;
}</style>';
echo '<div class="mc4wp-box">';
echo '<div class="mc4wp-premium-box">';
echo '<h3>Mailchimp for WordPress Premium</h3>';
echo '<p>';
echo 'You are currently using the free version of Mailchimp for WordPress. ';
echo '</p>';
echo '<p>';
echo 'There is a Premium version of this plugin that adds several powerful features. Like multiple and improved sign-up forms, an easier way to visually enhance those forms, advanced e-commerce integration and keeping track of all sign-up attempts in your local WordPress database.';
echo '</p>';
echo '<p>You can have all those benefits for a small yearly fee. <a href="https://www.mc4wp.com/premium-features/#utm_source=wp-plugin&utm_medium=mailchimp-for-wp&utm_campaign=upgrade-box">Take a look at Mailchimp for WordPress Premium here</a>.</p>';
echo '</div>';
echo '</div>';
}
/**
* Show notice about E-Commerce integration in Premium.
*/
public function ecommerce()
{
// detect whether WooCommerce is installed & activated.
if (! class_exists('WooCommerce')) {
return;
}
echo '<div class="mc4wp-margin-m">';
echo '<h3>Advanced WooCommerce integration for Mailchimp</h3>';
echo '<p>';
echo __('Do you want to track all WooCommerce orders in Mailchimp so you can send emails based on the purchase activity of your subscribers?', 'mailchimp-for-wp');
echo '</p>';
echo '<p>';
echo sprintf(__('<a href="%1$s">Upgrade to Mailchimp for WordPress Premium</a> or <a href="%2$s">read more about Mailchimp\'s E-Commerce features</a>.', 'mailchimp-for-wp') . '</p>', 'https://www.mc4wp.com/premium-features/#utm_source=wp-plugin&utm_medium=mailchimp-for-wp&utm_campaign=other-settings-link', 'https://www.mc4wp.com/kb/what-is-ecommerce360/#utm_source=wp-plugin&utm_medium=mailchimp-for-wp&utm_campaign=other-settings-link');
echo '</p>';
echo '</div>';
}
public function show_extensions_page()
{
require MC4WP_PLUGIN_DIR . '/includes/views/extensions.php';
}
}
<?php
/**
* Class MC4WP_Admin_Review_Notice
*
* @ignore
*/
class MC4WP_Admin_Review_Notice
{
/**
* @var MC4WP_Admin_Tools
*/
protected $tools;
/**
* @var string
*/
protected $meta_key_dismissed = '_mc4wp_review_notice_dismissed';
/**
* MC4WP_Admin_Review_Notice constructor.
*
* @param MC4WP_Admin_Tools $tools
*/
public function __construct(MC4WP_Admin_Tools $tools)
{
$this->tools = $tools;
}
/**
* Add action & filter hooks.
*/
public function add_hooks()
{
add_action('admin_notices', array( $this, 'show' ));
add_action('mc4wp_admin_dismiss_review_notice', array( $this, 'dismiss' ));
}
/**
* Set flag in user meta so notice won't be shown.
*/
public function dismiss()
{
$user = wp_get_current_user();
update_user_meta($user->ID, $this->meta_key_dismissed, 1);
}
/**
* @return bool
*/
public function show()
{
// only show on Mailchimp for WordPress' pages.
if (! $this->tools->on_plugin_page()) {
return false;
}
// only show if 2 weeks have passed since first use.
$two_weeks_in_seconds = ( 60 * 60 * 24 * 14 );
if ($this->time_since_first_use() <= $two_weeks_in_seconds) {
return false;
}
// only show if user did not dismiss before
$user = wp_get_current_user();
if (get_user_meta($user->ID, $this->meta_key_dismissed, true)) {
return false;
}
echo '<div class="notice notice-info mc4wp-is-dismissible" id="mc4wp-review-notice">';
echo '<p>';
echo esc_html__('You\'ve been using Mailchimp for WordPress for some time now; we hope you love it!', 'mailchimp-for-wp'), ' <br />';
echo sprintf(wp_kses(__('If you do, please <a href="%s">leave us a 5★ rating on WordPress.org</a>. It would be of great help to us.', 'mailchimp-for-wp'), array( 'a' => array( 'href' => array() ) )), 'https://wordpress.org/support/view/plugin-reviews/mailchimp-for-wp?rate=5#new-post');
echo '</p>';
echo '<form method="POST" id="mc4wp-dismiss-review-form"><button type="submit" class="notice-dismiss"><span class="screen-reader-text">', esc_html__('Dismiss this notice.', 'mailchimp-for-wp'), '</span></button><input type="hidden" name="_mc4wp_action" value="dismiss_review_notice" />', wp_nonce_field('_mc4wp_action', '_wpnonce', true, false), '</form>';
echo '</div>';
return true;
}
/**
* @return int
*/
private function time_since_first_use()
{
$options = get_option('mc4wp', array());
if (! is_array($options)) {
$options = array();
}
// option was never added before, do it now.
if (empty($options['first_activated_on'])) {
$options['first_activated_on'] = time();
update_option('mc4wp', $options);
}
return time() - $options['first_activated_on'];
}
}
<?php
/**
* Class MC4WP_DB_Upgrader
*
* This class takes care of loading migration files from the specified migrations directory.
* Migration files should only use default WP functions and NOT use code which might not be there in the future.
*
* @ignore
*/
class MC4WP_Upgrade_Routines
{
/**
* @var float
*/
protected $version_from = 0;
/**
* @var float
*/
protected $version_to = 0;
/**
* @var string
*/
protected $migrations_dir = '';
/**
* @param float $from
* @param float $to
*/
public function __construct($from, $to, $migrations_dir)
{
$this->version_from = $from;
$this->version_to = $to;
$this->migrations_dir = $migrations_dir;
}
/**
* Run the various upgrade routines, all the way up to the latest version
*/
public function run()
{
$migrations = $this->find_migrations();
// run in sub-function for scope
array_map(array( $this, 'run_migration' ), $migrations);
}
/**
* @return array
*/
public function find_migrations()
{
$files = glob(rtrim($this->migrations_dir, '/') . '/*.php');
$migrations = array();
// return empty array when glob returns non-array value.
if (! is_array($files)) {
return $migrations;
}
foreach ($files as $file) {
$migration = basename($file);
$parts = explode('-', $migration);
$version = $parts[0];
if (version_compare($this->version_from, $version, '<')) {
$migrations[] = $file;
}
}
return $migrations;
}
/**
* Include a migration file and runs it.
*
* @param string $file
*/
protected function run_migration($file)
{
include $file;
}
}
<?php
defined('ABSPATH') or exit;
// get options
$form_options = get_option('mc4wp_lite_form', array());
// bail if there are no previous options
if (empty($form_options)) {
return;
}
// bail if there are Pro forms already
$has_forms = get_posts(
array(
'post_type' => 'mc4wp-form',
'post_status' => 'publish',
'numberposts' => 1,
)
);
// There are forms already, don't continue.
if (! empty($has_forms)) {
// delete option as it apparently exists.
delete_option('mc4wp_lite_form');
return;
}
// create post type for form
$id = wp_insert_post(
array(
'post_type' => 'mc4wp-form',
'post_status' => 'publish',
'post_title' => __('Default sign-up form', 'mailchimp-for-wp'),
'post_content' => ( empty($form_options['markup']) ) ? '' : $form_options['markup'],
)
);
// set default_form_id
update_option('mc4wp_default_form_id', $id);
// set form settings
$setting_keys = array(
'css',
'custom_theme_color',
'double_optin',
'update_existing',
'replace_interests',
'send_welcome',
'redirect',
'hide_after_success',
);
$settings = array();
foreach ($setting_keys as $setting_key) {
// use isset to account for "0" settings
if (isset($form_options[ $setting_key ])) {
$settings[ $setting_key ] = $form_options[ $setting_key ];
}
}
// get only keys of lists setting
if (isset($form_options['lists'])) {
$settings['lists'] = array_keys($form_options['lists']);
}
update_post_meta($id, '_mc4wp_settings', $settings);
// set form message texts
$message_keys = array(
'text_subscribed',
'text_error',
'text_invalid_email',
'text_already_subscribed',
'text_required_field_missing',
'text_unsubscribed',
'text_not_subscribed',
);
foreach ($message_keys as $message_key) {
if (! empty($form_options[ $message_key ])) {
update_post_meta($id, $message_key, $form_options[ $message_key ]);
}
}
// delete old option
delete_option('mc4wp_lite_form');
<?php
defined('ABSPATH') or exit;
$global_options = (array) get_option('mc4wp_form', array());
// find all form posts
$posts = get_posts(
array(
'post_type' => 'mc4wp-form',
'post_status' => 'publish',
'numberposts' => -1,
)
);
$css_map = array(
'default' => 'basic',
'custom' => 'styles-builder',
'light' => 'theme-light',
'dark' => 'theme-dark',
'red' => 'theme-red',
'green' => 'theme-green',
'blue' => 'theme-blue',
'custom-color' => 'theme-custom-color',
);
$stylesheets = array();
foreach ($posts as $post) {
// get form options from post meta directly
$options = (array) get_post_meta($post->ID, '_mc4wp_settings', true);
// store all global options in scoped form settings
// do this BEFORE changing css key, so we take that as well.
foreach ($global_options as $key => $value) {
if (strlen($value) > 0 && ( ! isset($options[ $key ]) || strlen($options[ $key ]) == 0 )) {
$options[ $key ] = $value;
}
}
// update "css" option value
if (isset($options['css']) && isset($css_map[ $options['css'] ])) {
$options['css'] = $css_map[ $options['css'] ];
}
// create stylesheets option
if (! empty($options['css'])) {
$stylesheet = $options['css'];
if (strpos($stylesheet, 'theme-') === 0) {
$stylesheet = 'themes';
}
if (! in_array($stylesheet, $stylesheets)) {
$stylesheets[] = $stylesheet;
}
}
update_post_meta($post->ID, '_mc4wp_settings', $options);
}
// update stylesheets option
update_option('mc4wp_form_stylesheets', $stylesheets);
// delete old options
delete_option('mc4wp_form');
<?php
defined('ABSPATH') or exit;
// find all form posts
$posts = get_posts(
array(
'post_type' => 'mc4wp-form',
'post_status' => 'publish',
'numberposts' => -1,
)
);
// set form message texts
$message_keys = array(
'text_subscribed',
'text_error',
'text_invalid_email',
'text_already_subscribed',
'text_required_field_missing',
'text_unsubscribed',
'text_not_subscribed',
);
foreach ($posts as $post) {
$settings = get_post_meta($post->ID, '_mc4wp_settings', true);
foreach ($message_keys as $key) {
if (empty($settings[ $key ])) {
continue;
}
$message = $settings[ $key ];
// move message setting over to post meta
update_post_meta($post->ID, $key, $message);
unset($settings[ $key ]);
}
// update post meta with unset message keys
update_post_meta($post->ID, '_mc4wp_settings', $settings);
}
<?php
defined('ABSPATH') or exit;
// transfer option
$options = (array) get_option('mc4wp_lite', array());
// merge options, with Pro options taking precedence
$pro_options = (array) get_option('mc4wp', array());
$options = array_merge($options, $pro_options);
// update options
update_option('mc4wp', $options);
// delete old option
delete_option('mc4wp_lite');
<?php
defined('ABSPATH') or exit;
$old_options = get_option('mc4wp_lite_checkbox', array());
$pro_options = get_option('mc4wp_checkbox', array());
if (! empty($pro_options)) {
$old_options = array_merge($old_options, $pro_options);
}
// do we have to do something?
if (empty($old_options)) {
return;
}
// find activated integrations (show_at_xxx options)
$new_options = array();
$map = array(
'comment_form' => 'wp-comment-form',
'registration_form' => 'wp-registration-form',
'buddypress_form' => 'buddypress',
'bbpres_forms' => 'bbpress',
'woocommerce_checkout' => 'woocommerce',
'edd_checkout' => 'easy-digital-downloads',
);
$option_keys = array(
'label',
'precheck',
'css',
'lists',
'double_optin',
'update_existing',
'replace_interests',
'send_welcome',
);
foreach ($map as $old_integration_slug => $new_integration_slug) {
// check if integration is enabled using its old slug
$show_key = sprintf('show_at_%s', $old_integration_slug);
if (empty($old_options[ $show_key ])) {
continue;
}
$options = array(
'enabled' => 1,
);
foreach ($option_keys as $option_key) {
if (isset($old_options[ $option_key ])) {
$options[ $option_key ] = $old_options[ $option_key ];
}
}
// add to new options
$new_options[ $new_integration_slug ] = $options;
}
// save new settings
update_option('mc4wp_integrations', $new_options);
// delete old options
delete_option('mc4wp_lite_checkbox');
delete_option('mc4wp_checkbox');
<?php
defined('ABSPATH') or exit;
// move stylebuilders file to bundle
$file = (string) get_option('mc4wp_custom_css_file', '');
if (empty($file)) {
return;
}
$uploads = wp_upload_dir();
// figure out absolute file path
$prefix = str_replace('http:', '', $uploads['baseurl']);
$relative_path = str_replace($prefix, '', $file);
// get part before ?
if (strpos($relative_path, '?') !== false) {
$parts = explode('?', $relative_path);
$relative_path = array_shift($parts);
}
// This is the absolute path to the file, he he..
$file = $uploads['basedir'] . $relative_path;
if (file_exists($file)) {
// create directory, if necessary
$dir = $uploads['basedir'] . '/mc4wp-stylesheets';
if (! file_exists($dir)) {
@mkdir($dir, 0755);
}
@chmod($dir, 0755);
// Move file to new location
$new_file = $dir . '/bundle.css';
$success = rename($file, $new_file);
}
// remove old option
delete_option('mc4wp_custom_css_file');
<?php
defined('ABSPATH') or exit;
$section_widgets = get_option('sidebars_widgets', array());
$replaced = false;
foreach ($section_widgets as $section => $widgets) {
// WP has an "array_version" key that is not an array...
if (! is_array($widgets)) {
continue;
}
// loop through widget ID's
foreach ($widgets as $key => $widget_id) {
// does this widget ID start with "mc4wp_widget"?
if (strpos($widget_id, 'mc4wp_widget') === 0) {
// replace "mc4wp_widget" with "mc4wp_form_widget"
$new_widget_id = str_replace('mc4wp_widget', 'mc4wp_form_widget', $widget_id);
$section_widgets[ $section ][ $key ] = $new_widget_id;
$replaced = true;
}
}
}
// update option if we made changes
if ($replaced) {
update_option('sidebars_widgets', $section_widgets);
}
// update widget options
$options = get_option('widget_mc4wp_widget', false);
if ($options) {
update_option('widget_mc4wp_form_widget', $options);
// delete old option
delete_option('widget_mc4wp_widget');
}
<?php
defined('ABSPATH') or exit;
$options = get_option('mc4wp_integrations', array());
if (! empty($options['woocommerce']) && ! empty($options['woocommerce']['position'])) {
$options['woocommerce']['position'] = sprintf('checkout_%s', $options['woocommerce']['position']);
}
update_option('mc4wp_integrations', $options);
<?php
defined('ABSPATH') or exit;
/**
* @ignore
* @return object
*/
function _mc4wp_400_find_grouping_for_interest_category($groupings, $interest_category)
{
foreach ($groupings as $grouping) {
// cast to stdClass because of missing class
$grouping = (object) (array) $grouping;
if ($grouping->name === $interest_category->title) {
return $grouping;
}
}
return null;
}
/**
* @ignore
* @return object
*/
function _mc4wp_400_find_group_for_interest($groups, $interest)
{
foreach ($groups as $group_id => $group_name) {
if ($group_name === $interest->name) {
return (object) array(
'name' => $group_name,
'id' => $group_id,
);
}
}
return null;
}
// in case the migration is _very_ late to the party
if (! class_exists('MC4WP_API_V3')) {
return;
}
$options = get_option('mc4wp', array());
if (empty($options['api_key'])) {
return;
}
// get current state from transient
$lists = get_transient('mc4wp_mailchimp_lists_fallback');
if (empty($lists)) {
return;
}
@set_time_limit(600);
$api_v3 = new MC4WP_API_V3($options['api_key']);
$map = array();
foreach ($lists as $list) {
// cast to stdClass because of missing classes
$list = (object) (array) $list;
// no groupings? easy!
if (empty($list->groupings)) {
continue;
}
// fetch (new) interest categories for this list
try {
$interest_categories = $api_v3->get_list_interest_categories($list->id);
} catch (MC4WP_API_Exception $e) {
continue;
}
foreach ($interest_categories as $interest_category) {
// compare interest title with grouping name, if it matches, get new id.
$grouping = _mc4wp_400_find_grouping_for_interest_category($list->groupings, $interest_category);
if (! $grouping) {
continue;
}
$groups = array();
try {
$interests = $api_v3->get_list_interest_category_interests($list->id, $interest_category->id);
} catch (MC4WP_API_Exception $e) {
continue;
}
foreach ($interests as $interest) {
$group = _mc4wp_400_find_group_for_interest($grouping->groups, $interest);
if ($group) {
$groups[ $group->id ] = $interest->id;
$groups[ $group->name ] = $interest->id;
}
}
$map[ (string) $grouping->id ] = array(
'id' => $interest_category->id,
'groups' => $groups,
);
}
}
if (! empty($map)) {
update_option('mc4wp_groupings_map', $map);
}
<?php
defined('ABSPATH') or exit;
/** @ignore */
function _mc4wp_400_replace_comma_with_pipe($matches)
{
$old = $matches[1];
$new = str_replace(',', '|', $old);
return str_replace($old, $new, $matches[0]);
}
// get all forms
$posts = get_posts(
array(
'post_type' => 'mc4wp-form',
'numberposts' => -1,
)
);
foreach ($posts as $post) {
// find hidden field values in form and pass through replace function
$old = $post->post_content;
$new = preg_replace_callback('/type="hidden" .* value="(.*)"/i', '_mc4wp_400_replace_comma_with_pipe', $old);
// update post if we replaced something
if ($new != $old) {
$post->post_content = $new;
wp_update_post($post);
}
}
<?php
defined('ABSPATH') or exit;
// get old log filename
$upload_dir = wp_upload_dir(null, false);
$old_filename = trailingslashit($upload_dir['basedir']) . 'mc4wp-debug.log';
$new_filename = trailingslashit($upload_dir['basedir']) . 'mc4wp-debug-log.php';
// check if old default log file exists
if (! file_exists($old_filename)) {
return;
}
// rename to new file.
@rename($old_filename, $new_filename);
// if success, insert php exit tag as first line
if (file_exists($new_filename)) {
$handle = fopen($new_filename, 'r+');
if (is_resource($handle)) {
// make sure first line of log file is a PHP tag + exit statement (to prevent direct file access)
$line = fgets($handle);
$php_exit_string = '<?php exit; ?>';
if (strpos($line, $php_exit_string) !== 0) {
rewind($handle);
fwrite($handle, $php_exit_string . PHP_EOL . $line);
}
fclose($handle);
}
}
<?php
defined('ABSPATH') or exit;
if (function_exists('mc4wp_refresh_mailchimp_lists')) {
mc4wp_refresh_mailchimp_lists();
}
delete_transient('mc4wp_mailchimp_lists_v3');
delete_option('mc4wp_mailchimp_lists_v3_fallback');
wp_schedule_event(strtotime('tomorrow 3 am'), 'daily', 'mc4wp_refresh_mailchimp_lists');
<?php
defined('ABSPATH') or exit;
wp_clear_scheduled_hook('mc4wp_refresh_mailchimp_lists');
$time_string = sprintf('tomorrow %d:%d%d am', rand(1, 6), rand(0, 5), rand(0, 9));
wp_schedule_event(strtotime($time_string), 'daily', 'mc4wp_refresh_mailchimp_lists');
<?php
global $wpdb;
$wpdb->query("DELETE FROM {$wpdb->options} WHERE option_name LIKE 'mc4wp_mailchimp_list_%'");
<?php
defined('ABSPATH') or exit;
// get old filename
$upload_dir = wp_upload_dir(null, false);
$old_filename = trailingslashit($upload_dir['basedir']) . 'mc4wp-debug-log.php';
// if old file exists, move it to new location
if (is_file($old_filename)) {
$new_filename = $upload_dir['basedir'] . '/mailchimp-for-wp/debug-log.php';
$dir = dirname($new_filename);
if (! is_dir($dir)) {
mkdir($dir, 0755, true);
}
rename($old_filename, $new_filename);
}
<?php
class MC4WP_API_V3_Client
{
/**
* @var string
*/
private $api_key;
/**
* @var string
*/
private $api_url = 'https://api.mailchimp.com/3.0/';
/**
* @var array
*/
private $last_response;
/**
* @var array
*/
private $last_request;
/**
* Constructor
*
* @param string $api_key
*/
public function __construct($api_key)
{
$this->api_key = $api_key;
$dash_position = strpos($api_key, '-');
if ($dash_position !== false) {
$this->api_url = str_replace('//api.', '//' . substr($api_key, $dash_position + 1) . '.api.', $this->api_url);
}
}
/**
* @param string $resource
* @param array $args
*
* @return mixed
* @throws MC4WP_API_Exception
*/
public function get($resource, array $args = array())
{
return $this->request('GET', $resource, $args);
}
/**
* @param string $resource
* @param array $data
*
* @return mixed
* @throws MC4WP_API_Exception
*/
public function post($resource, array $data)
{
return $this->request('POST', $resource, $data);
}
/**
* @param string $resource
* @param array $data
* @return mixed
* @throws MC4WP_API_Exception
*/
public function put($resource, array $data)
{
return $this->request('PUT', $resource, $data);
}
/**
* @param string $resource
* @param array $data
* @return mixed
* @throws MC4WP_API_Exception
*/
public function patch($resource, array $data)
{
return $this->request('PATCH', $resource, $data);
}
/**
* @param string $resource
* @return mixed
* @throws MC4WP_API_Exception
*/
public function delete($resource)
{
return $this->request('DELETE', $resource);
}
/**
* @param string $method
* @param string $resource
* @param array $data
*
* @return mixed
*
* @throws MC4WP_API_Exception
*/
private function request($method, $resource, array $data = array())
{
$this->reset();
// don't bother if no API key was given.
if (empty($this->api_key)) {
throw new MC4WP_API_Exception('Missing API key', 001);
}
$method = strtoupper(trim($method));
$url = $this->api_url . ltrim($resource, '/');
$args = array(
'method' => $method,
'headers' => $this->get_headers(),
'timeout' => 20,
'sslverify' => apply_filters('mc4wp_use_sslverify', true),
);
if (! empty($data)) {
if (in_array($method, array( 'GET', 'DELETE' ), true)) {
$url = add_query_arg($data, $url);
} else {
$args['headers']['Content-Type'] = 'application/json';
$args['body'] = json_encode($data);
}
}
/**
* Filter the request arguments for all requests generated by this class
*
* @param array $args
*/
$args = apply_filters('mc4wp_http_request_args', $args, $url);
// perform request
$response = wp_remote_request($url, $args);
// store request & response
$args['url'] = $url;
$this->last_request = $args;
$this->last_response = $response;
// parse response
$data = $this->parse_response($response);
return $data;
}
/**
* @return array
*/
private function get_headers()
{
global $wp_version;
$headers = array(
'Authorization' => sprintf('Basic %s', base64_encode('mc4wp:' . $this->api_key)),
'User-Agent' => sprintf('mc4wp/%s; WordPress/%s; %s', MC4WP_VERSION, $wp_version, home_url()),
);
// Copy Accept-Language from browser headers
if (! empty($_SERVER['HTTP_ACCEPT_LANGUAGE'])) {
$headers['Accept-Language'] = $_SERVER['HTTP_ACCEPT_LANGUAGE'];
}
return $headers;
}
/**
* @param array|WP_Error $response
*
* @return mixed
*
* @throws MC4WP_API_Connection_Exception|MC4WP_API_Resource_Not_Found_Exception|MC4WP_API_Exception
*/
private function parse_response($response)
{
if ($response instanceof WP_Error) {
throw new MC4WP_API_Connection_Exception($response->get_error_message(), (int) $response->get_error_code(), $this->last_request);
}
// decode response body
$code = (int) wp_remote_retrieve_response_code($response);
$message = wp_remote_retrieve_response_message($response);
$body = wp_remote_retrieve_body($response);
// set body to "true" in case Mailchimp returned No Content
if ($code < 300 && empty($body)) {
$body = 'true';
}
$data = json_decode($body);
if ($code >= 400) {
// check for akamai errors
// {"type":"akamai_error_message","title":"akamai_503","status":503,"ref_no":"Reference Number: 00.950e16c3.1498559813.1450dbe2"}
if (is_object($data) && isset($data->type) && $data->type === 'akamai_error_message') {
throw new MC4WP_API_Connection_Exception($message, $code, $this->last_request, $this->last_response, $data);
}
if ($code === 404) {
throw new MC4WP_API_Resource_Not_Found_Exception($message, $code, $this->last_request, $this->last_response, $data);
}
// mailchimp returned an error..
throw new MC4WP_API_Exception($message, $code, $this->last_request, $this->last_response, $data);
}
// throw exception if unable to decode response
if ($data === null) {
throw new MC4WP_API_Exception($message, $code, $this->last_request, $this->last_response);
}
return $data;
}
/**
* Empties all data from previous response
*/
private function reset()
{
$this->last_response = null;
$this->last_request = null;
}
/**
* @return string
*/
public function get_last_response_body()
{
return wp_remote_retrieve_body($this->last_response);
}
/**
* @return array
*/
public function get_last_response_headers()
{
return wp_remote_retrieve_headers($this->last_response);
}
/**
* @return array|WP_Error
*/
public function get_last_response()
{
return $this->last_response;
}
}
<?php
class MC4WP_API_Connection_Exception extends MC4WP_API_Exception
{
}
<?php
/**
* Class MC4WP_API_Exception
*
* @property string $title
* @property string $detail
* @property array $errors
*/
class MC4WP_API_Exception extends Exception
{
/**
* @var object
*/
public $response = array();
/**
* @var object
*/
public $request = array();
/**
* @var array
*/
public $response_data = array();
/**
* MC4WP_API_Exception constructor.
*
* @param string $message
* @param int $code
* @param array $request
* @param array $response
* @param object $data
*/
public function __construct($message, $code, $request = null, $response = null, $data = null)
{
parent::__construct($message, $code);
$this->request = $request;
$this->response = $response;
$this->response_data = $data;
}
/**
* Backwards compatibility for direct property access.
* @param string $property
* @return mixed
*/
public function __get($property)
{
if (in_array($property, array( 'title', 'detail', 'errors' ), true)) {
if (! empty($this->response_data) && isset($this->response_data->{$property})) {
return $this->response_data->{$property};
}
return '';
}
}
/**
* @return string
*/
public function __toString()
{
$string = $this->message . '.';
// add errors from response data returned by Mailchimp
if (! empty($this->response_data)) {
if (! empty($this->response_data->title) && $this->response_data->title !== $this->getMessage()) {
$string .= ' ' . $this->response_data->title . '.';
}
// add detail message
if (! empty($this->response_data->detail)) {
$string .= ' ' . $this->response_data->detail;
}
// add field specific errors
if (! empty($this->response_data->errors) && isset($this->response_data->errors[0]->field)) {
// strip off obsolete msg
$string = str_replace('For field-specific details, see the \'errors\' array.', '', $string);
// generate list of field errors
$field_errors = array();
foreach ($this->response_data->errors as $error) {
if (! empty($error->field)) {
$field_errors[] = sprintf('- %s : %s', $error->field, $error->message);
} else {
$field_errors[] = sprintf('- %s', $error->message);
}
}
$string .= " \n" . join("\n", $field_errors);
}
}
// Add request data
if (! empty($this->request) && is_array($this->request)) {
$string .= "\n\n" . sprintf("Request: \n%s %s\n", $this->request['method'], $this->request['url']);
// foreach ( $this->request['headers'] as $key => $value ) {
// $string .= sprintf( "%s: %s\n", $key, $value );
// }
if (! empty($this->request['body'])) {
$string .= "\n" . $this->request['body'];
}
}
// Add response data
if (! empty($this->response) && is_array($this->response)) {
$response_code = wp_remote_retrieve_response_code($this->response);
$response_message = wp_remote_retrieve_response_message($this->response);
$response_body = wp_remote_retrieve_body($this->response);
$string .= "\n\n" . sprintf("Response: \n%d %s\n%s", $response_code, $response_message, $response_body);
}
return $string;
}
}
<?php
class MC4WP_API_Resource_Not_Found_Exception extends MC4WP_API_Exception
{
// Thrown when a requested resource does not exist in Mailchimp
}
<?php
/**
* Class MC4WP_Service_Container
*
* @access private
* @ignore
*/
class MC4WP_Container implements ArrayAccess
{
/**
* @var array
*/
protected $services = array();
/**
* @var array
*/
protected $resolved_services = array();
/**
* @param string $name
* @return boolean
*/
public function has($name)
{
return isset($this->services[ $name ]);
}
/**
* @param string $name
*
* @return mixed
* @throws Exception
*/
public function get($name)
{
if (! $this->has($name)) {
throw new Exception(sprintf('No service named %s was registered.', $name));
}
$service = $this->services[ $name ];
// is this a resolvable service?
if (is_callable($service)) {
// resolve service if it's not resolved yet
if (! isset($this->resolved_services[ $name ])) {
$this->resolved_services[ $name ] = call_user_func($service);
}
return $this->resolved_services[ $name ];
}
return $this->services[ $name ];
}
/**
* (PHP 5 &gt;= 5.0.0)<br/>
* Whether a offset exists
* @link http://php.net/manual/en/arrayaccess.offsetexists.php
*
* @param mixed $offset <p>
* An offset to check for.
* </p>
*
* @return boolean true on success or false on failure.
* </p>
* <p>
* The return value will be casted to boolean if non-boolean was returned.
*/
#[\ReturnTypeWillChange]
public function offsetExists($offset)
{
return $this->has($offset);
}
/**
* (PHP 5 &gt;= 5.0.0)<br/>
* Offset to retrieve
* @link http://php.net/manual/en/arrayaccess.offsetget.php
*
* @param mixed $offset <p>
* The offset to retrieve.
* </p>
*
* @return mixed Can return all value types.
*/
#[\ReturnTypeWillChange]
public function offsetGet($offset)
{
return $this->get($offset);
}
/**
* (PHP 5 &gt;= 5.0.0)<br/>
* Offset to set
* @link http://php.net/manual/en/arrayaccess.offsetset.php
*
* @param mixed $offset <p>
* The offset to assign the value to.
* </p>
* @param mixed $value <p>
* The value to set.
* </p>
*
* @return void
*/
#[\ReturnTypeWillChange]
public function offsetSet($offset, $value)
{
$this->services[ $offset ] = $value;
}
/**
* (PHP 5 &gt;= 5.0.0)<br/>
* Offset to unset
* @link http://php.net/manual/en/arrayaccess.offsetunset.php
*
* @param mixed $offset <p>
* The offset to unset.
* </p>
*
* @return void
*/
#[\ReturnTypeWillChange]
public function offsetUnset($offset)
{
unset($this->services[ $offset ]);
}
}
<?php
/**
* Class MC4WP_Debug_Log_Reader
*/
class MC4WP_Debug_Log_Reader
{
/**
* @var resource|null
*/
private $handle;
/**
* @var string
*/
private static $regex = '/^(\[[\d \-\:]+\]) (\w+\:) (.*)$/S';
/**
* @var string
*/
private static $html_template = '<span class="time">$1</span> <span class="level">$2</span> <span class="message">$3</span>';
/**
* @var string The log file location.
*/
private $file;
/**
* MC4WP_Debug_Log_Reader constructor.
*
* @param $file
*/
public function __construct($file)
{
$this->file = $file;
}
/**
* @return string
*/
public function all()
{
return file_get_contents($this->file);
}
/**
* Sets file pointer to $n of lines from the end of file.
*
* @param int $n
*/
private function seek_line_from_end($n)
{
$line_count = 0;
// get line count
while (! feof($this->handle)) {
fgets($this->handle);
++$line_count;
}
// rewind to beginning
rewind($this->handle);
// calculate target
$target = $line_count - $n;
$target = $target > 1 ? $target : 1; // always skip first line because oh PHP header
$current = 0;
// keep reading until we're at target
while ($current < $target) {
fgets($this->handle);
++$current;
}
}
/**
* @return string|null
*/
public function read()
{
// open file if not yet opened
if (! is_resource($this->handle)) {
// doesn't exist?
if (! file_exists($this->file)) {
return null;
}
$this->handle = @fopen($this->file, 'r');
// unable to read?
if (! is_resource($this->handle)) {
return null;
}
// set pointer to 1000 files from EOF
$this->seek_line_from_end(1000);
}
// stop reading once we're at the end
if (feof($this->handle)) {
fclose($this->handle);
$this->handle = null;
return null;
}
// read line, up to 8kb
$text = fgets($this->handle);
// strip tags & trim
$text = strip_tags($text);
$text = trim($text);
return $text;
}
/**
* @return string
*/
public function read_as_html()
{
$line = $this->read();
// null means end of file
if (is_null($line)) {
return null;
}
// empty string means empty line, but not yet eof
if (empty($line)) {
return '';
}
$line = preg_replace(self::$regex, self::$html_template, $line);
return $line;
}
/**
* Reads X number of lines.
*
* If $start is negative, reads from end of log file.
*
* @param int $start
* @param int $number
* @return string
*/
public function lines($start, $number)
{
$handle = fopen($start, 'r');
$lines = '';
$current_line = 0;
while ($current_line < $number) {
$lines .= fgets($handle);
}
fclose($handle);
return $lines;
}
}
<?php
/**
* Class MC4WP_Debug_Log
*
* Simple logging class which writes to a file, loosely based on PSR-3.
*/
class MC4WP_Debug_Log
{
/**
* Detailed debug information
*/
const DEBUG = 100;
/**
* Interesting events
*
* Examples: Visitor subscribed
*/
const INFO = 200;
/**
* Exceptional occurrences that are not errors
*
* Examples: User already subscribed
*/
const WARNING = 300;
/**
* Runtime errors
*/
const ERROR = 400;
/**
* Logging levels from syslog protocol defined in RFC 5424
*
* @var array $levels Logging levels
*/
protected static $levels = array(
self::DEBUG => 'DEBUG',
self::INFO => 'INFO',
self::WARNING => 'WARNING',
self::ERROR => 'ERROR',
);
/**
* @var string The file to which messages should be written.
*/
public $file;
/**
* @var int Only write messages with this level or higher
*/
public $level;
/**
* @var resource
*/
protected $stream;
/**
* MC4WP_Debug_Log constructor.
*
* @param string $file
* @param mixed $level;
*/
public function __construct($file, $level = self::DEBUG)
{
$this->file = $file;
$this->level = self::to_level($level);
}
/**
* @param mixed $level
* @param string $message
* @return boolean
*/
public function log($level, $message)
{
$level = self::to_level($level);
// only log if message level is higher than log level
if ($level < $this->level) {
return false;
}
// obfuscate email addresses in log message since log might be public.
$message = mc4wp_obfuscate_email_addresses((string) $message);
// first, get rid of everything between "invisible" tags
$message = preg_replace('/<(?:style|script|head)>.+?<\/(?:style|script|head)>/is', '', $message);
// then, strip tags (while retaining content of these tags)
$message = strip_tags($message);
$message = trim($message);
/**
* Modifies the message that is written to the debug log.
* Return an empty string to skip logging this message altogether.
*
* @param string $message
*/
$message = apply_filters('mc4wp_debug_log_message', $message);
if (empty($message)) {
return false;
}
// generate line
$level_name = self::get_level_name($level);
$datetime = gmdate('Y-m-d H:i:s', time() + ( get_option('gmt_offset', 0) * HOUR_IN_SECONDS ));
$message = sprintf('[%s] %s: %s', $datetime, $level_name, $message) . PHP_EOL;
// did we open stream yet?
if (! is_resource($this->stream)) {
// attempt to open stream
$this->stream = @fopen($this->file, 'c+');
if (! is_resource($this->stream)) {
return false;
}
// make sure first line of log file is a PHP tag + exit statement (to prevent direct file access)
$line = fgets($this->stream);
$php_exit_string = '<?php exit; ?>';
if (strpos($line, $php_exit_string) !== 0) {
rewind($this->stream);
fwrite($this->stream, $php_exit_string . PHP_EOL . $line);
}
// place pointer at end of file
fseek($this->stream, 0, SEEK_END);
}
// lock file while we write, ignore errors (not much we can do)
flock($this->stream, LOCK_EX);
// write the message to the file
fwrite($this->stream, $message);
// unlock file again, but don't close it for remainder of this request
flock($this->stream, LOCK_UN);
return true;
}
/**
* @param string $message
* @return boolean
*/
public function warning($message)
{
return $this->log(self::WARNING, $message);
}
/**
* @param string $message
* @return boolean
*/
public function info($message)
{
return $this->log(self::INFO, $message);
}
/**
* @param string $message
* @return boolean
*/
public function error($message)
{
return $this->log(self::ERROR, $message);
}
/**
* @param string $message
* @return boolean
*/
public function debug($message)
{
return $this->log(self::DEBUG, $message);
}
/**
* Converts PSR-3 levels to local ones if necessary
*
* @param string|int Level number or name (PSR-3)
* @return int
*/
public static function to_level($level)
{
if (is_string($level)) {
$level = strtoupper($level);
if (defined(__CLASS__ . '::' . $level)) {
return constant(__CLASS__ . '::' . $level);
}
throw new InvalidArgumentException('Level "' . $level . '" is not defined, use one of: ' . implode(', ', array_keys(self::$levels)));
}
return $level;
}
/**
* Gets the name of the logging level.
*
* @param int $level
* @return string
*/
public static function get_level_name($level)
{
if (! isset(self::$levels[ $level ])) {
throw new InvalidArgumentException('Level "' . $level . '" is not defined, use one of: ' . implode(', ', array_keys(self::$levels)));
}
return self::$levels[ $level ];
}
/**
* Tests if the log file is writable
*
* @return bool
*/
public function test()
{
$handle = @fopen($this->file, 'a');
$writable = false;
if (is_resource($handle)) {
$writable = true;
fclose($handle);
}
return $writable;
}
}
<?php
/**
* Class MC4WP_Dynamic_Content_Tags
*
* @access private
* @ignore
*/
abstract class MC4WP_Dynamic_Content_Tags
{
/**
* @var string The escape function for replacement values.
*/
protected $escape_function = null;
/**
* @var array Array of registered dynamic content tags
*/
protected $tags = array();
/**
* Register template tags
*/
protected function register()
{
// Global tags can go here
$this->tags['cookie'] = array(
'description' => sprintf(__('Data from a cookie.', 'mailchimp-for-wp')),
'callback' => array( $this, 'get_cookie' ),
'example' => "cookie name='my_cookie' default='Default Value'",
);
$this->tags['email'] = array(
'description' => __('The email address of the current visitor (if known).', 'mailchimp-for-wp'),
'callback' => array( $this, 'get_email' ),
);
$this->tags['current_url'] = array(
'description' => __('The URL of the page.', 'mailchimp-for-wp'),
'callback' => 'mc4wp_get_request_url',
);
$this->tags['current_path'] = array(
'description' => __('The path of the page.', 'mailchimp-for-wp'),
'callback' => 'mc4wp_get_request_path',
);
$this->tags['date'] = array(
'description' => sprintf(__('The current date. Example: %s.', 'mailchimp-for-wp'), '<strong>' . gmdate('Y/m/d', time() + ( get_option('gmt_offset') * HOUR_IN_SECONDS )) . '</strong>'),
'replacement' => gmdate('Y/m/d', time() + ( get_option('gmt_offset') * HOUR_IN_SECONDS )),
);
$this->tags['time'] = array(
'description' => sprintf(__('The current time. Example: %s.', 'mailchimp-for-wp'), '<strong>' . gmdate('H:i:s', time() + ( get_option('gmt_offset') * HOUR_IN_SECONDS )) . '</strong>'),
'replacement' => gmdate('H:i:s', time() + ( get_option('gmt_offset') * HOUR_IN_SECONDS )),
);
$this->tags['language'] = array(
'description' => sprintf(__('The site\'s language. Example: %s.', 'mailchimp-for-wp'), '<strong>' . get_locale() . '</strong>'),
'callback' => 'get_locale',
);
$this->tags['ip'] = array(
'description' => sprintf(__('The visitor\'s IP address. Example: %s.', 'mailchimp-for-wp'), '<strong>' . mc4wp_get_request_ip_address() . '</strong>'),
'callback' => 'mc4wp_get_request_ip_address',
);
$this->tags['user'] = array(
'description' => sprintf(__('The property of the currently logged-in user.', 'mailchimp-for-wp')),
'callback' => array( $this, 'get_user_property' ),
'example' => "user property='user_email'",
);
$this->tags['post'] = array(
'description' => sprintf(__('Property of the current page or post.', 'mailchimp-for-wp')),
'callback' => array( $this, 'get_post_property' ),
'example' => "post property='ID'",
);
}
/**
* @return array
*/
public function all()
{
if ($this->tags === array()) {
$this->register();
}
return $this->tags;
}
/**
* @param array $matches
*
* @return string
*/
protected function replace_tag(array $matches)
{
$tags = $this->all();
$tag = $matches[1];
if (isset($tags[ $tag ])) {
$config = $tags[ $tag ];
$replacement = '';
if (isset($config['replacement'])) {
$replacement = $config['replacement'];
} elseif (isset($config['callback'])) {
// parse attributes
$attributes = array();
if (isset($matches[2])) {
$attribute_string = $matches[2];
$attributes = shortcode_parse_atts($attribute_string);
}
// call function
$replacement = call_user_func($config['callback'], $attributes);
}
if (is_callable($this->escape_function)) {
$replacement = call_user_func($this->escape_function, $replacement);
}
return $replacement;
}
// default to not replacing it
return $matches[0];
}
/**
* @param string $string The string containing dynamic content tags.
* @param string $escape_function Escape mode for the replacement value. Leave empty for no escaping.
* @return string
*/
protected function replace($string, $escape_function = '')
{
$this->escape_function = $escape_function;
// replace strings like this: {tagname attr="value"}
$string = preg_replace_callback('/\{(\w+)(\ +(?:(?!\{)[^}\n])+)*\}/', array( $this, 'replace_tag' ), $string);
// call again to take care of nested variables
$string = preg_replace_callback('/\{(\w+)(\ +(?:(?!\{)[^}\n])+)*\}/', array( $this, 'replace_tag' ), $string);
return $string;
}
/**
* @param string $string
*
* @return string
*/
protected function replace_in_html($string)
{
return $this->replace($string, 'esc_html');
}
/**
* @param string $string
*
* @return string
*/
protected function replace_in_attributes($string)
{
return $this->replace($string, 'esc_attr');
}
/**
* @param string $string
*
* @return string
*/
protected function replace_in_url($string)
{
return $this->replace($string, 'urlencode');
}
/**
* Gets data variable from cookie.
*
* @param array $args
*
* @return string
*/
protected function get_cookie($args = array())
{
if (empty($args['name'])) {
return '';
}
$name = $args['name'];
$default = isset($args['default']) ? $args['default'] : '';
if (isset($_COOKIE[ $name ])) {
return esc_html(stripslashes($_COOKIE[ $name ]));
}
return $default;
}
/*
* Get property of currently logged-in user
*
* @param array $args
*
* @return string
*/
protected function get_user_property($args = array())
{
$property = empty($args['property']) ? 'user_email' : $args['property'];
$default = isset($args['default']) ? $args['default'] : '';
$user = wp_get_current_user();
if ($user instanceof WP_User && isset($user->{$property})) {
return esc_html($user->{$property});
}
return $default;
}
/*
* Get property of viewed post
*
* @param array $args
*
* @return string
*/
protected function get_post_property($args = array())
{
global $post;
$property = empty($args['property']) ? 'ID' : $args['property'];
$default = isset($args['default']) ? $args['default'] : '';
if ($post instanceof WP_Post && isset($post->{$property})) {
return $post->{$property};
}
return $default;
}
/**
* @return string
*/
protected function get_email()
{
if (! empty($_REQUEST['EMAIL'])) {
return strip_tags($_REQUEST['EMAIL']);
}
// then , try logged-in user
if (is_user_logged_in()) {
$user = wp_get_current_user();
return $user->user_email;
}
// TODO: Read from cookie? Or add $_COOKIE support to {data} tag?
return '';
}
}
<?php
/**
* Class MC4WP_Field_Formatter
*
* Formats values based on what the Mailchimp API expects or accepts for the given field types.
*/
class MC4WP_Field_Formatter
{
/**
* @param mixed $value
* @param object $options
* @return array
*/
public function address($value, $options = null)
{
// auto-format if this is a string
if (is_string($value)) {
// addr1, addr2, city, state, zip, country
$address_pieces = explode(',', $value);
$address_pieces = array_filter($address_pieces);
$address_pieces = array_values($address_pieces);
// try to fill it.... this is a long shot
$value = array(
'addr1' => $address_pieces[0],
'city' => isset($address_pieces[1]) ? $address_pieces[1] : '',
'state' => isset($address_pieces[2]) ? $address_pieces[2] : '',
'zip' => isset($address_pieces[3]) ? $address_pieces[3] : '',
);
if (! empty($address_pieces[4])) {
$value['country'] = $address_pieces[4];
}
} elseif (is_array($value)) {
// merge with array of empty defaults to allow skipping certain fields
$default = array_fill_keys(array( 'addr1', 'city', 'state', 'zip' ), '');
$value = array_merge($default, $value);
}
return $value;
}
/**
* @param mixed $value
* @param object $options
* @return string
*/
public function birthday($value, $options = null)
{
$format = is_object($options) && isset($options->date_format) ? $options->date_format : 'MM/DD';
if (is_array($value)) {
// allow for "day" and "month" fields
if (isset($value['month']) && isset($value['day'])) {
$value = $value['month'] . '/' . $value['day'];
} else {
// if other array, just join together
$value = join('/', $value);
}
}
$value = trim($value);
if (empty($value)) {
return $value;
}
// always use slashes as delimiter, so next part works
$value = str_replace(array( '.', '-' ), '/', $value);
// if format = DD/MM OR if first part is definitely a day value (>12), then flip order
// this allows `strtotime` to understand `dd/mm` values
$values = explode('/', $value);
if ($format === 'DD/MM' || ( $values[0] > 12 && $values[0] <= 31 && isset($values[1]) && $values[1] <= 12 )) {
$values = array_reverse($values);
$value = join('/', $values);
}
// Mailchimp expects a MM/DD format, regardless of their display preference
$value = (string) gmdate('m/d', strtotime($value));
return $value;
}
/**
* @param mixed $value
* @param object $options
* @return string
*/
public function date($value, $options = null)
{
if (is_array($value)) {
// allow for "year", "month" and "day" keys
if (isset($value['year']) && isset($value['month']) && isset($value['day'])) {
$value = $value['year'] . '/' . $value['month'] . '/' . $value['day'];
} else {
// if other array, just join together
$value = join('/', $value);
}
}
$value = trim($value);
if (empty($value)) {
return $value;
}
// Mailchimp expects a Y-m-d format no matter the display preference
return (string) gmdate('Y-m-d', strtotime($value));
}
/**
* @param string $value
* @param object $options
* @return string
*/
public function language($value, $options = null)
{
$value = trim($value);
$exceptions = array(
'pt_PT',
'es_ES',
'fr_CA',
);
if (! in_array($value, $exceptions, true)) {
$value = substr($value, 0, 2);
}
return $value;
}
/**
* @param mixed $value
* @param object $options
* @return bool
*/
public function boolean($value, $options = null)
{
$falsey = array( 'false', '0' );
if (in_array($value, $falsey, true)) {
return false;
}
// otherwise, just cast.
return (bool) $value;
}
}
<?php
/**
* Class MC4WP_Field_Guesser
*
* @access private
* @ignore
*/
class MC4WP_Field_Guesser
{
/**
* @var array
*/
protected $fields;
/**
* @param array $fields
*/
public function __construct(array $fields)
{
$fields = array_change_key_case($fields, CASE_UPPER);
$this->fields = $fields;
}
/**
* Get all data which is namespaced with a given namespace
*
* @param string $namespace
*
* @return array
*/
public function namespaced($namespace = 'mc4wp-')
{
$prefix = strtoupper($namespace);
$return = array();
$length = strlen($prefix);
foreach ($this->fields as $key => $value) {
if (strpos($key, $prefix) === 0) {
$new_key = substr($key, $length);
$return[ $new_key ] = $value;
}
}
return $return;
}
/**
* Guess values for the following fields
* - EMAIL
* - NAME
* - FNAME
* - LNAME
*
* @return array
*/
public function guessed()
{
$guessed = array();
foreach ($this->fields as $field => $value) {
// transform value into array to support 1-level arrays
$sub_fields = is_array($value) ? $value : array( $value );
foreach ($sub_fields as $sub_field_value) {
// poor man's urldecode, to get Enfold theme's contact element to work.
$sub_field_value = str_replace('%40', '@', $sub_field_value);
// is this an email value? if so, assume it's the EMAIL field
if (empty($guessed['EMAIL']) && is_string($sub_field_value) && is_email($sub_field_value)) {
$guessed['EMAIL'] = $sub_field_value;
continue 2;
}
// remove special characters from field name
$simple_key = str_replace(array( '-', '_', ' ' ), '', $field);
if (empty($guessed['FNAME']) && $this->string_contains($simple_key, array( 'FIRSTNAME', 'FNAME', 'GIVENNAME', 'FORENAME' ))) {
// find first name field
$guessed['FNAME'] = $sub_field_value;
} elseif (empty($guessed['LNAME']) && $this->string_contains($simple_key, array( 'LASTNAME', 'LNAME', 'SURNAME', 'FAMILYNAME' ))) {
// find last name field
$guessed['LNAME'] = $sub_field_value;
} elseif (empty($guessed['NAME']) && $this->string_contains($simple_key, 'NAME')) {
// find name field
$guessed['NAME'] = $sub_field_value;
}
}
}
return $guessed;
}
/**
* @param $methods
*
* @return array
*/
public function combine(array $methods)
{
$combined = array();
foreach ($methods as $method) {
if (method_exists($this, $method)) {
$combined = array_merge($combined, call_user_func(array( $this, $method )));
}
}
return $combined;
}
/**
* @param string $haystack
* @param string|array $needles
*
* @return bool
*/
private function string_contains($haystack, $needles)
{
if (! is_array($needles)) {
$needles = array( $needles );
}
foreach ($needles as $needle) {
if (strpos($haystack, $needle) !== false) {
return true;
}
}
return false;
}
}
<?php
/**
* Class MC4WP_Field_Map
*
* @access private
* @since 4.0
* @ignore
*/
class MC4WP_List_Data_Mapper
{
/**
* @var array
*/
private $data = array();
/**
* @var array
*/
private $list_ids = array();
/**
* @var MC4WP_Field_Formatter
*/
private $formatter;
/**
* @var MC4WP_MailChimp
*/
private $mailchimp;
/**
* @param array $data
* @param array $list_ids
*/
public function __construct(array $data, array $list_ids)
{
$this->data = array_change_key_case($data, CASE_UPPER);
if (! isset($this->data['EMAIL'])) {
throw new InvalidArgumentException('Data needs at least an EMAIL key.');
}
$this->list_ids = $list_ids;
$this->formatter = new MC4WP_Field_Formatter();
$this->mailchimp = new MC4WP_MailChimp();
}
/**
* @return MC4WP_MailChimp_Subscriber[]
*/
public function map()
{
$map = array();
foreach ($this->list_ids as $list_id) {
$map[ "$list_id" ] = $this->map_list($list_id);
}
return $map;
}
/**
* @param string $list_id
* @return MC4WP_MailChimp_Subscriber
* @throws Exception
*/
protected function map_list($list_id)
{
$subscriber = new MC4WP_MailChimp_Subscriber();
$subscriber->email_address = $this->data['EMAIL'];
// find merge fields
$merge_fields = $this->mailchimp->get_list_merge_fields($list_id);
foreach ($merge_fields as $merge_field) {
// skip EMAIL field as that is handled separately (see above)
if ($merge_field->tag === 'EMAIL') {
continue;
}
// use empty() here to skip empty field values
if (empty($this->data[ $merge_field->tag ])) {
continue;
}
// format field value
$value = $this->data[ $merge_field->tag ];
$value = $this->format_merge_field_value($merge_field, $value);
// add to map
$subscriber->merge_fields[ $merge_field->tag ] = $value;
}
// find interest categories
if (! empty($this->data['INTERESTS'])) {
$interest_categories = $this->mailchimp->get_list_interest_categories($list_id);
foreach ($interest_categories as $interest_category) {
foreach ($interest_category->interests as $interest_id => $interest_name) {
// straight lookup by ID as key with value copy.
if (isset($this->data['INTERESTS'][ $interest_id ])) {
$subscriber->interests[ $interest_id ] = $this->formatter->boolean($this->data['INTERESTS'][ $interest_id ]);
}
// straight lookup by ID as top-level value
if (in_array($interest_id, $this->data['INTERESTS'], false)) {
$subscriber->interests[ $interest_id ] = true;
}
// look in array with category ID as key.
if (isset($this->data['INTERESTS'][ $interest_category->id ])) {
$value = $this->data['INTERESTS'][ $interest_category->id ];
$values = is_array($value) ? $value : array_map('trim', explode('|', $value));
// find by category ID + interest ID
if (in_array($interest_id, $values, false)) {
$subscriber->interests[ $interest_id ] = true;
}
// find by category ID + interest name
if (in_array($interest_name, $values, true)) {
$subscriber->interests[ $interest_id ] = true;
}
}
}
}
}
// add GDPR marketing permissions
if (! empty($this->data['MARKETING_PERMISSIONS'])) {
$values = $this->data['MARKETING_PERMISSIONS'];
$values = is_array($values) ? $values : explode(',', $values);
$values = array_map('trim', $values);
$marketing_permissions = $this->mailchimp->get_list_marketing_permissions($list_id);
foreach ($marketing_permissions as $mp) {
if (in_array($mp->marketing_permission_id, $values, true) || in_array($mp->text, $values, true)) {
$subscriber->marketing_permissions[] = (object) array(
'marketing_permission_id' => $mp->marketing_permission_id,
'enabled' => true,
);
}
}
}
// find language
/* @see http://kb.mailchimp.com/lists/managing-subscribers/view-and-edit-subscriber-languages?utm_source=mc-api&utm_medium=docs&utm_campaign=apidocs&_ga=1.211519638.2083589671.1469697070 */
if (! empty($this->data['MC_LANGUAGE'])) {
$subscriber->language = $this->formatter->language($this->data['MC_LANGUAGE']);
}
return $subscriber;
}
/**
* @param object $merge_field
* @param string $value
*
* @return mixed
*/
private function format_merge_field_value($merge_field, $value)
{
$field_type = strtolower($merge_field->type);
if (method_exists($this->formatter, $field_type)) {
$value = call_user_func(array( $this->formatter, $field_type ), $value, $merge_field->options);
}
/**
* Filters the value of a field after it is formatted.
*
* Use this to format a field value according to the field type (in Mailchimp).
*
* @since 3.0
* @param string $value The value
* @param string $field_type The type of the field (in Mailchimp)
*/
$value = apply_filters('mc4wp_format_field_value', $value, $field_type);
return $value;
}
}
<?php
class MC4WP_MailChimp_Subscriber
{
/**
* @var string Email address for this subscriber.
*/
public $email_address = '';
/**
* @var array The key of this object’s properties is the ID of the interest in question.
*/
public $interests = array();
/**
* @var array An individual merge var and value for a member.
*/
public $merge_fields = array();
/**
* @var string Subscriber’s status.
*/
public $status = 'pending';
/**
* @var string Type of email this member asked to get (‘html’ or ‘text’).
*/
public $email_type = 'html';
/**
* @var string IP address the subscriber signed up from.
*/
public $ip_signup;
/**
* @var string The subscriber's language
*/
public $language;
/**
* @var boolean VIP status for subscriber.
*/
public $vip;
/**
* @var array The tags applied to this member.
*/
public $tags = array();
/**
* @var array The marketing permissions for the subscriber.
*/
public $marketing_permissions = array();
/**
* Retrieves member data as an array, without null values.
*
* @return array
*/
public function to_array()
{
$all = get_object_vars($this);
$array = array();
foreach ($all as $key => $value) {
// skip null values
if ($value === null) {
continue;
}
// skip empty marketing_permissions property
if ($key === 'marketing_permissions' && empty($value)) {
continue;
}
// otherwise, add to final array
$array[ $key ] = $value;
}
return $array;
}
}
<?php
/**
* Class MC4WP_Plugin
*
* Helper class for easy access to information like the plugin file or plugin directory.
* Used in MC4WP Premium.
*
* @access public
* @ignore
*/
class MC4WP_Plugin
{
/**
* @var string The plugin version.
*/
protected $version;
/**
* @var string The main plugin file.
*/
protected $file;
/**
* @param string $file The plugin version.
* @param string $version The main plugin file.
*/
public function __construct($file, $version)
{
$this->file = $file;
$this->version = $version;
}
/**
* Get the main plugin file.
*
* @return string
*/
public function file()
{
return $this->file;
}
/**
* Get the plugin version.
*
* @return string
*/
public function version()
{
return $this->version;
}
/**
* Gets the directory the plugin lives in.
*
* @param string $path
*
* @return string
*/
public function dir($path = '')
{
// ensure path has leading slash
if ('' !== $path) {
$path = '/' . ltrim($path, '/');
}
return dirname($this->file) . $path;
}
/**
* Gets the URL to the plugin files.
*
* @param string $path
*
* @return string
*/
public function url($path = '')
{
return plugins_url($path, $this->file);
}
}
<?php
/**
* Class MC4WP_Queue_Job
*
* @ignore
*/
class MC4WP_Queue_Job
{
/**
* @var string
*/
public $id;
/**
* @var mixed
*/
public $data;
/**
* @var int
*/
public $max_attempts = 1;
/**
* @var int
*/
public $attempts = 0;
/**
* MC4WP_Queue_Job constructor.
*
* @param mixed $data
*/
public function __construct($data)
{
$this->id = (string) microtime(true) . rand(1, 10000);
$this->data = $data;
}
}
<?php
/**
* Class MC4WP_Queue
*
* @ignore
*/
class MC4WP_Queue
{
/**
* @var MC4WP_Queue_Job[]
*/
protected $jobs;
/**
* @var string
*/
protected $option_name;
/**
* @var bool
*/
protected $dirty = false;
/**
* @var int
*/
const MAX_JOB_COUNT = 1000;
/**
* MC4WP_Ecommerce_Queue constructor.
*
* @param string $option_name
*/
public function __construct($option_name)
{
$this->option_name = $option_name;
register_shutdown_function(array( $this, 'save' ));
}
/**
* Load jobs from option
*/
protected function load()
{
if (! is_null($this->jobs)) {
return;
}
$jobs = get_option($this->option_name, array());
if (! is_array($jobs)) {
$jobs = array();
} else {
$valid_jobs = array();
foreach ($jobs as $i => $obj) {
// filter invalid data from array
if (! is_object($obj) || empty($obj->data)) {
continue;
}
// make sure each job is instance of MC4WP_Queue_Job
if ($obj instanceof MC4WP_Queue_Job) {
$job = $obj;
} else {
$job = new MC4WP_Queue_Job($obj->data);
$job->id = $obj->id;
}
$valid_jobs[] = $job;
}
$jobs = $valid_jobs;
}
$this->jobs = $jobs;
}
/**
* Get all jobs in the queue
*
* @return MC4WP_Queue_Job[] Array of jobs
*/
public function all()
{
$this->load();
return $this->jobs;
}
/**
* Add job to queue
*
* @param mixed $data
* @return boolean
*/
public function put($data)
{
$this->load();
// check if we already have a job with same data
foreach ($this->jobs as $job) {
if ($job->data === $data) {
return false;
}
}
// if we have more than MAX_JOB_COUNT jobs, remove first job item.
// this protects against an ever-growing job list, but also potentially loses jobs if the queue is not processed soon enough.
if (count($this->jobs) > self::MAX_JOB_COUNT) {
array_shift($this->jobs);
}
// add job to end of jobs array
$job = new MC4WP_Queue_Job($data);
$this->jobs[] = $job;
$this->dirty = true;
return true;
}
/**
* Get all jobs in the queue
*
* @return MC4WP_Queue_Job|false
*/
public function get()
{
$this->load();
// do we have jobs?
if (count($this->jobs) === 0) {
return false;
}
// return first element
return reset($this->jobs);
}
/**
* @param MC4WP_Queue_Job $job
*/
public function delete(MC4WP_Queue_Job $job)
{
$this->load();
$index = array_search($job, $this->jobs, true);
// check for "false" here, as 0 is a valid index.
if ($index !== false) {
unset($this->jobs[ $index ]);
$this->jobs = array_values($this->jobs);
$this->dirty = true;
}
}
/**
* @param MC4WP_Queue_Job $job
*/
public function reschedule(MC4WP_Queue_Job $job)
{
$this->load();
// delete job from start of queue
$this->delete($job);
// add job to end of queue
$this->jobs[] = $job;
$this->dirty = true;
}
/**
* Reset queue
*/
public function reset()
{
$this->jobs = array();
$this->dirty = true;
}
/**
* Save the queue
*/
public function save()
{
if (! $this->dirty || is_null($this->jobs)) {
return false;
}
$success = update_option($this->option_name, $this->jobs, false);
if ($success) {
$this->dirty = false;
}
return $success;
}
}
<?php
/**
* Class MC4WP_Tools
*
* @access private
* @ignore
*/
class MC4WP_Tools
{
/**
* @return array
*/
public static function get_countries()
{
return array(
'AF' => 'Afghanistan',
'AX' => 'Aland Islands',
'AL' => 'Albania',
'DZ' => 'Algeria',
'AS' => 'American Samoa',
'AD' => 'Andorra',
'AO' => 'Angola',
'AI' => 'Anguilla',
'AQ' => 'Antarctica',
'AG' => 'Antigua and Barbuda',
'AR' => 'Argentina',
'AM' => 'Armenia',
'AW' => 'Aruba',
'AU' => 'Australia',
'AT' => 'Austria',
'AZ' => 'Azerbaijan',
'BS' => 'Bahamas',
'BH' => 'Bahrain',
'BD' => 'Bangladesh',
'BB' => 'Barbados',
'BY' => 'Belarus',
'BE' => 'Belgium',
'BZ' => 'Belize',
'BJ' => 'Benin',
'BM' => 'Bermuda',
'BT' => 'Bhutan',
'BO' => 'Bolivia',
'BQ' => 'Bonaire, Saint Eustatius and Saba',
'BA' => 'Bosnia and Herzegovina',
'BW' => 'Botswana',
'BV' => 'Bouvet Island',
'BR' => 'Brazil',
'IO' => 'British Indian Ocean Territory',
'VG' => 'British Virgin Islands',
'BN' => 'Brunei',
'BG' => 'Bulgaria',
'BF' => 'Burkina Faso',
'BI' => 'Burundi',
'KH' => 'Cambodia',
'CM' => 'Cameroon',
'CA' => 'Canada',
'CV' => 'Cape Verde',
'KY' => 'Cayman Islands',
'CF' => 'Central African Republic',
'TD' => 'Chad',
'CL' => 'Chile',
'CN' => 'China',
'CX' => 'Christmas Island',
'CC' => 'Cocos Islands',
'CO' => 'Colombia',
'KM' => 'Comoros',
'CK' => 'Cook Islands',
'CR' => 'Costa Rica',
'HR' => 'Croatia',
'CU' => 'Cuba',
'CW' => 'Curacao',
'CY' => 'Cyprus',
'CZ' => 'Czech Republic',
'CD' => 'Democratic Republic of the Congo',
'DK' => 'Denmark',
'DJ' => 'Djibouti',
'DM' => 'Dominica',
'DO' => 'Dominican Republic',
'TL' => 'East Timor',
'EC' => 'Ecuador',
'EG' => 'Egypt',
'SV' => 'El Salvador',
'GQ' => 'Equatorial Guinea',
'ER' => 'Eritrea',
'EE' => 'Estonia',
'ET' => 'Ethiopia',
'FK' => 'Falkland Islands',
'FO' => 'Faroe Islands',
'FJ' => 'Fiji',
'FI' => 'Finland',
'FR' => 'France',
'GF' => 'French Guiana',
'PF' => 'French Polynesia',
'TF' => 'French Southern Territories',
'GA' => 'Gabon',
'GM' => 'Gambia',
'GE' => 'Georgia',
'DE' => 'Germany',
'GH' => 'Ghana',
'GI' => 'Gibraltar',
'GR' => 'Greece',
'GL' => 'Greenland',
'GD' => 'Grenada',
'GP' => 'Guadeloupe',
'GU' => 'Guam',
'GT' => 'Guatemala',
'GG' => 'Guernsey',
'GN' => 'Guinea',
'GW' => 'Guinea-Bissau',
'GY' => 'Guyana',
'HT' => 'Haiti',
'HM' => 'Heard Island and McDonald Islands',
'HN' => 'Honduras',
'HK' => 'Hong Kong',
'HU' => 'Hungary',
'IS' => 'Iceland',
'IN' => 'India',
'ID' => 'Indonesia',
'IR' => 'Iran',
'IQ' => 'Iraq',
'IE' => 'Ireland',
'IM' => 'Isle of Man',
'IL' => 'Israel',
'IT' => 'Italy',
'CI' => 'Ivory Coast',
'JM' => 'Jamaica',
'JP' => 'Japan',
'JE' => 'Jersey',
'JO' => 'Jordan',
'KZ' => 'Kazakhstan',
'KE' => 'Kenya',
'KI' => 'Kiribati',
'XK' => 'Kosovo',
'KW' => 'Kuwait',
'KG' => 'Kyrgyzstan',
'LA' => 'Laos',
'LV' => 'Latvia',
'LB' => 'Lebanon',
'LS' => 'Lesotho',
'LR' => 'Liberia',
'LY' => 'Libya',
'LI' => 'Liechtenstein',
'LT' => 'Lithuania',
'LU' => 'Luxembourg',
'MO' => 'Macao',
'MK' => 'Macedonia',
'MG' => 'Madagascar',
'MW' => 'Malawi',
'MY' => 'Malaysia',
'MV' => 'Maldives',
'ML' => 'Mali',
'MT' => 'Malta',
'MH' => 'Marshall Islands',
'MQ' => 'Martinique',
'MR' => 'Mauritania',
'MU' => 'Mauritius',
'YT' => 'Mayotte',
'MX' => 'Mexico',
'FM' => 'Micronesia',
'MD' => 'Moldova',
'MC' => 'Monaco',
'MN' => 'Mongolia',
'ME' => 'Montenegro',
'MS' => 'Montserrat',
'MA' => 'Morocco',
'MZ' => 'Mozambique',
'MM' => 'Myanmar',
'NA' => 'Namibia',
'NR' => 'Nauru',
'NP' => 'Nepal',
'NL' => 'Netherlands',
'NC' => 'New Caledonia',
'NZ' => 'New Zealand',
'NI' => 'Nicaragua',
'NE' => 'Niger',
'NG' => 'Nigeria',
'NU' => 'Niue',
'NF' => 'Norfolk Island',
'KP' => 'North Korea',
'MP' => 'Northern Mariana Islands',
'NO' => 'Norway',
'OM' => 'Oman',
'PK' => 'Pakistan',
'PW' => 'Palau',
'PS' => 'Palestinian Territory',
'PA' => 'Panama',
'PG' => 'Papua New Guinea',
'PY' => 'Paraguay',
'PE' => 'Peru',
'PH' => 'Philippines',
'PN' => 'Pitcairn',
'PL' => 'Poland',
'PT' => 'Portugal',
'PR' => 'Puerto Rico',
'QA' => 'Qatar',
'CG' => 'Republic of the Congo',
'RE' => 'Reunion',
'RO' => 'Romania',
'RU' => 'Russia',
'RW' => 'Rwanda',
'BL' => 'Saint Barthelemy',
'SH' => 'Saint Helena',
'KN' => 'Saint Kitts and Nevis',
'LC' => 'Saint Lucia',
'MF' => 'Saint Martin',
'PM' => 'Saint Pierre and Miquelon',
'VC' => 'Saint Vincent and the Grenadines',
'WS' => 'Samoa',
'SM' => 'San Marino',
'ST' => 'Sao Tome and Principe',
'SA' => 'Saudi Arabia',
'SN' => 'Senegal',
'RS' => 'Serbia',
'SC' => 'Seychelles',
'SL' => 'Sierra Leone',
'SG' => 'Singapore',
'SX' => 'Sint Maarten',
'SK' => 'Slovakia',
'SI' => 'Slovenia',
'SB' => 'Solomon Islands',
'SO' => 'Somalia',
'ZA' => 'South Africa',
'GS' => 'South Georgia and the South Sandwich Islands',
'KR' => 'South Korea',
'SS' => 'South Sudan',
'ES' => 'Spain',
'LK' => 'Sri Lanka',
'SD' => 'Sudan',
'SR' => 'Suriname',
'SJ' => 'Svalbard and Jan Mayen',
'SZ' => 'Swaziland',
'SE' => 'Sweden',
'CH' => 'Switzerland',
'SY' => 'Syria',
'TW' => 'Taiwan',
'TJ' => 'Tajikistan',
'TZ' => 'Tanzania',
'TH' => 'Thailand',
'TG' => 'Togo',
'TK' => 'Tokelau',
'TO' => 'Tonga',
'TT' => 'Trinidad and Tobago',
'TN' => 'Tunisia',
'TR' => 'Turkey',
'TM' => 'Turkmenistan',
'TC' => 'Turks and Caicos Islands',
'TV' => 'Tuvalu',
'VI' => 'U.S. Virgin Islands',
'UG' => 'Uganda',
'UA' => 'Ukraine',
'AE' => 'United Arab Emirates',
'GB' => 'United Kingdom',
'US' => 'United States',
'UM' => 'United States Minor Outlying Islands',
'UY' => 'Uruguay',
'UZ' => 'Uzbekistan',
'VU' => 'Vanuatu',
'VA' => 'Vatican',
'VE' => 'Venezuela',
'VN' => 'Vietnam',
'WF' => 'Wallis and Futuna',
'EH' => 'Western Sahara',
'YE' => 'Yemen',
'ZM' => 'Zambia',
'ZW' => 'Zimbabwe',
);
}
}
<?php
defined('ABSPATH') or exit;
add_action('mc4wp_refresh_mailchimp_lists', 'mc4wp_refresh_mailchimp_lists');
<?php
defined('ABSPATH') or exit;
add_filter('mc4wp_form_data', 'mc4wp_add_name_data', 60);
add_filter('mc4wp_integration_data', 'mc4wp_add_name_data', 60);
add_filter('mctb_data', '_mc4wp_update_groupings_data', PHP_INT_MAX);
add_filter('mc4wp_form_data', '_mc4wp_update_groupings_data', PHP_INT_MAX);
add_filter('mc4wp_integration_data', '_mc4wp_update_groupings_data', PHP_INT_MAX);
add_filter('mailchimp_sync_user_data', '_mc4wp_update_groupings_data', PHP_INT_MAX);
add_filter('mc4wp_use_sslverify', '_mc4wp_use_sslverify', 1);
mc4wp_apply_deprecated_filters('mc4wp_merge_vars', 'mc4wp_form_data');
mc4wp_apply_deprecated_filters('mc4wp_form_merge_vars', 'mc4wp_form_data');
mc4wp_apply_deprecated_filters('mc4wp_integration_merge_vars', 'mc4wp_integration_data');
<?php
/**
* Gets the absolute url to edit a form
*
* @param int $form_id ID of the form
* @param string $tab Tab identifier to open
*
* @return string
*/
function mc4wp_get_edit_form_url($form_id, $tab = '')
{
$url = admin_url(sprintf('admin.php?page=mailchimp-for-wp-forms&view=edit-form&form_id=%d', $form_id));
if (! empty($tab)) {
$url .= sprintf('&tab=%s', $tab);
}
return $url;
}
/**
* Get absolute URL to create a new form
*
* @return string
*/
function mc4wp_get_add_form_url()
{
$url = admin_url('admin.php?page=mailchimp-for-wp-forms&view=add-form');
return $url;
}
<?php
/**
* This class takes care of all form assets related functionality
*
* @access private
* @ignore
*/
class MC4WP_Form_Asset_Manager
{
/**
* @var bool Flag to determine whether scripts should be enqueued.
*/
private $load_scripts = false;
/**
* Add hooks
*/
public function add_hooks()
{
add_action('init', array( $this, 'register_scripts' ));
add_action('wp_enqueue_scripts', array( $this, 'load_stylesheets' ));
add_action('wp_footer', array( $this, 'load_scripts' ));
add_action('mc4wp_output_form', array( $this, 'before_output_form' ));
add_action('script_loader_tag', array( $this, 'add_defer_attribute' ), 10, 2);
}
/**
* Register scripts to be enqueued later.
*/
public function register_scripts()
{
wp_register_script('mc4wp-forms-api', mc4wp_plugin_url('assets/js/forms.js'), array(), MC4WP_VERSION, true);
}
/**
* @param string $stylesheet
*
* @return bool
*/
public function is_registered_stylesheet($stylesheet)
{
$stylesheets = $this->get_registered_stylesheets();
return in_array($stylesheet, $stylesheets, true);
}
/**
* @return array
*/
public function get_registered_stylesheets()
{
return array(
'basic',
'themes',
);
}
/**
* @param string $stylesheet
*
* @return string
*/
public function get_stylesheet_url($stylesheet)
{
return mc4wp_plugin_url('assets/css/form-' . $stylesheet . '.css');
}
/**
* Get array of stylesheet handles which should be enqueued.
*
* @return array
*/
public function get_active_stylesheets()
{
$stylesheets = (array) get_option('mc4wp_form_stylesheets', array());
/**
* Filters the stylesheets to be loaded
*
* Should be an array of stylesheet handles previously registered using `wp_register_style`.
* Each value is prefixed with `mc4wp-form-` to get the handle.
*
* Return an empty array if you want to disable the loading of all stylesheets.
*
* @since 3.0
* @param array $stylesheets Array of valid stylesheet handles
*/
$stylesheets = (array) apply_filters('mc4wp_form_stylesheets', $stylesheets);
return $stylesheets;
}
/**
* Load the various stylesheets
*/
public function load_stylesheets()
{
$stylesheets = $this->get_active_stylesheets();
foreach ($stylesheets as $stylesheet) {
if (! $this->is_registered_stylesheet($stylesheet)) {
continue;
}
$handle = 'mc4wp-form-' . $stylesheet;
$url = $this->get_stylesheet_url($stylesheet);
wp_enqueue_style($handle, $url, array(), MC4WP_VERSION);
add_editor_style($url);
}
/**
* @ignore
*/
do_action('mc4wp_load_form_stylesheets', $stylesheets);
}
/**
* Get data object for client-side use for after a form is submitted over HTTP POST (not AJAX).
*
* @return array
*/
public function get_submitted_form_data()
{
$submitted_form = mc4wp_get_submitted_form();
if (! $submitted_form instanceof MC4WP_Form) {
return null;
}
$data = array(
'id' => $submitted_form->ID,
'event' => $submitted_form->last_event,
'data' => $submitted_form->get_data(),
'element_id' => $submitted_form->config['element_id'],
'auto_scroll' => true,
);
if ($submitted_form->has_errors()) {
$data['errors'] = $submitted_form->errors;
}
/**
* Filters the `auto_scroll` setting for when a form is submitted.
* Set to false to disable scrolling to form.
*
* @param boolean $auto_scroll
* @since 3.0
*/
$data['auto_scroll'] = apply_filters('mc4wp_form_auto_scroll', $data['auto_scroll']);
return $data;
}
/**
* Load JavaScript files
*/
public function before_output_form()
{
$load_scripts = apply_filters('mc4wp_load_form_scripts', true);
if (! $load_scripts) {
return;
}
$this->print_dummy_javascript();
$this->load_scripts = true;
}
/**
* Prints dummy JavaScript which allows people to call `mc4wp.forms.on()` before the JS is loaded.
*/
public function print_dummy_javascript()
{
echo '<script>';
include __DIR__ . '/views/js/dummy-api.js';
echo '</script>';
}
/**
* Outputs the inline JavaScript that is used to enhance forms
*/
public function load_scripts()
{
$load_scripts = apply_filters('mc4wp_load_form_scripts', $this->load_scripts);
if (! $load_scripts) {
return;
}
// load general client-side form API
wp_enqueue_script('mc4wp-forms-api');
// maybe load JS file for when a form was submitted over HTTP POST
$submitted_form_data = $this->get_submitted_form_data();
if ($submitted_form_data !== null) {
wp_enqueue_script('mc4wp-forms-submitted', mc4wp_plugin_url('assets/js/forms-submitted.js'), array( 'mc4wp-forms-api' ), MC4WP_VERSION, true);
wp_localize_script('mc4wp-forms-submitted', 'mc4wp_submitted_form', $submitted_form_data);
}
// print inline scripts
echo '<script>';
echo '(function() {';
include __DIR__ . '/views/js/url-fields.js';
echo '})();';
echo '</script>';
/** @ignore */
do_action('mc4wp_load_form_scripts');
}
/**
* Adds `defer` attribute to all form-related `<script>` elements so they do not block page rendering.
*
* @param string $tag
* @param string $handle
* @return string
*/
public function add_defer_attribute($tag, $handle)
{
if (! in_array($handle, array( 'mc4wp-forms-api', 'mc4wp-forms-submitted' ), true) || stripos($tag, ' defer') !== false) {
return $tag;
}
return str_replace(' src=', ' defer src=', $tag);
}
}
<?php
/**
* Class MC4WP_Form_AMP
*/
class MC4WP_Form_AMP
{
/**
* Hook!
*/
public function add_hooks()
{
add_filter('mc4wp_form_content', array( $this, 'add_response_templates' ), 10, 2);
add_filter('mc4wp_form_element_attributes', array( $this, 'add_amp_request' ));
add_filter('mc4wp_load_form_scripts', array( $this, 'suppress_scripts' ));
}
/**
* Add AMP templates for submit/success/error.
*
* @param string $content The form content.
* @param MC4WP_Form $form The form object.
* @return string Modified $content.
*/
public function add_response_templates($content, $form)
{
if (! function_exists('amp_is_request') || ! amp_is_request()) {
return $content;
}
ob_start();
?>
<div submitting>
<template type="amp-mustache">
<?php echo esc_html__('Submitting...', 'mailchimp-for-wp'); ?>
</template>
</div>
<div submit-success>
<template type="amp-mustache">
<?php
echo wp_kses(
$form->get_message('subscribed'),
array(
'a' => array(),
'strong' => array(),
'em' => array(),
)
);
?>
</template>
</div>
<div submit-error>
<template type="amp-mustache">
{{message}}
</template>
</div>
<?php
$content .= ob_get_clean();
return $content;
}
/**
* Add 'action-xhr' to AMP forms.
*
* @param array $attributes Key-Value pairs of attributes output on form.
* @return array Modified $attributes.
*/
public function add_amp_request($attributes)
{
if (function_exists('amp_is_request') && amp_is_request()) {
$attributes['action-xhr'] = get_rest_url(null, 'mc4wp/v1/form');
}
return $attributes;
}
/**
* Suppress form scripts on AMP pages.
*
* @param bool $load_scripts Whether scripts should be loaded.
* @return bool Modified $load_scripts.
*/
public function suppress_scripts($load_scripts)
{
if (function_exists('amp_is_request') && amp_is_request()) {
return false;
}
return $load_scripts;
}
}
<?php
/**
* This class takes care of all form related functionality
*
* Do not interact with this class directly, use `mc4wp_form` functions tagged with @access public instead.
*
* @class MC4WP_Form_Manager
* @ignore
* @access private
*/
class MC4WP_Form_Manager
{
/**
* @var MC4WP_Form_Output_Manager
*/
protected $output_manager;
/**
* @var MC4WP_Form_Listener
*/
protected $listener;
/**
* @var MC4WP_Form_Tags
*/
protected $tags;
/**
* @var MC4WP_Form_Previewer
*/
protected $previewer;
/**
* @var MC4WP_Form_Asset_Manager
*/
protected $assets;
/**
* @var MC4WP_Form_AMP
*/
protected $amp_compatibility;
/**
* Constructor
*/
public function __construct()
{
$this->output_manager = new MC4WP_Form_Output_Manager();
$this->tags = new MC4WP_Form_Tags();
$this->listener = new MC4WP_Form_Listener();
$this->previewer = new MC4WP_Form_Previewer();
$this->assets = new MC4WP_Form_Asset_Manager();
$this->amp_compatibility = new MC4WP_Form_AMP();
}
/**
* Hook!
*/
public function add_hooks()
{
add_action('init', array( $this, 'initialize' ));
add_action('widgets_init', array( $this, 'register_widget' ));
add_action('rest_api_init', array( $this, 'register_endpoint' ));
$this->listener->add_hooks();
$this->output_manager->add_hooks();
$this->assets->add_hooks();
$this->tags->add_hooks();
$this->previewer->add_hooks();
$this->amp_compatibility->add_hooks();
}
/**
* Initialize
*/
public function initialize()
{
$this->register_post_type();
$this->register_block_type();
}
private function register_block_type()
{
// Bail if register_block_type does not exist (available since WP 5.0)
if (! function_exists('register_block_type')) {
return;
}
register_block_type(
'mailchimp-for-wp/form',
array(
'render_callback' => array( $this->output_manager, 'shortcode' ),
)
);
}
/**
* Register post type "mc4wp-form"
*/
private function register_post_type()
{
// register post type
register_post_type(
'mc4wp-form',
array(
'labels' => array(
'name' => 'Mailchimp Sign-up Forms',
'singular_name' => 'Sign-up Form',
),
'public' => false,
)
);
}
/**
* Register our Form widget
*/
public function register_widget()
{
register_widget('MC4WP_Form_Widget');
}
/**
* Register an API endpoint for handling a form.
*/
public function register_endpoint()
{
register_rest_route(
'mc4wp/v1',
'/form',
array(
'methods' => 'POST',
'permission_callback' => '__return_true',
'callback' => array( $this, 'handle_endpoint' ),
)
);
}
/**
* Process requests to the form endpoint.
*
* A listener checks every request for a form submit, so we just need to fetch the listener and get its status.
*/
public function handle_endpoint()
{
$form = mc4wp_get_submitted_form();
if (! $form instanceof MC4WP_Form) {
return new WP_Error(
'not_found',
esc_html__('Resource does not exist.', 'mailchimp-for-wp'),
array(
'status' => 404,
)
);
}
if ($form->has_errors()) {
$message_key = $form->errors[0];
$message = $form->get_message($message_key);
return new WP_Error(
$message_key,
$message,
array(
'status' => 400,
)
);
}
return new WP_REST_Response(true, 200);
}
/**
* @param $form_id
* @param array $config
* @param bool $echo
*
* @return string
*/
public function output_form($form_id, $config = array(), $echo = true)
{
return $this->output_manager->output_form($form_id, $config, $echo);
}
/**
* Gets the currently submitted form
*
* @return MC4WP_Form|null
*/
public function get_submitted_form()
{
if ($this->listener->submitted_form instanceof MC4WP_Form) {
return $this->listener->submitted_form;
}
return null;
}
/**
* Return all tags
*
* @return array
*/
public function get_tags()
{
return $this->tags->all();
}
}
<?php
/**
* Class MC4WP_Form_Notice
*
* @ignore
* @access private
*/
class MC4WP_Form_Notice
{
/**
* @var string
*/
public $type = 'error';
/**
* @var string
*/
public $text;
/**
* @param string $text
* @param string $type
*/
public function __construct($text, $type = 'error')
{
$this->text = $text;
if (! empty($type)) {
$this->type = $type;
}
}
/**
* @return string
*/
public function __toString()
{
return $this->text;
}
}
<?php
class MC4WP_Form_Previewer
{
public function add_hooks()
{
add_action('parse_request', array( $this, 'listen' ));
}
public function listen()
{
if (empty($_GET['mc4wp_preview_form'])) {
return;
}
if (! current_user_can('edit_posts')) {
return;
}
show_admin_bar(false);
add_filter('pre_handle_404', '__return_true');
remove_all_actions('template_redirect');
add_action('template_redirect', array( $this, 'load_preview' ));
}
public function load_preview()
{
// clear output, some plugin or hooked code might have thrown errors by now.
if (ob_get_level() > 0) {
ob_end_clean();
}
$form_id = (int) $_GET['mc4wp_preview_form'];
status_header(200);
require __DIR__ . '/views/preview.php';
exit;
}
}
<?php
/**
* Class MC4WP_Form_Tags
*
* @access private
* @ignore
*/
class MC4WP_Form_Tags extends MC4WP_Dynamic_Content_Tags
{
/**
* @var MC4WP_Form
*/
protected $form;
/**
* @var MC4WP_Form_Element
*/
protected $form_element;
public function add_hooks()
{
add_filter('mc4wp_form_response_html', array( $this, 'replace_in_form_response' ), 10, 2);
add_filter('mc4wp_form_content', array( $this, 'replace_in_form_content' ), 10, 3);
add_filter('mc4wp_form_redirect_url', array( $this, 'replace_in_form_redirect_url' ), 10, 2);
}
/**
* Register template tags
*/
public function register()
{
parent::register();
$this->tags['response'] = array(
'description' => __('Replaced with the form response (error or success messages).', 'mailchimp-for-wp'),
'callback' => array( $this, 'get_form_response' ),
);
$this->tags['data'] = array(
'description' => sprintf(__('Data from the URL or a submitted form.', 'mailchimp-for-wp')),
'callback' => array( $this, 'get_data' ),
'example' => "data key='UTM_SOURCE' default='Default Source'",
);
$this->tags['subscriber_count'] = array(
'description' => __('Replaced with the number of subscribers on the selected list(s)', 'mailchimp-for-wp'),
'callback' => array( $this, 'get_subscriber_count' ),
);
}
public function replace_in_form_content($string, MC4WP_Form $form, MC4WP_Form_Element $element = null)
{
$this->form = $form;
$this->form_element = $element;
$string = $this->replace($string);
return $string;
}
public function replace_in_form_response($string, MC4WP_Form $form)
{
$this->form = $form;
$string = $this->replace($string);
return $string;
}
public function replace_in_form_redirect_url($string, MC4WP_Form $form)
{
$this->form = $form;
$string = $this->replace_in_url($string);
return $string;
}
/**
* Returns the number of subscribers on the selected lists (for the form context)
*
* @return int
*/
public function get_subscriber_count()
{
$mailchimp = new MC4WP_MailChimp();
$count = $mailchimp->get_subscriber_count($this->form->get_lists());
return number_format($count);
}
/**
* Returns the form response
*
* @return string
*/
public function get_form_response()
{
if ($this->form_element instanceof MC4WP_Form_Element) {
return $this->form_element->get_response_html();
}
return '';
}
/**
* Gets data value from GET or POST variables.
*
* @param array $args
* @return string
*/
public function get_data(array $args = array())
{
if (empty($args['key'])) {
return '';
}
$default = isset($args['default']) ? $args['default'] : '';
$key = $args['key'];
$data = array_merge($_GET, $_POST);
$value = isset($data[ $key ]) ? $data[ $key ] : $default;
// turn array into readable value
if (is_array($value)) {
$value = array_filter($value);
$value = join(', ', $value);
}
return esc_html($value);
}
}
<?php
/**
* Class MC4WP_Form_Output_Manager
*
* @ignore
* @access private
*/
class MC4WP_Form_Output_Manager
{
/**
* @var int The # of forms outputted
*/
public $count = 0;
/**
* @const string
*/
const SHORTCODE = 'mc4wp_form';
/**
* Add hooks
*/
public function add_hooks()
{
// enable shortcodes in form content
add_filter('mc4wp_form_content', 'do_shortcode');
add_action('init', array( $this, 'register_shortcode' ));
}
/**
* Registers the [mc4wp_form] shortcode
*/
public function register_shortcode()
{
add_shortcode(self::SHORTCODE, array( $this, 'shortcode' ));
}
/**
* @param array $attributes
* @param string $content
* @return string
*/
public function shortcode($attributes = array(), $content = '')
{
$default_attributes = array(
'id' => '',
'lists' => '',
'email_type' => '',
'element_id' => '',
'element_class' => '',
);
$attributes = shortcode_atts(
$default_attributes,
$attributes,
self::SHORTCODE
);
$config = array(
'element_id' => $attributes['element_id'],
'lists' => $attributes['lists'],
'email_type' => $attributes['email_type'],
'element_class' => $attributes['element_class'],
);
return $this->output_form($attributes['id'], $config, false);
}
/**
* @param int $id
* @param array $config
* @param bool $echo
*
* @return string
*/
public function output_form($id = 0, $config = array(), $echo = true)
{
try {
$form = mc4wp_get_form($id);
} catch (Exception $e) {
if (current_user_can('manage_options')) {
return sprintf('<strong>Mailchimp for WordPress error:</strong> %s', $e->getMessage());
}
return '';
}
++$this->count;
// set a default element_id if none is given
if (empty($config['element_id'])) {
$config['element_id'] = 'mc4wp-form-' . $this->count;
}
$form_html = $form->get_html($config['element_id'], $config);
try {
// start new output buffer
ob_start();
/**
* Runs just before a form element is outputted.
*
* @since 3.0
*
* @param MC4WP_Form $form
*/
do_action('mc4wp_output_form', $form);
// output the form (in output buffer)
echo $form_html;
// grab all contents in current output buffer & then clean + end it.
$html = ob_get_clean();
} catch (Error $e) {
$html = $form_html;
}
// echo content if necessary
if ($echo) {
echo $html;
}
return $html;
}
}
This diff could not be displayed because it is too large.