Version Description
Download this release
Release Info
Developer | constantcontact |
Plugin | Creative Mail – Easier WordPress & WooCommerce Email Marketing |
Version | 1.1.0 |
Comparing to | |
See all releases |
Code changes from version 1.0.4 to 1.1.0
- CHANGELOG.md +6 -0
- README.md +93 -35
- assets/css/admin.css +47 -4
- composer.json +2 -1
- composer.lock +38 -3
- creative-mail-plugin.php +8 -4
- readme.txt +38 -36
- src/creativemail.php +11 -7
- src/helpers/options-helper.php +140 -0
- src/managers/admin-manager.php +11 -0
- src/managers/api-manager.php +397 -79
- src/managers/email-manager.php +499 -0
- src/managers/instance-manager.php +9 -15
- src/managers/integration-manager.php +15 -3
- src/modules/api/Models/ApiRequestItem.php +31 -0
- src/modules/api/Processes/ApiBackgroundProcess.php +68 -0
- src/modules/blog/models/BlogAttachment.php +8 -2
- src/modules/blog/models/BlogInformation.php +4 -3
- src/modules/contacts/Handlers/ContactFormSevenPluginHandler.php +1 -0
- src/modules/contacts/Handlers/GravityFormsPluginHandler.php +202 -0
- src/modules/contacts/Handlers/JetpackPluginHandler.php +159 -0
- src/modules/contacts/Handlers/NewsLetterContactFormPluginHandler.php +2 -1
- src/modules/contacts/Handlers/WooCommercePluginHandler.php +2 -1
- src/modules/contacts/Handlers/WpFormsLitePluginHandler.php +1 -0
- src/modules/contacts/Services/ContactsSyncService.php +24 -63
- src/modules/contacts/models/ContactModel.php +11 -1
- src/modules/woocommerce/models/WCInformationModel.php +21 -0
- src/modules/woocommerce/models/WCStoreInformation.php +6 -2
- src/views/dashboard.php +17 -0
- src/views/onboarding.php +5 -0
- vendor/a5hleyrich/wp-background-processing/.gitignore +1 -0
- vendor/a5hleyrich/wp-background-processing/README.md +158 -0
- vendor/a5hleyrich/wp-background-processing/classes/wp-async-request.php +163 -0
- vendor/a5hleyrich/wp-background-processing/classes/wp-background-process.php +506 -0
- vendor/a5hleyrich/wp-background-processing/composer.json +18 -0
- vendor/a5hleyrich/wp-background-processing/license.txt +280 -0
- vendor/a5hleyrich/wp-background-processing/wp-background-processing.php +20 -0
- vendor/autoload.php +1 -1
- vendor/composer/autoload_classmap.php +8 -0
- vendor/composer/autoload_real.php +4 -4
- vendor/composer/autoload_static.php +12 -4
- vendor/composer/installed.json +38 -0
CHANGELOG.md
CHANGED
@@ -1,6 +1,12 @@
|
|
1 |
Changelog
|
2 |
=========
|
3 |
|
|
|
|
|
|
|
|
|
|
|
|
|
4 |
#### 1.0.4 - July 23 2020
|
5 |
- Small fixes in the plugin readme.
|
6 |
- Added compatibility with PHP 5.6
|
1 |
Changelog
|
2 |
=========
|
3 |
|
4 |
+
#### 1.1.0 - September 1 2020
|
5 |
+
- Add support for WooCommerce emails
|
6 |
+
- Add support for JetPack forms
|
7 |
+
- Add support for WPForms Lite
|
8 |
+
- Add support for Gravity forms
|
9 |
+
|
10 |
#### 1.0.4 - July 23 2020
|
11 |
- Small fixes in the plugin readme.
|
12 |
- Added compatibility with PHP 5.6
|
README.md
CHANGED
@@ -1,37 +1,95 @@
|
|
1 |
-
|
2 |
-
|
3 |
-
|
4 |
-
|
5 |
-
|
6 |
-
|
7 |
-
|
8 |
-
|
9 |
-
|
10 |
-
|
11 |
-
Power your WooCommerce Store or WordPress Blog with simple & free email marketing from Constant Contact.
|
12 |
-
With the official Creative Mail for WooCommerce plugin, your products, blog posts, images and store links are automatically included as rich shoppable email marketing content for your customers. Our included CRM also intelligently pulls in and identifies your WordPress site contacts and WooCommerce store customers. That makes it easy to build audiences and send targeted customer campaigns. Get free email marketing, 98% deliverability, and Constant Contact rock solid reliability all without ever needing to leave your WP Admin.
|
13 |
-
|
14 |
-
#### Features
|
15 |
-
A Constant Contact WordPress plugin that gathers contacts submitted via the WordPress site forms and enables users to send email campaigns in a simple and intuitive way.
|
16 |
-
|
17 |
-
The plugin offers the following functionality:
|
18 |
-
|
19 |
-
- Automated email creation
|
20 |
-
- Section based, offering preset vs unlimited design options
|
21 |
-
- Seamless integration with the following Contact opt-ins without need for adding JMML:
|
22 |
-
- Contact Form 7
|
23 |
-
- WooCommerce
|
24 |
-
- WPForms Lite
|
25 |
-
- Newsletter
|
26 |
-
- Combined Contacts CRM (fed from WordPress Site forms & WooCommerce store)
|
27 |
-
- Stock images (Unsplash integration, for free)
|
28 |
-
- WordPress Blog Posts & WooCommerce Products integration to allow easy sharing via email campaigns
|
29 |
-
|
30 |
-
|
31 |
-
#### Installing the plugin
|
32 |
-
1. In your WordPress admin panel, go to *Plugins > New Plugin*, search for `Creative Mail by Constant Contact` and click "*Install now*"
|
33 |
-
1. Alternatively, download the plugin and upload the contents of `*.zip` to your plugins directory, which usually is `/wp-content/plugins/`.
|
34 |
-
1. Activate the plugin
|
35 |
-
1. Log Into your account or sign up.
|
36 |
|
|
|
|
|
37 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
=== Creative Mail – Easier WordPress & WooCommerce Email Marketing ===
|
2 |
+
Contributors: Constant Contact
|
3 |
+
Tags: email, marketing, newsletter, subscribe, contact form, constant contact, crm, automations, ecommerce, promotion, offers, retargeting
|
4 |
+
Requires at least: 4.6
|
5 |
+
Tested up to: 5.5
|
6 |
+
Stable tag: 1.1
|
7 |
+
License: GPLv2 or later
|
8 |
+
License URI: http://www.gnu.org/licenses/gpl-2.0.html
|
9 |
+
Requires PHP: 5.6
|
10 |
+
Website: https://www.creativemail.com
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
11 |
|
12 |
+
== Description ==
|
13 |
+
Creative Mail was designed specifically for WordPress and WooCommerce.
|
14 |
|
15 |
+
Our intelligent (and super fun) email editor simplifies email marketing campaign creation and pulls your WordPress blog posts, website images and WooCommerce products right into your email content. Leads from your WordPress website, ecommerce store and contact forms are automatically captured and routed into our included Contacts CRM and synced with your email marketing lists.
|
16 |
+
|
17 |
+
It’s perfect for newsletters and announcements, to promote events, share product specials, retarget ecommerce shoppers, send postcards, provide updates and more.
|
18 |
+
|
19 |
+
Create awesome emails right from your WordPress Admin Dashboard that are all powered by the award-winning & rock-solid reliability of Constant Contact.
|
20 |
+
|
21 |
+
### [VIEW OUR DETAILED FEATURES](https://www.creativemail.com/plans)
|
22 |
+
|
23 |
+
### [WOOCOMMERCE & WORDPRESS INTEGRATION](https://www.creativemail.com):
|
24 |
+
Turn your WooCommerce store and your WordPress site into efficient marketing engines. All ecommerce purchases and form entries are all captured in our included CRM and synced automatically with Creative Mail.
|
25 |
+
|
26 |
+
- **Enhanced Ecommerce:** WooCommerce store purchase emails and ecommerce inquiries are all captured automatically within your email marketing list. Retarget and re-engage your customers. Sell more stuff.
|
27 |
+
- **Beautiful Transactional Emails:** Standard WooCommerce triggered emails can be replaced to match your branding and style. Build one and all your other WooCommerce emails managed by Creative will inherit the same branded look. Hey, style matters. (Coming Soon)
|
28 |
+
- **Jetpack Forms Integration:** Collect,sync, and manage opt-in subscribers directly from Jetpack forms into Creative Mail.
|
29 |
+
- **Build Better Branding:** Creative Mail includes our free LogoMaker and image editing suite to enhance your brand.
|
30 |
+
- **Amazing Unsplash Images:** You get free access to the completely integrated Unsplash photo library (in addition to your own WordPress media library) to make amazing campaigns with award winning images. Unsplash is simply awesome!
|
31 |
+
- **Get Better Deliverability:** Other email solutions require complex SMTP solutions, external gateways or have you sending from their less than stellar IPs. As a result, your emails can get bounced or never delivered. Creative Mail is an all in one solution that uses Constant Contact’s rock solid infrastructure, for superior deliverability. Boom! ‘nuff said.
|
32 |
+
- **Live Support:** With our paid plans you get access to phone and chat support to help you get answers from real live, nice humans. Imagine that!
|
33 |
+
|
34 |
+
### [OPT-IN EMAIL FORMS](https://www.creativemail.com):
|
35 |
+
- **Jetpack & WordPress Website Forms:** Creative Mail detects the current website forms used on your site, and automatically adds contacts to your email marketing lists. Automagically awesome!
|
36 |
+
- **JMML Form Options:** Create Mail includes a JMML (join my mailing list) form. When activated, contacts who sign up for your mailing list through one of our JMML forms are sent an automatic “Confirm Opt-in” message to the email address they provided, asking them to confirm their subscription. (Coming Soon)
|
37 |
+
|
38 |
+
### [EMAIL AUTOMATIONS](https://www.creativemail.com):
|
39 |
+
- **Scheduled Sends:** Schedule the time and date of outgoing email marketing campaigns based on your business or organizations preferences.
|
40 |
+
- **Single-Step Automations:** Replace your non-branded triggered emails with on-brand Creative Mail emails for deeper customer engagement.
|
41 |
+
- **Multi-Step Marketing Journeys:** Develop sophisticated CLM (that’s marketing speak for - customer lifecycle marketing) campaigns by leveraging our “if this, then that” campaign automation engine that responds to a customers actions or purchases. (Coming Soon)
|
42 |
+
|
43 |
+
### [ANALYTICS & INSIGHTS](https://www.creativemail.com):
|
44 |
+
- **Realtime Email Marketing Statistics:** Bounces, opens, clicks, forwards, complaints, unsubscribes and more are easily tracked and managed. Be a control freak, it’s OK.
|
45 |
+
- **Marketing Campaign Mapview:** With our mapview you can see who's opening your emails on what devices on an interactive visual map.
|
46 |
+
|
47 |
+
### [CREATIVE CONTACTS CRM](https://www.creativemail.com):
|
48 |
+
- **Contact Lists:** Within the Creative Mail Contacts CRM you can quickly and easily manage all your Contacts, Subscribers and Unsubscribes.
|
49 |
+
- **Contact Activity:** Drill into the purchases and behaviors of your contacts.
|
50 |
+
- **List Sources:** You’ll know where your contacts come from whether it’s manual entry, your Jetpack form, WooCommerce Store, or another defined source.
|
51 |
+
- **Custom Labels:** Further refine your marketing by adding custom labels to subscribers or customers (ex. Truck Buyers, Concert Attendee, Dog Owners, etc.).
|
52 |
+
|
53 |
+
### [IMPORT & EXPORT](https://www.creativemail.com):
|
54 |
+
- **Contacts Sync & Import:** Forget adding complex integrations between your WordPress site and your email marketing provider. With Creative Mail it all simply works with WordPress out of the box. We do the heavy lifting to sync and import your Jetpack, WordPress or WooCommerce contacts automatically.
|
55 |
+
- **Import & Export Via CSV:** From our Creative Mail Contacts CRM you can import bulk email marketing lists (limits may apply), add subscribers one by one, or export your contacts into a CSV file.
|
56 |
+
|
57 |
+
### [CAMPAIGNS](https://www.creativemail.com):
|
58 |
+
- **AI Emails:** Forget templates, let our A.I. build your email marketing campaigns for you. Pull in WordPress posts or WooCommerce products for sale and you’re good to go. Let our robots do your bidding!
|
59 |
+
- **Email Campaign:** Build your email marketing campaigns in seconds from your WordPress admin dashboard.
|
60 |
+
- **Awesome Deliverability:** All email marketing campaigns are sent and delivered by the award-winning power of Constant Contact technology. We got you.
|
61 |
+
- **Automated Email Marketing:** Send multi-step email campaigns automatically, with triggers you define, whether that’s based on time or behavioral actions. (Coming Soon)
|
62 |
+
|
63 |
+
### [EMAIL LIST MANAGEMENT](https://www.creativemail.com):
|
64 |
+
- **Join My Mailing List:** Creative Mail collects leads from Jetpack forms or the top WordPress lead capture forms and adds them directly to your email lists.
|
65 |
+
- **Automate email:** With our “Welcome” email trigger you can send a Creative Mail welcome message to new subscribers and blog readers.
|
66 |
+
- **Auto List Updater:** Creative Mail automatically updates your contact lists for email bounces or unsubscribes.
|
67 |
+
|
68 |
+
## CREATIVE MAIL IS:
|
69 |
+
1. Incredibly easy WordPress email marketing
|
70 |
+
1. Deeply connected to your website & WooCommerce store
|
71 |
+
1. Accessed from within your WP Admin Dashboard
|
72 |
+
1. Automatically syncing your contacts and building your marketing lists
|
73 |
+
1. Powered by the reliability superior deliverability of Constant Contact
|
74 |
+
1. Fun, which makes life way better
|
75 |
+
|
76 |
+
## TERMS OF SERVICE & PRIVACY POLICY
|
77 |
+
On behalf of our lawyers (seriously, they’re nice people), please feel free to review our:
|
78 |
+
|
79 |
+
Creative Mail by Constant Contact [Terms of Service](https://www.constantcontact.com/website/terms)
|
80 |
+
Creative Mail by Constant Contact [Privacy Policy](https://endurance.clarip.com/privacycenter/?brand=ctct)
|
81 |
+
|
82 |
+
== Screenshots ==
|
83 |
+
1. Our Awesome Email Editor
|
84 |
+
2. Style your campaign
|
85 |
+
3. All of your Contacts in one place
|
86 |
+
4. Your Awesome Campaigns
|
87 |
+
5. Open your email marketing from your WP-admin dashboard
|
88 |
+
|
89 |
+
== Changelog ==
|
90 |
+
* 1.1.0 - Added support for WooCommerce emails, WPFormsLite and JetPack Forms
|
91 |
+
* 1.0.4 - Added compatibility with PHP 5.6
|
92 |
+
* 1.0.3 - Small fixes in the plugin readme.
|
93 |
+
* 1.0.2 - Small fixes in the plugin readme.
|
94 |
+
* 1.0.1 - Fixes an issue where the "Let's get started" button needed to be clicked twice in some cases.
|
95 |
+
* 1.0.0 - Initial version of the plugin
|
assets/css/admin.css
CHANGED
@@ -200,10 +200,6 @@
|
|
200 |
text-transform: none;
|
201 |
}
|
202 |
|
203 |
-
.ce4wp-button-root:hover{
|
204 |
-
color: rgba(255, 255, 255, 0.7);
|
205 |
-
}
|
206 |
-
|
207 |
.ce4wp-button-contained {
|
208 |
color: rgba(0, 0, 0, 0.87);
|
209 |
box-shadow: none;
|
@@ -217,6 +213,25 @@
|
|
217 |
font-weight: 700;
|
218 |
background-color: #7A4CA8;
|
219 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
220 |
|
221 |
.ce4wp-button-text-primary {
|
222 |
align-items:center;
|
@@ -624,4 +639,32 @@
|
|
624 |
}
|
625 |
.ce4wp-d-flex {
|
626 |
display: flex !important;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
627 |
}
|
200 |
text-transform: none;
|
201 |
}
|
202 |
|
|
|
|
|
|
|
|
|
203 |
.ce4wp-button-contained {
|
204 |
color: rgba(0, 0, 0, 0.87);
|
205 |
box-shadow: none;
|
213 |
font-weight: 700;
|
214 |
background-color: #7A4CA8;
|
215 |
}
|
216 |
+
.ce4wp-button-contained-primary:hover {
|
217 |
+
box-shadow: none;
|
218 |
+
background-color: #663399;
|
219 |
+
color: rgba(255, 255, 255, 0.7);
|
220 |
+
}
|
221 |
+
|
222 |
+
.ce4wp-button-outlined {
|
223 |
+
border: 1px solid rgba(0, 0, 0, 0.23);
|
224 |
+
padding: 5px 15px;
|
225 |
+
}
|
226 |
+
.ce4wp-button-outlined-primary {
|
227 |
+
color: #7A4CA8;
|
228 |
+
border: 1px solid #7A4CA8;
|
229 |
+
}
|
230 |
+
.ce4wp-button-outlined-primary:hover {
|
231 |
+
border: 1px solid #7A4CA8;
|
232 |
+
background-color: rgba(122, 76, 168, 0.04);
|
233 |
+
color: #7A4CA8;
|
234 |
+
}
|
235 |
|
236 |
.ce4wp-button-text-primary {
|
237 |
align-items:center;
|
639 |
}
|
640 |
.ce4wp-d-flex {
|
641 |
display: flex !important;
|
642 |
+
}
|
643 |
+
|
644 |
+
.status-creativemail {
|
645 |
+
font-size: 1.4em;
|
646 |
+
display: block;
|
647 |
+
text-indent: -9999px;
|
648 |
+
position: relative;
|
649 |
+
height: 1em;
|
650 |
+
width: 1em;
|
651 |
+
}
|
652 |
+
|
653 |
+
.status-creativemail::before {
|
654 |
+
font-family: WooCommerce;
|
655 |
+
speak: none;
|
656 |
+
font-weight: 400;
|
657 |
+
font-variant: normal;
|
658 |
+
text-transform: none;
|
659 |
+
line-height: 1;
|
660 |
+
margin: 0;
|
661 |
+
text-indent: 0;
|
662 |
+
position: absolute;
|
663 |
+
top: 0;
|
664 |
+
left: 0;
|
665 |
+
width: 100%;
|
666 |
+
height: 100%;
|
667 |
+
text-align: center;
|
668 |
+
content: "";
|
669 |
+
color: #999;
|
670 |
}
|
composer.json
CHANGED
@@ -6,7 +6,8 @@
|
|
6 |
"defuse/php-encryption": "^2.2",
|
7 |
"firebase/php-jwt": "^5.0",
|
8 |
"ext-curl": "*",
|
9 |
-
"ext-json": "*"
|
|
|
10 |
},
|
11 |
"autoload": {
|
12 |
"psr-4": {
|
6 |
"defuse/php-encryption": "^2.2",
|
7 |
"firebase/php-jwt": "^5.0",
|
8 |
"ext-curl": "*",
|
9 |
+
"ext-json": "*",
|
10 |
+
"a5hleyrich/wp-background-processing": "^1.0"
|
11 |
},
|
12 |
"autoload": {
|
13 |
"psr-4": {
|
composer.lock
CHANGED
@@ -4,8 +4,44 @@
|
|
4 |
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
5 |
"This file is @generated automatically"
|
6 |
],
|
7 |
-
"content-hash": "
|
8 |
"packages": [
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
9 |
{
|
10 |
"name": "defuse/php-encryption",
|
11 |
"version": "v2.2.1",
|
@@ -175,6 +211,5 @@
|
|
175 |
"ext-curl": "*",
|
176 |
"ext-json": "*"
|
177 |
},
|
178 |
-
"platform-dev": []
|
179 |
-
"plugin-api-version": "1.1.0"
|
180 |
}
|
4 |
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
5 |
"This file is @generated automatically"
|
6 |
],
|
7 |
+
"content-hash": "8c2f62e78bc917ad923d70c228460395",
|
8 |
"packages": [
|
9 |
+
{
|
10 |
+
"name": "a5hleyrich/wp-background-processing",
|
11 |
+
"version": "1.0.1",
|
12 |
+
"source": {
|
13 |
+
"type": "git",
|
14 |
+
"url": "https://github.com/A5hleyRich/wp-background-processing.git",
|
15 |
+
"reference": "1f070aab5058dbaf45d5435a343033ddd8a641b1"
|
16 |
+
},
|
17 |
+
"dist": {
|
18 |
+
"type": "zip",
|
19 |
+
"url": "https://api.github.com/repos/A5hleyRich/wp-background-processing/zipball/1f070aab5058dbaf45d5435a343033ddd8a641b1",
|
20 |
+
"reference": "1f070aab5058dbaf45d5435a343033ddd8a641b1",
|
21 |
+
"shasum": ""
|
22 |
+
},
|
23 |
+
"require": {
|
24 |
+
"php": ">=5.2"
|
25 |
+
},
|
26 |
+
"type": "library",
|
27 |
+
"autoload": {
|
28 |
+
"classmap": [
|
29 |
+
"classes/"
|
30 |
+
]
|
31 |
+
},
|
32 |
+
"notification-url": "https://packagist.org/downloads/",
|
33 |
+
"license": [
|
34 |
+
"GPL-2.0-only"
|
35 |
+
],
|
36 |
+
"authors": [
|
37 |
+
{
|
38 |
+
"name": "Ashley Rich",
|
39 |
+
"email": "hello@ashleyrich.com"
|
40 |
+
}
|
41 |
+
],
|
42 |
+
"description": "WP Background Processing can be used to fire off non-blocking asynchronous requests or as a background processing tool, allowing you to queue tasks.",
|
43 |
+
"time": "2018-02-12T09:24:05+00:00"
|
44 |
+
},
|
45 |
{
|
46 |
"name": "defuse/php-encryption",
|
47 |
"version": "v2.2.1",
|
211 |
"ext-curl": "*",
|
212 |
"ext-json": "*"
|
213 |
},
|
214 |
+
"platform-dev": []
|
|
|
215 |
}
|
creative-mail-plugin.php
CHANGED
@@ -3,10 +3,10 @@ use CreativeMail\CreativeMail;
|
|
3 |
|
4 |
/**
|
5 |
* Plugin Name: Creative Mail by Constant Contact
|
6 |
-
* Plugin URI: https://
|
7 |
-
* Description: Power your WooCommerce Store or WordPress Blog with simple & free email marketing from Constant Contact. With the official Creative Mail for WooCommerce plugin, your products, blog posts, images and store links are automatically included as rich shoppable email marketing content for your customers. Our included CRM also intelligently pulls in and identifies your WordPress site contacts and WooCommerce store customers. That makes it easy to build audiences and send targeted customer campaigns. Get free email marketing,
|
8 |
* Author: Constant Contact
|
9 |
-
* Version: 1.0
|
10 |
* Author URI: https://www.constantcontact.com
|
11 |
*/
|
12 |
|
@@ -20,7 +20,7 @@ function _load_ce4wp_plugin() {
|
|
20 |
|
21 |
define('CE4WP_PLUGIN_DIR', __DIR__ . '/');
|
22 |
define('CE4WP_PLUGIN_URL', plugin_dir_url(__FILE__) . '/');
|
23 |
-
define('CE4WP_PLUGIN_VERSION', '1.0
|
24 |
define('CE4WP_INSTANCE_UUID_KEY', 'ce4wp_instance_uuid');
|
25 |
define('CE4WP_INSTANCE_HANDSHAKE_TOKEN', 'ce4wp_handshake_token');
|
26 |
define('CE4WP_INSTANCE_HANDSHAKE_EXPIRATION', 'ce4wp_handshake_expiration');
|
@@ -29,12 +29,16 @@ function _load_ce4wp_plugin() {
|
|
29 |
define('CE4WP_ENCRYPTION_KEY_KEY', 'ce4wp_encryption_key');
|
30 |
define('CE4WP_CONNECTED_ACCOUNT_ID', 'ce4wp_connected_account_id');
|
31 |
define('CE4WP_ACTIVATED_PLUGINS', 'ce4wp_activated_plugins');
|
|
|
32 |
define('CE4WP_ACCEPTED_CONSENT', 'ce4wp_accepted_consent');
|
33 |
define('CE4WP_SYNCHRONIZE_ACTION', 'ce4wp_synchronize_contacts');
|
34 |
define('CE4WP_APP_GATEWAY_URL', 'https://app-gateway.creativemail.com/');
|
35 |
define('CE4WP_APP_URL', 'https://app.creativemail.com/');
|
36 |
define('CE4WP_ENVIRONMENT', 'PRODUCTION');
|
37 |
define('CE4WP_BATCH_SIZE', 500);
|
|
|
|
|
|
|
38 |
|
39 |
// Load all the required files
|
40 |
if (file_exists(__DIR__ . '/vendor/autoload.php')) {
|
3 |
|
4 |
/**
|
5 |
* Plugin Name: Creative Mail by Constant Contact
|
6 |
+
* Plugin URI: https://wordpress.org/plugins/creative-mail-by-constant-contact/
|
7 |
+
* Description: Power your WooCommerce Store or WordPress Blog with simple & free email marketing from Constant Contact. With the official Creative Mail for WooCommerce plugin, your products, blog posts, images and store links are automatically included as rich shoppable email marketing content for your customers. Our included CRM also intelligently pulls in and identifies your WordPress site contacts and WooCommerce store customers. That makes it easy to build audiences and send targeted customer campaigns. Get free email marketing, 97% deliverability, and Constant Contact rock solid reliability all without ever needing to leave your WP Admin.
|
8 |
* Author: Constant Contact
|
9 |
+
* Version: 1.1.0
|
10 |
* Author URI: https://www.constantcontact.com
|
11 |
*/
|
12 |
|
20 |
|
21 |
define('CE4WP_PLUGIN_DIR', __DIR__ . '/');
|
22 |
define('CE4WP_PLUGIN_URL', plugin_dir_url(__FILE__) . '/');
|
23 |
+
define('CE4WP_PLUGIN_VERSION', '1.1.0');
|
24 |
define('CE4WP_INSTANCE_UUID_KEY', 'ce4wp_instance_uuid');
|
25 |
define('CE4WP_INSTANCE_HANDSHAKE_TOKEN', 'ce4wp_handshake_token');
|
26 |
define('CE4WP_INSTANCE_HANDSHAKE_EXPIRATION', 'ce4wp_handshake_expiration');
|
29 |
define('CE4WP_ENCRYPTION_KEY_KEY', 'ce4wp_encryption_key');
|
30 |
define('CE4WP_CONNECTED_ACCOUNT_ID', 'ce4wp_connected_account_id');
|
31 |
define('CE4WP_ACTIVATED_PLUGINS', 'ce4wp_activated_plugins');
|
32 |
+
define('CE4WP_MANAGED_EMAIL_NOTIFICATIONS', 'ce4wp_managed_email_notifications');
|
33 |
define('CE4WP_ACCEPTED_CONSENT', 'ce4wp_accepted_consent');
|
34 |
define('CE4WP_SYNCHRONIZE_ACTION', 'ce4wp_synchronize_contacts');
|
35 |
define('CE4WP_APP_GATEWAY_URL', 'https://app-gateway.creativemail.com/');
|
36 |
define('CE4WP_APP_URL', 'https://app.creativemail.com/');
|
37 |
define('CE4WP_ENVIRONMENT', 'PRODUCTION');
|
38 |
define('CE4WP_BATCH_SIZE', 500);
|
39 |
+
define('CE4WP_WC_API_KEY_ID', 'ce4wp_woocommerce_api_key_id');
|
40 |
+
define('CE4WP_WC_API_CONSUMER_KEY', 'ce4wp_woocommerce_consumer_key');
|
41 |
+
define('CE4WP_REFERRED_BY', 'ce4wp_referred_by');
|
42 |
|
43 |
// Load all the required files
|
44 |
if (file_exists(__DIR__ . '/vendor/autoload.php')) {
|
readme.txt
CHANGED
@@ -2,8 +2,8 @@
|
|
2 |
Contributors: Constant Contact
|
3 |
Tags: email, marketing, newsletter, subscribe, contact form, constant contact, crm, automations, ecommerce, promotion, offers, retargeting
|
4 |
Requires at least: 4.6
|
5 |
-
Tested up to: 5.
|
6 |
-
Stable tag: 1.
|
7 |
License: GPLv2 or later
|
8 |
License URI: http://www.gnu.org/licenses/gpl-2.0.html
|
9 |
Requires PHP: 5.6
|
@@ -12,57 +12,57 @@ Website: https://www.creativemail.com
|
|
12 |
== Description ==
|
13 |
Creative Mail was designed specifically for WordPress and WooCommerce.
|
14 |
|
15 |
-
Our intelligent (and super fun) email editor simplifies email creation and pulls your WordPress blog posts, website images and WooCommerce products right into your email content. Leads from your WordPress website, ecommerce store and contact forms are automatically captured and routed into our included Contacts CRM and synced with your email marketing lists.
|
16 |
|
17 |
-
It’s perfect for newsletters and announcements,
|
18 |
|
19 |
-
Create awesome
|
20 |
|
21 |
### [VIEW OUR DETAILED FEATURES](https://www.creativemail.com/plans)
|
22 |
|
23 |
### [WOOCOMMERCE & WORDPRESS INTEGRATION](https://www.creativemail.com):
|
24 |
-
Turn your WooCommerce store and your WordPress site into efficient marketing engines. All
|
25 |
|
26 |
-
- **Enhanced Ecommerce:** WooCommerce store
|
27 |
-
- **
|
28 |
-
- **
|
29 |
-
- **Build Better Branding:** Creative includes our free LogoMaker and image editing suite to enhance your brand.
|
30 |
-
- **Amazing
|
31 |
-
- **Get Better Deliverability:** Other email solutions require complex SMTP solutions, external gateways or have you sending from their less than stellar IPs. As a result, your emails can get bounced or never delivered. Creative Mail is an all
|
32 |
-
- **Live Support:** With our paid plans you get access to phone and chat support to help you get answers from real live,
|
33 |
|
34 |
### [OPT-IN EMAIL FORMS](https://www.creativemail.com):
|
35 |
-
- **WordPress Website Forms:** Creative Mail detects the current website forms used on your site, and automatically adds contacts to your email lists. Automagically awesome!
|
36 |
-
- **JMML Form
|
37 |
|
38 |
### [EMAIL AUTOMATIONS](https://www.creativemail.com):
|
39 |
-
- **Scheduled Sends:** Schedule the time and date of outgoing
|
40 |
-
- **Single-Step
|
41 |
-
- **Multi-Step
|
42 |
|
43 |
### [ANALYTICS & INSIGHTS](https://www.creativemail.com):
|
44 |
-
- **Realtime Email Statistics:** Bounces, opens, clicks, forwards, complaints, unsubscribes and more are easily tracked and managed. Be a control freak, it’s OK.
|
45 |
-
- **Campaign Mapview:** With our mapview you can see who's opening your emails on what devices on an interactive visual map.
|
46 |
|
47 |
-
### [
|
48 |
- **Contact Lists:** Within the Creative Mail Contacts CRM you can quickly and easily manage all your Contacts, Subscribers and Unsubscribes.
|
49 |
- **Contact Activity:** Drill into the purchases and behaviors of your contacts.
|
50 |
-
- **List Sources:** You’ll know where your contacts come from whether it’s manual entry, your
|
51 |
- **Custom Labels:** Further refine your marketing by adding custom labels to subscribers or customers (ex. Truck Buyers, Concert Attendee, Dog Owners, etc.).
|
52 |
|
53 |
### [IMPORT & EXPORT](https://www.creativemail.com):
|
54 |
-
- **Contacts Sync & Import:** We
|
55 |
-
- **Import & Export Via CSV:** From our Creative Mail Contacts CRM you can import bulk lists (limits may apply), add subscribers one by one, or export your contacts into a CSV file.
|
56 |
|
57 |
### [CAMPAIGNS](https://www.creativemail.com):
|
58 |
-
- **AI Emails:** Forget templates, let our A.I. build
|
59 |
-
- **Email Campaign:** Build your campaigns in seconds from
|
60 |
-
- **Awesome Deliverability:**
|
61 |
-
- **Email
|
62 |
|
63 |
### [EMAIL LIST MANAGEMENT](https://www.creativemail.com):
|
64 |
-
- **
|
65 |
-
- **Automate
|
66 |
- **Auto List Updater:** Creative Mail automatically updates your contact lists for email bounces or unsubscribes.
|
67 |
|
68 |
## CREATIVE MAIL IS:
|
@@ -71,7 +71,7 @@ Turn your WooCommerce store and your WordPress site into efficient marketing eng
|
|
71 |
1. Accessed from within your WP Admin Dashboard
|
72 |
1. Automatically syncing your contacts and building your marketing lists
|
73 |
1. Powered by the reliability superior deliverability of Constant Contact
|
74 |
-
1. Fun, which makes life way better
|
75 |
|
76 |
## TERMS OF SERVICE & PRIVACY POLICY
|
77 |
On behalf of our lawyers (seriously, they’re nice people), please feel free to review our:
|
@@ -80,13 +80,15 @@ Creative Mail by Constant Contact [Terms of Service](https://www.constantcontact
|
|
80 |
Creative Mail by Constant Contact [Privacy Policy](https://endurance.clarip.com/privacycenter/?brand=ctct)
|
81 |
|
82 |
== Screenshots ==
|
83 |
-
1.
|
84 |
-
2.
|
85 |
-
3.
|
86 |
-
4.
|
87 |
-
5.
|
|
|
88 |
|
89 |
== Changelog ==
|
|
|
90 |
* 1.0.4 - Added compatibility with PHP 5.6
|
91 |
* 1.0.3 - Small fixes in the plugin readme.
|
92 |
* 1.0.2 - Small fixes in the plugin readme.
|
2 |
Contributors: Constant Contact
|
3 |
Tags: email, marketing, newsletter, subscribe, contact form, constant contact, crm, automations, ecommerce, promotion, offers, retargeting
|
4 |
Requires at least: 4.6
|
5 |
+
Tested up to: 5.5
|
6 |
+
Stable tag: 1.1
|
7 |
License: GPLv2 or later
|
8 |
License URI: http://www.gnu.org/licenses/gpl-2.0.html
|
9 |
Requires PHP: 5.6
|
12 |
== Description ==
|
13 |
Creative Mail was designed specifically for WordPress and WooCommerce.
|
14 |
|
15 |
+
Our intelligent (and super fun) email editor simplifies email marketing campaign creation and pulls your WordPress blog posts, website images and WooCommerce products right into your email content. Leads from your WordPress website, ecommerce store and contact forms are automatically captured and routed into our included Contacts CRM and synced with your email marketing lists.
|
16 |
|
17 |
+
It’s perfect for automatic blog post syndication, newsletters and announcements, event promotion, WooCommerce product specials, retargeting ecommerce shoppers, sending postcards, providing updates and more.
|
18 |
|
19 |
+
Create awesome email marketing campaigns right from your WordPress Admin Dashboard that are all powered by the award-winning & rock-solid reliability of Constant Contact.
|
20 |
|
21 |
### [VIEW OUR DETAILED FEATURES](https://www.creativemail.com/plans)
|
22 |
|
23 |
### [WOOCOMMERCE & WORDPRESS INTEGRATION](https://www.creativemail.com):
|
24 |
+
Turn your WooCommerce store and your WordPress site into efficient marketing engines. All ecommerce contacts and form entries are all captured in our included CRM and synced automatically with Creative Mail.
|
25 |
|
26 |
+
- **Enhanced Ecommerce:** WooCommerce store customers and ecommerce interactions are all captured automatically within your email marketing list. Retarget and re-engage your customers. Sell more stuff.
|
27 |
+
- **Beautiful Transactional Emails:** Standard WooCommerce triggered emails can be replaced to match your branding and style. Build one, and then all your other WooCommerce emails managed by Creative will inherit the same branded look. Hey, style matters.
|
28 |
+
- **Jetpack Forms Integration:** Collect, sync, and manage opt-in subscribers directly from Jetpack forms into Creative Mail.
|
29 |
+
- **Build Better Branding:** Creative Mail includes our free LogoMaker and image editing suite to enhance your brand.
|
30 |
+
- **Amazing Stock Images:** You get free access to the completely integrated photo library (in addition to your own WordPress media library) to make amazing email marketing campaigns with award winning images.
|
31 |
+
- **Get Better Deliverability:** Other email marketing solutions require complex SMTP solutions, external gateways or have you sending from their less than stellar IPs. As a result, your emails can get bounced or never delivered. Creative Mail is an all-in-one solution that uses Constant Contact’s rock solid infrastructure, for superior deliverability. Boom! ‘nuff said.
|
32 |
+
- **Live Support:** With our paid plans (Awesome & Ultimate) you get access to phone and chat support to help you get answers from real live, helpful humans. Imagine that!
|
33 |
|
34 |
### [OPT-IN EMAIL FORMS](https://www.creativemail.com):
|
35 |
+
- **Jetpack & WordPress Website Forms:** Creative Mail detects the current website forms used on your site, and automatically adds contacts to your email marketing lists. Automagically awesome!
|
36 |
+
- **JMML Newsletter Form:** Create Mail and Jetpack now include a JMML (join my mailing list) Newsletter Signup form. When activated, contacts who sign up for your Newsletter through the JMML form are brought right into your Newsletter email marketing list. Easy peasy.
|
37 |
|
38 |
### [EMAIL AUTOMATIONS](https://www.creativemail.com):
|
39 |
+
- **Scheduled Sends:** Schedule the time and date of outgoing email marketing campaigns based on your business or organizations preferences.
|
40 |
+
- **Single-Step Triggered Emails:** Replace your non-branded triggered emails with on-brand Creative Mail emails for deeper customer engagement.
|
41 |
+
- **Multi-Step Marketing Journeys:** Develop sophisticated CLM (that’s marketing speak for - customer lifecycle marketing) campaigns by leveraging our “if this, then that” campaign automation engine that responds to a customers actions or purchases. (Coming Soon)
|
42 |
|
43 |
### [ANALYTICS & INSIGHTS](https://www.creativemail.com):
|
44 |
+
- **Realtime Email Marketing Statistics:** Bounces, opens, clicks, forwards, complaints, unsubscribes and more are easily tracked and managed. Be a control freak, it’s OK.
|
45 |
+
- **Marketing Campaign Mapview:** With our mapview you can see who's opening your emails on what devices on an awesome, interactive visual map.
|
46 |
|
47 |
+
### [CONTACTS CRM](https://www.creativemail.com):
|
48 |
- **Contact Lists:** Within the Creative Mail Contacts CRM you can quickly and easily manage all your Contacts, Subscribers and Unsubscribes.
|
49 |
- **Contact Activity:** Drill into the purchases and behaviors of your contacts.
|
50 |
+
- **List Sources:** You’ll know where your contacts come from whether it’s a manual entry, your Jetpack forms, WooCommerce Store, or another defined source.
|
51 |
- **Custom Labels:** Further refine your marketing by adding custom labels to subscribers or customers (ex. Truck Buyers, Concert Attendee, Dog Owners, etc.).
|
52 |
|
53 |
### [IMPORT & EXPORT](https://www.creativemail.com):
|
54 |
+
- **Contacts Sync & Import:** Forget adding complex integrations between your WordPress site and your email marketing provider. With Creative Mail it all simply works with WordPress out of the box. We do the heavy lifting to sync and import your Jetpack, WordPress or WooCommerce contacts automatically.
|
55 |
+
- **Import & Export Via CSV:** From our Creative Mail Contacts CRM you can import bulk email marketing lists (limits may apply), add subscribers one by one, or export your contacts into a CSV file.
|
56 |
|
57 |
### [CAMPAIGNS](https://www.creativemail.com):
|
58 |
+
- **AI Emails:** Forget templates, let our A.I. build your email marketing campaigns for you. Pull in WordPress posts or WooCommerce products for sale and you’re good to go. Let our robots do your bidding!
|
59 |
+
- **Email Campaign Creation:** Build your email marketing campaigns in seconds from your WordPress admin dashboard.
|
60 |
+
- **Awesome Deliverability:** All email marketing campaigns are sent and delivered by the award-winning power of Constant Contact technology. We got you.
|
61 |
+
- **Automated Email Marketing:** Send multi-step email campaigns automatically, with triggers you define, whether that’s based on time or behavioral actions. (Coming Soon)
|
62 |
|
63 |
### [EMAIL LIST MANAGEMENT](https://www.creativemail.com):
|
64 |
+
- **Contact List Growth:** Creative Mail collects leads from Jetpack forms or the top WordPress lead capture forms and adds them directly to your email lists.
|
65 |
+
- **Automate Emails:** With our “Welcome” email trigger you can send a Creative Mail welcome message to new subscribers and blog readers. (Coming Soon)
|
66 |
- **Auto List Updater:** Creative Mail automatically updates your contact lists for email bounces or unsubscribes.
|
67 |
|
68 |
## CREATIVE MAIL IS:
|
71 |
1. Accessed from within your WP Admin Dashboard
|
72 |
1. Automatically syncing your contacts and building your marketing lists
|
73 |
1. Powered by the reliability superior deliverability of Constant Contact
|
74 |
+
1. Fun, which makes life way better
|
75 |
|
76 |
## TERMS OF SERVICE & PRIVACY POLICY
|
77 |
On behalf of our lawyers (seriously, they’re nice people), please feel free to review our:
|
80 |
Creative Mail by Constant Contact [Privacy Policy](https://endurance.clarip.com/privacycenter/?brand=ctct)
|
81 |
|
82 |
== Screenshots ==
|
83 |
+
1. Your all in one dashboard
|
84 |
+
2. Design awesome email campaigns with the visual editor
|
85 |
+
3. Manage your contacts and email lists, all in one place
|
86 |
+
4. Let Creative Mail handle your WooCommerce emails
|
87 |
+
5. Spice up your transactional WooCommerce store emails
|
88 |
+
6. Enhance your brand with the logomaker
|
89 |
|
90 |
== Changelog ==
|
91 |
+
* 1.1.0 - Added support for WooCommerce emails, WPFormsLite and JetPack Forms
|
92 |
* 1.0.4 - Added compatibility with PHP 5.6
|
93 |
* 1.0.3 - Small fixes in the plugin readme.
|
94 |
* 1.0.2 - Small fixes in the plugin readme.
|
src/creativemail.php
CHANGED
@@ -5,6 +5,7 @@ namespace CreativeMail;
|
|
5 |
|
6 |
use CreativeMail\Managers\AdminManager;
|
7 |
use CreativeMail\Managers\ApiManager;
|
|
|
8 |
use CreativeMail\Managers\InstanceManager;
|
9 |
use CreativeMail\Managers\IntegrationManager;
|
10 |
|
@@ -16,21 +17,19 @@ class CreativeMail
|
|
16 |
private $api_manager;
|
17 |
private $instance_manager;
|
18 |
private $integration_manager;
|
19 |
-
|
20 |
|
21 |
public function __construct() {
|
22 |
|
23 |
-
if (current_user_can('administrator'))
|
24 |
-
|
25 |
$this->admin_manager = new AdminManager();
|
26 |
-
$this->admin_manager->add_hooks();
|
27 |
-
|
28 |
}
|
29 |
|
30 |
$this->instance_manager = new InstanceManager();
|
31 |
$this->api_manager = new ApiManager();
|
32 |
$this->integration_manager = new IntegrationManager();
|
33 |
-
|
34 |
}
|
35 |
|
36 |
public function add_hooks() {
|
@@ -42,6 +41,7 @@ class CreativeMail
|
|
42 |
$this->api_manager->add_hooks();
|
43 |
$this->integration_manager->add_hooks();
|
44 |
$this->instance_manager->add_hooks();
|
|
|
45 |
}
|
46 |
|
47 |
public function get_integration_manager() {
|
@@ -56,6 +56,10 @@ class CreativeMail
|
|
56 |
return $this->api_manager;
|
57 |
}
|
58 |
|
|
|
|
|
|
|
|
|
59 |
public function get_admin_manager() {
|
60 |
return $this->admin_manager;
|
61 |
}
|
@@ -68,4 +72,4 @@ class CreativeMail
|
|
68 |
|
69 |
return self::$instance;
|
70 |
}
|
71 |
-
}
|
5 |
|
6 |
use CreativeMail\Managers\AdminManager;
|
7 |
use CreativeMail\Managers\ApiManager;
|
8 |
+
use CreativeMail\Managers\EmailManager;
|
9 |
use CreativeMail\Managers\InstanceManager;
|
10 |
use CreativeMail\Managers\IntegrationManager;
|
11 |
|
17 |
private $api_manager;
|
18 |
private $instance_manager;
|
19 |
private $integration_manager;
|
20 |
+
private $email_manager;
|
21 |
|
22 |
public function __construct() {
|
23 |
|
24 |
+
if (current_user_can('administrator'))
|
25 |
+
{
|
26 |
$this->admin_manager = new AdminManager();
|
|
|
|
|
27 |
}
|
28 |
|
29 |
$this->instance_manager = new InstanceManager();
|
30 |
$this->api_manager = new ApiManager();
|
31 |
$this->integration_manager = new IntegrationManager();
|
32 |
+
$this->email_manager = new EmailManager();
|
33 |
}
|
34 |
|
35 |
public function add_hooks() {
|
41 |
$this->api_manager->add_hooks();
|
42 |
$this->integration_manager->add_hooks();
|
43 |
$this->instance_manager->add_hooks();
|
44 |
+
$this->email_manager->add_hooks();
|
45 |
}
|
46 |
|
47 |
public function get_integration_manager() {
|
56 |
return $this->api_manager;
|
57 |
}
|
58 |
|
59 |
+
public function get_email_manager() {
|
60 |
+
return $this->email_manager;
|
61 |
+
}
|
62 |
+
|
63 |
public function get_admin_manager() {
|
64 |
return $this->admin_manager;
|
65 |
}
|
72 |
|
73 |
return self::$instance;
|
74 |
}
|
75 |
+
}
|
src/helpers/options-helper.php
CHANGED
@@ -2,6 +2,8 @@
|
|
2 |
|
3 |
namespace CreativeMail\Helpers;
|
4 |
|
|
|
|
|
5 |
/**
|
6 |
* Class CE4WP_OptionsHelper
|
7 |
* Exposes a wrapper around all the options that we register within the plugin.
|
@@ -59,6 +61,64 @@ class OptionsHelper
|
|
59 |
return get_option(CE4WP_INSTANCE_HANDSHAKE_EXPIRATION, null);
|
60 |
}
|
61 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
62 |
/**
|
63 |
* Gets the assigned instance id.
|
64 |
* @return int|null
|
@@ -135,6 +195,71 @@ class OptionsHelper
|
|
135 |
update_option(CE4WP_ACTIVATED_PLUGINS, $plugins);
|
136 |
}
|
137 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
138 |
/**
|
139 |
* Gets an int value representing when the user did accept the terms on our consent screen.
|
140 |
* @return int|null
|
@@ -152,6 +277,15 @@ class OptionsHelper
|
|
152 |
update_option(CE4WP_ACCEPTED_CONSENT, time());
|
153 |
}
|
154 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
155 |
/**
|
156 |
* Will clear all the registered options for this plugin.
|
157 |
* Only the Unique Id won't be cleared so that we can restore the link when the plugin is reactivated.
|
@@ -165,6 +299,12 @@ class OptionsHelper
|
|
165 |
delete_option(CE4WP_CONNECTED_ACCOUNT_ID);
|
166 |
delete_option(CE4WP_ACTIVATED_PLUGINS);
|
167 |
delete_option(CE4WP_ACCEPTED_CONSENT);
|
|
|
|
|
|
|
|
|
|
|
|
|
168 |
|
169 |
if($clear_all === true) {
|
170 |
delete_option(CE4WP_INSTANCE_UUID_KEY);
|
2 |
|
3 |
namespace CreativeMail\Helpers;
|
4 |
|
5 |
+
use stdClass;
|
6 |
+
|
7 |
/**
|
8 |
* Class CE4WP_OptionsHelper
|
9 |
* Exposes a wrapper around all the options that we register within the plugin.
|
61 |
return get_option(CE4WP_INSTANCE_HANDSHAKE_EXPIRATION, null);
|
62 |
}
|
63 |
|
64 |
+
/**
|
65 |
+
* Gets the consumer API key that can be used to interact with the Creative Mail platform.
|
66 |
+
* @return string|null
|
67 |
+
*/
|
68 |
+
public static function get_wc_consumer_key()
|
69 |
+
{
|
70 |
+
return EncryptionHelper::get_option(CE4WP_WC_API_CONSUMER_KEY, null);
|
71 |
+
}
|
72 |
+
|
73 |
+
/**
|
74 |
+
* Sets the consumer key that can be used to interact with the Creative Mail platform.
|
75 |
+
*
|
76 |
+
* @param $value string
|
77 |
+
*
|
78 |
+
* @throws \Defuse\Crypto\Exception\BadFormatException
|
79 |
+
* @throws \Defuse\Crypto\Exception\EnvironmentIsBrokenException
|
80 |
+
*/
|
81 |
+
public static function set_wc_consumer_key($value)
|
82 |
+
{
|
83 |
+
EncryptionHelper::add_option(CE4WP_WC_API_CONSUMER_KEY, $value);
|
84 |
+
}
|
85 |
+
|
86 |
+
/**
|
87 |
+
* Deletes the consumer key.
|
88 |
+
* @return int|null
|
89 |
+
*/
|
90 |
+
public static function delete_wc_consumer_key()
|
91 |
+
{
|
92 |
+
return delete_option(CE4WP_WC_API_CONSUMER_KEY);
|
93 |
+
}
|
94 |
+
|
95 |
+
/**
|
96 |
+
* Gets the assigned api key id.
|
97 |
+
* @return int|null
|
98 |
+
*/
|
99 |
+
public static function get_wc_api_key_id()
|
100 |
+
{
|
101 |
+
return get_option(CE4WP_WC_API_KEY_ID, null);
|
102 |
+
}
|
103 |
+
|
104 |
+
/**
|
105 |
+
* Sets the assigned api key id that is generated when connecting this WP instance to the Creative Mail account.
|
106 |
+
* @param $value int
|
107 |
+
*/
|
108 |
+
public static function set_wc_api_key_id($value)
|
109 |
+
{
|
110 |
+
add_option(CE4WP_WC_API_KEY_ID, $value);
|
111 |
+
}
|
112 |
+
|
113 |
+
/**
|
114 |
+
* Deletes the api key id.
|
115 |
+
* @return int|null
|
116 |
+
*/
|
117 |
+
public static function delete_wc_api_key_id()
|
118 |
+
{
|
119 |
+
return delete_option(CE4WP_WC_API_KEY_ID);
|
120 |
+
}
|
121 |
+
|
122 |
/**
|
123 |
* Gets the assigned instance id.
|
124 |
* @return int|null
|
195 |
update_option(CE4WP_ACTIVATED_PLUGINS, $plugins);
|
196 |
}
|
197 |
|
198 |
+
/**
|
199 |
+
* @return string|array
|
200 |
+
*/
|
201 |
+
public static function get_managed_email_notifications() {
|
202 |
+
global $wpdb;
|
203 |
+
$rows = $wpdb->get_results( $wpdb->prepare( "SELECT option_name, option_value FROM $wpdb->options WHERE option_name like %s", CE4WP_MANAGED_EMAIL_NOTIFICATIONS . '%' ) );
|
204 |
+
$result = array();
|
205 |
+
foreach ( $rows as $row ) {
|
206 |
+
$name = $row->option_name;
|
207 |
+
if ( $name === CE4WP_MANAGED_EMAIL_NOTIFICATIONS ) {
|
208 |
+
//convert old to new format
|
209 |
+
return self::convert_managed_email_notifications($row->option_value);
|
210 |
+
}
|
211 |
+
|
212 |
+
$item = new stdClass();
|
213 |
+
$item->name = str_replace( CE4WP_MANAGED_EMAIL_NOTIFICATIONS . '_', '', $name );
|
214 |
+
$item->active =$row->option_value == 'true';
|
215 |
+
array_push( $result, $item);
|
216 |
+
}
|
217 |
+
|
218 |
+
return $result;
|
219 |
+
}
|
220 |
+
|
221 |
+
/**
|
222 |
+
* One time converts the email notifications to the new format
|
223 |
+
* @return array
|
224 |
+
*/
|
225 |
+
private static function convert_managed_email_notifications($items) {
|
226 |
+
$items = maybe_unserialize($items);
|
227 |
+
if ( empty( $items ) || $items == null ) {
|
228 |
+
return array();
|
229 |
+
}
|
230 |
+
|
231 |
+
$result = array();
|
232 |
+
foreach ( $items as $item ) {
|
233 |
+
if ( property_exists( $item, 'name' ) ) {
|
234 |
+
OptionsHelper::set_managed_email_notification( $item->name, $item->active == true ? 'true' : 'false' );
|
235 |
+
array_push( $result, $item );
|
236 |
+
}
|
237 |
+
}
|
238 |
+
|
239 |
+
delete_option(CE4WP_MANAGED_EMAIL_NOTIFICATIONS);
|
240 |
+
return $result;
|
241 |
+
}
|
242 |
+
|
243 |
+
/**
|
244 |
+
* Deletes all the email notifications options
|
245 |
+
*/
|
246 |
+
private static function delete_managed_email_notifications() {
|
247 |
+
$managed_notifications = self::get_managed_email_notifications();
|
248 |
+
foreach ( $managed_notifications as $item ) {
|
249 |
+
if ( property_exists( $item, 'name' ) ) {
|
250 |
+
delete_option(CE4WP_MANAGED_EMAIL_NOTIFICATIONS . '_' . $item->name);
|
251 |
+
}
|
252 |
+
}
|
253 |
+
}
|
254 |
+
|
255 |
+
/**
|
256 |
+
* @param $data
|
257 |
+
*/
|
258 |
+
public static function set_managed_email_notification($name, $active)
|
259 |
+
{
|
260 |
+
update_option(CE4WP_MANAGED_EMAIL_NOTIFICATIONS . '_' . $name, $active);
|
261 |
+
}
|
262 |
+
|
263 |
/**
|
264 |
* Gets an int value representing when the user did accept the terms on our consent screen.
|
265 |
* @return int|null
|
277 |
update_option(CE4WP_ACCEPTED_CONSENT, time());
|
278 |
}
|
279 |
|
280 |
+
/**
|
281 |
+
* Gets an string value representing who referred this customer
|
282 |
+
* @return string|null
|
283 |
+
*/
|
284 |
+
public static function get_referred_by()
|
285 |
+
{
|
286 |
+
return get_option(CE4WP_REFERRED_BY, null);
|
287 |
+
}
|
288 |
+
|
289 |
/**
|
290 |
* Will clear all the registered options for this plugin.
|
291 |
* Only the Unique Id won't be cleared so that we can restore the link when the plugin is reactivated.
|
299 |
delete_option(CE4WP_CONNECTED_ACCOUNT_ID);
|
300 |
delete_option(CE4WP_ACTIVATED_PLUGINS);
|
301 |
delete_option(CE4WP_ACCEPTED_CONSENT);
|
302 |
+
delete_option(CE4WP_WC_API_KEY_ID);
|
303 |
+
delete_option(CE4WP_WC_API_CONSUMER_KEY);
|
304 |
+
delete_option(CE4WP_INSTANCE_HANDSHAKE_TOKEN);
|
305 |
+
delete_option(CE4WP_INSTANCE_HANDSHAKE_EXPIRATION);
|
306 |
+
delete_option(CE4WP_MANAGED_EMAIL_NOTIFICATIONS);
|
307 |
+
self::delete_managed_email_notifications();
|
308 |
|
309 |
if($clear_all === true) {
|
310 |
delete_option(CE4WP_INSTANCE_UUID_KEY);
|
src/managers/admin-manager.php
CHANGED
@@ -2,6 +2,7 @@
|
|
2 |
|
3 |
namespace CreativeMail\Managers;
|
4 |
|
|
|
5 |
use CreativeMail\Helpers\EnvironmentHelper;
|
6 |
use CreativeMail\Helpers\OptionsHelper;
|
7 |
use CreativeMail\Helpers\SsoHelper;
|
@@ -49,6 +50,7 @@ class AdminManager
|
|
49 |
{
|
50 |
add_action('admin_menu', array( $this, 'build_menu' ));
|
51 |
add_action('admin_enqueue_scripts', array( $this, 'add_assets' ));
|
|
|
52 |
}
|
53 |
|
54 |
/**
|
@@ -88,6 +90,15 @@ class AdminManager
|
|
88 |
}
|
89 |
}
|
90 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
91 |
/**
|
92 |
* Renders the onboarding flow.
|
93 |
*/
|
2 |
|
3 |
namespace CreativeMail\Managers;
|
4 |
|
5 |
+
use CreativeMail\CreativeMail;
|
6 |
use CreativeMail\Helpers\EnvironmentHelper;
|
7 |
use CreativeMail\Helpers\OptionsHelper;
|
8 |
use CreativeMail\Helpers\SsoHelper;
|
50 |
{
|
51 |
add_action('admin_menu', array( $this, 'build_menu' ));
|
52 |
add_action('admin_enqueue_scripts', array( $this, 'add_assets' ));
|
53 |
+
add_action('admin_notices', array($this, 'add_admin_notices' ));
|
54 |
}
|
55 |
|
56 |
/**
|
90 |
}
|
91 |
}
|
92 |
|
93 |
+
public function add_admin_notices() {
|
94 |
+
if (CreativeMail::get_instance()->get_integration_manager()->is_plugin_active('woocommerce')) {
|
95 |
+
if ( ! CreativeMail::get_instance()->get_integration_manager()->get_permalinks_enabled() ) {
|
96 |
+
print( '<div class="notice notice-error is-dismissible"><p>Ohoh, pretty permalinks are disabled. To enable the CreativeMail WooCommerce integration <a href="/wp-admin/options-permalink.php">please update your permalink settings</a>.</p></div>');
|
97 |
+
return;
|
98 |
+
}
|
99 |
+
}
|
100 |
+
}
|
101 |
+
|
102 |
/**
|
103 |
* Renders the onboarding flow.
|
104 |
*/
|
src/managers/api-manager.php
CHANGED
@@ -5,11 +5,14 @@ namespace CreativeMail\Managers;
|
|
5 |
|
6 |
use CreativeMail\CreativeMail;
|
7 |
use CreativeMail\Helpers\OptionsHelper;
|
|
|
8 |
use CreativeMail\Modules\WooCommerce\Models\WCProductModel;
|
|
|
9 |
use CreativeMail\Modules\Blog\Models\BlogInformation;
|
10 |
use CreativeMail\Modules\Blog\Models\BlogPost;
|
11 |
use CreativeMail\Modules\Blog\Models\BlogAttachment;
|
12 |
use WP_Error;
|
|
|
13 |
use WP_REST_Response;
|
14 |
|
15 |
/**
|
@@ -18,10 +21,21 @@ use WP_REST_Response;
|
|
18 |
*/
|
19 |
class ApiManager
|
20 |
{
|
21 |
-
const
|
|
|
|
|
|
|
|
|
|
|
|
|
22 |
|
23 |
function __construct()
|
24 |
{
|
|
|
|
|
|
|
|
|
|
|
25 |
}
|
26 |
|
27 |
/**
|
@@ -30,58 +44,121 @@ class ApiManager
|
|
30 |
public function add_hooks() {
|
31 |
|
32 |
add_action( 'rest_api_init', array($this, 'add_rest_endpoints'));
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
33 |
|
|
|
34 |
}
|
35 |
|
36 |
public function add_rest_endpoints() {
|
37 |
// Add the endpoint to handle the callback
|
38 |
$routes = array (
|
39 |
array (
|
40 |
-
|
41 |
-
|
42 |
-
|
43 |
-
|
44 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
45 |
),
|
46 |
array (
|
47 |
-
|
48 |
-
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
-
foreach ($plugins as $activePlugin) {
|
53 |
-
array_push($result, array(
|
54 |
-
'name' => $activePlugin->get_name(),
|
55 |
-
'slug' => $activePlugin->get_slug()
|
56 |
-
));
|
57 |
}
|
58 |
|
59 |
-
|
|
|
60 |
}
|
61 |
),
|
62 |
array (
|
63 |
-
|
64 |
-
|
65 |
-
|
66 |
-
|
67 |
}
|
68 |
),
|
69 |
array (
|
70 |
-
|
71 |
-
|
72 |
-
|
73 |
-
'require_api_key' => true,
|
74 |
-
'callback' => function() {
|
75 |
do_action(CE4WP_SYNCHRONIZE_ACTION, 250);
|
76 |
-
return new WP_REST_Response(null, 200);
|
77 |
}
|
78 |
),
|
79 |
array (
|
80 |
-
|
81 |
-
|
82 |
-
|
83 |
-
|
84 |
-
|
|
|
|
|
|
|
|
|
|
|
85 |
$productData = array();
|
86 |
if (in_array('woocommerce/woocommerce.php', apply_filters('active_plugins', get_option('active_plugins'))))
|
87 |
{
|
@@ -93,24 +170,20 @@ class ApiManager
|
|
93 |
array_push($productData, new WCProductModel($product->get_data()));
|
94 |
}
|
95 |
}
|
96 |
-
return new WP_REST_Response($productData, 200);
|
97 |
}
|
98 |
),
|
99 |
array (
|
100 |
-
|
101 |
-
|
102 |
-
|
103 |
-
|
104 |
-
'callback' => function() {
|
105 |
-
return new WP_REST_Response(new BlogInformation(), 200);
|
106 |
}
|
107 |
),
|
108 |
array (
|
109 |
-
|
110 |
-
|
111 |
-
|
112 |
-
'require_api_key' => true,
|
113 |
-
'callback' => function() {
|
114 |
$postData = array();
|
115 |
|
116 |
$posts = get_posts(array(
|
@@ -122,15 +195,13 @@ class ApiManager
|
|
122 |
array_push($postData, new BlogPost($post));
|
123 |
}
|
124 |
|
125 |
-
return new WP_REST_Response($postData, 200);
|
126 |
}
|
127 |
),
|
128 |
array (
|
129 |
-
|
130 |
-
|
131 |
-
|
132 |
-
'require_api_key' => true,
|
133 |
-
'callback' => function() {
|
134 |
$attachmentData = array();
|
135 |
$attachments = get_posts(array(
|
136 |
'post_type' => 'attachment',
|
@@ -144,7 +215,7 @@ class ApiManager
|
|
144 |
array_push($attachmentData, new BlogAttachment($attachment));
|
145 |
}
|
146 |
|
147 |
-
return new WP_REST_Response($attachmentData, 200);
|
148 |
}
|
149 |
)
|
150 |
);
|
@@ -154,6 +225,70 @@ class ApiManager
|
|
154 |
}
|
155 |
}
|
156 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
157 |
/**
|
158 |
* Registers a route to the WP Rest endpoints for this plugin.
|
159 |
* @param array $route
|
@@ -161,54 +296,237 @@ class ApiManager
|
|
161 |
private function register_route(array $route) {
|
162 |
|
163 |
// Make sure the route is valid
|
164 |
-
$path = $route[
|
165 |
-
$methods = $route[
|
166 |
-
$callback = $route[
|
167 |
-
|
168 |
-
|
|
|
|
|
|
|
169 |
|
170 |
// Make sure we at least have a path
|
171 |
if (empty($path)) return;
|
172 |
|
173 |
-
// Skip the route if we are not in admin mode and the route should only be available in admin mode.
|
174 |
-
$is_admin = current_user_can('administrator');
|
175 |
-
if($require_wp_admin === true && !$is_admin) {
|
176 |
-
return;
|
177 |
-
}
|
178 |
-
|
179 |
// If we don't have a method, assume it is GET
|
180 |
if(empty($methods)) {
|
181 |
$methods = 'GET';
|
182 |
}
|
183 |
|
184 |
$arguments = array(
|
185 |
-
|
186 |
-
|
|
|
187 |
);
|
188 |
|
189 |
-
$
|
190 |
-
|
191 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
192 |
}
|
193 |
|
194 |
-
|
195 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
196 |
}
|
197 |
|
|
|
198 |
/**
|
199 |
-
|
200 |
-
|
201 |
-
|
202 |
-
|
203 |
-
public function
|
204 |
-
|
205 |
-
|
206 |
-
$
|
207 |
-
|
208 |
-
return true;
|
209 |
}
|
210 |
|
211 |
-
|
|
|
212 |
}
|
213 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
214 |
}
|
5 |
|
6 |
use CreativeMail\CreativeMail;
|
7 |
use CreativeMail\Helpers\OptionsHelper;
|
8 |
+
use CreativeMail\Modules\Api\Processes\ApiBackgroundProcess;
|
9 |
use CreativeMail\Modules\WooCommerce\Models\WCProductModel;
|
10 |
+
use CreativeMail\Modules\WooCommerce\Models\WCInformationModel;
|
11 |
use CreativeMail\Modules\Blog\Models\BlogInformation;
|
12 |
use CreativeMail\Modules\Blog\Models\BlogPost;
|
13 |
use CreativeMail\Modules\Blog\Models\BlogAttachment;
|
14 |
use WP_Error;
|
15 |
+
use WP_REST_Request;
|
16 |
use WP_REST_Response;
|
17 |
|
18 |
/**
|
21 |
*/
|
22 |
class ApiManager
|
23 |
{
|
24 |
+
const API_NAMESPACE = "creativemail/v1";
|
25 |
+
const ROUTE_METHODS = 'methods';
|
26 |
+
const ROUTE_PATH = 'path';
|
27 |
+
const ROUTE_CALLBACK = 'callback';
|
28 |
+
const ROUTE_PERMISSION_CALLBACK = 'permission_callback';
|
29 |
+
const HTTP_STATUS = 'status';
|
30 |
+
private $api_background_process;
|
31 |
|
32 |
function __construct()
|
33 |
{
|
34 |
+
$this->api_background_process = new ApiBackgroundProcess();
|
35 |
+
}
|
36 |
+
|
37 |
+
public function get_api_background_process() {
|
38 |
+
return $this->api_background_process;
|
39 |
}
|
40 |
|
41 |
/**
|
44 |
public function add_hooks() {
|
45 |
|
46 |
add_action( 'rest_api_init', array($this, 'add_rest_endpoints'));
|
47 |
+
}
|
48 |
+
|
49 |
+
public function validate_api_key() {
|
50 |
+
if ( ! array_key_exists( "HTTP_X_API_KEY", $_SERVER ) ) {
|
51 |
+
return new WP_Error( 'rest_forbidden', __( 'Sorry, you are not allowed to do that.' ), array( self::HTTP_STATUS => 401 ) );
|
52 |
+
}
|
53 |
+
|
54 |
+
$key = OptionsHelper::get_instance_api_key();
|
55 |
+
$apiKey = $_SERVER["HTTP_X_API_KEY"];
|
56 |
+
// verify that api key is valid
|
57 |
+
if ( $apiKey === $key ) {
|
58 |
+
return true;
|
59 |
+
}
|
60 |
+
|
61 |
+
return new WP_Error( 'rest_forbidden', __( 'Sorry, you are not allowed to do that.' ), array( self::HTTP_STATUS => 401 ) );
|
62 |
+
}
|
63 |
+
|
64 |
+
public function validate_callback() {
|
65 |
+
if ( ! array_key_exists( "HTTP_X_API_KEY", $_SERVER ) ) {
|
66 |
+
return new WP_Error( 'rest_forbidden', __( 'Sorry, you are not allowed to do that.' ), array( self::HTTP_STATUS => 401 ) );
|
67 |
+
}
|
68 |
+
|
69 |
+
$apiKey = $_SERVER["HTTP_X_API_KEY"];
|
70 |
+
// Verify handshake expiration
|
71 |
+
$expiration = OptionsHelper::get_handshake_expiration();
|
72 |
+
if ( $expiration === null || $expiration < time() ) {
|
73 |
+
return new WP_Error( 'rest_unauthorized', 'Unauthorized', array( self::HTTP_STATUS => 401 ) );
|
74 |
+
}
|
75 |
+
|
76 |
+
// Verify handshake
|
77 |
+
if ( $apiKey === OptionsHelper::get_handshake_token() ) {
|
78 |
+
return true;
|
79 |
+
}
|
80 |
|
81 |
+
return new WP_Error( 'rest_unauthorized', 'Unauthorized', array( self::HTTP_STATUS => 401 ) );
|
82 |
}
|
83 |
|
84 |
public function add_rest_endpoints() {
|
85 |
// Add the endpoint to handle the callback
|
86 |
$routes = array (
|
87 |
array (
|
88 |
+
self::ROUTE_PATH => '/callback',
|
89 |
+
self::ROUTE_METHODS => 'POST',
|
90 |
+
self::ROUTE_CALLBACK => array(CreativeMail::get_instance()->get_instance_manager(), 'handle_callback'),
|
91 |
+
self::ROUTE_PERMISSION_CALLBACK => function() {
|
92 |
+
return $this->validate_callback();
|
93 |
+
}
|
94 |
+
),
|
95 |
+
array (
|
96 |
+
self::ROUTE_PATH => '/available_plugins',
|
97 |
+
self::ROUTE_METHODS => 'GET',
|
98 |
+
self::ROUTE_CALLBACK => function() {
|
99 |
+
return $this->modify_response($this->get_plugin_info(true));
|
100 |
+
}
|
101 |
+
),
|
102 |
+
array (
|
103 |
+
self::ROUTE_PATH => '/available_plugins',
|
104 |
+
self::ROUTE_METHODS => 'POST',
|
105 |
+
self::ROUTE_CALLBACK => function($request) {
|
106 |
+
CreativeMail::get_instance()->get_integration_manager()->set_activated_plugins(json_decode($request->get_body()));
|
107 |
+
}
|
108 |
+
),
|
109 |
+
array (
|
110 |
+
self::ROUTE_PATH => '/plugins',
|
111 |
+
self::ROUTE_METHODS => 'GET',
|
112 |
+
self::ROUTE_CALLBACK => function() {
|
113 |
+
return $this->modify_response($this->get_plugin_info(false));
|
114 |
+
}
|
115 |
+
),
|
116 |
+
array (
|
117 |
+
self::ROUTE_PATH => '/managed_email_notifications',
|
118 |
+
self::ROUTE_METHODS => 'GET',
|
119 |
+
self::ROUTE_CALLBACK => function() {
|
120 |
+
$result = CreativeMail::get_instance()->get_email_manager()->get_managed_email_notifications();
|
121 |
+
return $this->modify_response(new WP_REST_Response($result, 200));
|
122 |
+
}
|
123 |
),
|
124 |
array (
|
125 |
+
self::ROUTE_PATH => '/managed_email_notifications',
|
126 |
+
self::ROUTE_METHODS => 'POST',
|
127 |
+
self::ROUTE_CALLBACK => function($request) {
|
128 |
+
if(!CreativeMail::get_instance()->get_integration_manager()->get_permalinks_enabled()) {
|
129 |
+
return $this->modify_response(new WP_REST_Response( array( 'message' => 'Please enable pretty permalinks in the WordPress settings.'), 400 ));
|
|
|
|
|
|
|
|
|
|
|
130 |
}
|
131 |
|
132 |
+
$result = CreativeMail::get_instance()->get_email_manager()->set_managed_email_notifications(json_decode($request->get_body()));
|
133 |
+
return $this->modify_response(new WP_REST_Response($result, 200));
|
134 |
}
|
135 |
),
|
136 |
array (
|
137 |
+
self::ROUTE_PATH => '/wc_key',
|
138 |
+
self::ROUTE_METHODS => 'GET',
|
139 |
+
self::ROUTE_CALLBACK => function() {
|
140 |
+
return $this->modify_response($this->get_wc_keys());
|
141 |
}
|
142 |
),
|
143 |
array (
|
144 |
+
self::ROUTE_PATH => '/synchronize',
|
145 |
+
self::ROUTE_METHODS => 'POST',
|
146 |
+
self::ROUTE_CALLBACK => function() {
|
|
|
|
|
147 |
do_action(CE4WP_SYNCHRONIZE_ACTION, 250);
|
148 |
+
return $this->modify_response(new WP_REST_Response(null, 200));
|
149 |
}
|
150 |
),
|
151 |
array (
|
152 |
+
self::ROUTE_PATH => '/wc_information',
|
153 |
+
self::ROUTE_METHODS => 'GET',
|
154 |
+
self::ROUTE_CALLBACK => function() {
|
155 |
+
return $this->modify_response(new WP_REST_Response(new WCInformationModel(), 200));
|
156 |
+
}
|
157 |
+
),
|
158 |
+
array (
|
159 |
+
self::ROUTE_PATH => '/wc_products',
|
160 |
+
self::ROUTE_METHODS => 'GET',
|
161 |
+
self::ROUTE_CALLBACK => function() {
|
162 |
$productData = array();
|
163 |
if (in_array('woocommerce/woocommerce.php', apply_filters('active_plugins', get_option('active_plugins'))))
|
164 |
{
|
170 |
array_push($productData, new WCProductModel($product->get_data()));
|
171 |
}
|
172 |
}
|
173 |
+
return $this->modify_response(new WP_REST_Response($productData, 200));
|
174 |
}
|
175 |
),
|
176 |
array (
|
177 |
+
self::ROUTE_PATH => '/blog_information',
|
178 |
+
self::ROUTE_METHODS => 'GET',
|
179 |
+
self::ROUTE_CALLBACK => function() {
|
180 |
+
return $this->modify_response(new WP_REST_Response(new BlogInformation(), 200));
|
|
|
|
|
181 |
}
|
182 |
),
|
183 |
array (
|
184 |
+
self::ROUTE_PATH => '/wp_posts',
|
185 |
+
self::ROUTE_METHODS => 'GET',
|
186 |
+
self::ROUTE_CALLBACK => function() {
|
|
|
|
|
187 |
$postData = array();
|
188 |
|
189 |
$posts = get_posts(array(
|
195 |
array_push($postData, new BlogPost($post));
|
196 |
}
|
197 |
|
198 |
+
return $this->modify_response(new WP_REST_Response($postData, 200));
|
199 |
}
|
200 |
),
|
201 |
array (
|
202 |
+
self::ROUTE_PATH => '/images',
|
203 |
+
self::ROUTE_METHODS => 'GET',
|
204 |
+
self::ROUTE_CALLBACK => function() {
|
|
|
|
|
205 |
$attachmentData = array();
|
206 |
$attachments = get_posts(array(
|
207 |
'post_type' => 'attachment',
|
215 |
array_push($attachmentData, new BlogAttachment($attachment));
|
216 |
}
|
217 |
|
218 |
+
return $this->modify_response(new WP_REST_Response($attachmentData, 200));
|
219 |
}
|
220 |
)
|
221 |
);
|
225 |
}
|
226 |
}
|
227 |
|
228 |
+
private function get_plugin_info($onlyActivePlugins) {
|
229 |
+
$result = array();
|
230 |
+
$activePlugins = CreativeMail::get_instance()->get_integration_manager()->get_active_plugins();
|
231 |
+
if ( $onlyActivePlugins === true ) {
|
232 |
+
foreach ( $activePlugins as $activePlugin ) {
|
233 |
+
array_push( $result, array(
|
234 |
+
'name' => $activePlugin->get_name(),
|
235 |
+
'slug' => $activePlugin->get_slug()
|
236 |
+
) );
|
237 |
+
}
|
238 |
+
} else {
|
239 |
+
$allPlugins = CreativeMail::get_instance()->get_integration_manager()->get_supported_integrations();
|
240 |
+
$activatedPlugins = CreativeMail::get_instance()->get_integration_manager()->get_activated_plugins();
|
241 |
+
foreach ( $allPlugins as $plugin ) {
|
242 |
+
array_push( $result, array(
|
243 |
+
'name' => $plugin->get_name(),
|
244 |
+
'slug' => $plugin->get_slug(),
|
245 |
+
'installed' => in_array( $plugin, $activePlugins, true ) !== false,
|
246 |
+
'activated' => array_search( $plugin->get_slug(), $activatedPlugins, true ) !== false,
|
247 |
+
) );
|
248 |
+
}
|
249 |
+
}
|
250 |
+
|
251 |
+
return new WP_REST_Response( $result, 200 );
|
252 |
+
}
|
253 |
+
|
254 |
+
/**
|
255 |
+
* Modifies the response to disable caching
|
256 |
+
*
|
257 |
+
* @param WP_REST_Response $response The endpoint its response
|
258 |
+
* @return WP_REST_Response
|
259 |
+
*/
|
260 |
+
private function modify_response($response) {
|
261 |
+
if ( isset( $response ) && $response instanceof WP_REST_Response ) {
|
262 |
+
$response->set_headers( array( 'Cache-Control' => 'no-cache' ) );
|
263 |
+
}
|
264 |
+
|
265 |
+
return $response;
|
266 |
+
}
|
267 |
+
|
268 |
+
private function get_wc_keys() {
|
269 |
+
$wcKey = CreativeMail::get_instance()->get_api_manager()->get_or_generate_key();
|
270 |
+
$key = sha1(OptionsHelper::get_instance_api_key() . OptionsHelper::get_instance_uuid());
|
271 |
+
$salt = openssl_random_pseudo_bytes( openssl_cipher_iv_length( 'aes-256-cbc' ) );
|
272 |
+
$salted = '';
|
273 |
+
$dx = '';
|
274 |
+
while ( strlen( $salted ) < 48 ) {
|
275 |
+
$dx = md5( $dx . $key . $salt, true );
|
276 |
+
$salted .= $dx;
|
277 |
+
}
|
278 |
+
$key = substr( $salted, 0, 32 );
|
279 |
+
$iv = substr( $salted, 32, 16 );
|
280 |
+
$cs = openssl_encrypt( $wcKey->consumer_secret, 'aes-256-cbc', $key, OPENSSL_RAW_DATA, $iv );
|
281 |
+
$ck = openssl_encrypt( $wcKey->consumer_key, 'aes-256-cbc', $key, OPENSSL_RAW_DATA, $iv );
|
282 |
+
|
283 |
+
$result = new \stdClass();
|
284 |
+
$result->salt = bin2hex( $salt );
|
285 |
+
$result->secret = base64_encode( $cs );
|
286 |
+
$result->key = base64_encode( $ck );
|
287 |
+
$result->version = '1';
|
288 |
+
|
289 |
+
return new WP_REST_Response( $result, 200 );
|
290 |
+
}
|
291 |
+
|
292 |
/**
|
293 |
* Registers a route to the WP Rest endpoints for this plugin.
|
294 |
* @param array $route
|
296 |
private function register_route(array $route) {
|
297 |
|
298 |
// Make sure the route is valid
|
299 |
+
$path = $route[self::ROUTE_PATH];
|
300 |
+
$methods = $route[self::ROUTE_METHODS];
|
301 |
+
$callback = $route[self::ROUTE_CALLBACK];
|
302 |
+
if ((array_key_exists(self::ROUTE_PERMISSION_CALLBACK, $route)) ) {
|
303 |
+
$permission_callback = $route[self::ROUTE_PERMISSION_CALLBACK];
|
304 |
+
}else {
|
305 |
+
$permission_callback = array( $this, 'validate_api_key' );
|
306 |
+
}
|
307 |
|
308 |
// Make sure we at least have a path
|
309 |
if (empty($path)) return;
|
310 |
|
|
|
|
|
|
|
|
|
|
|
|
|
311 |
// If we don't have a method, assume it is GET
|
312 |
if(empty($methods)) {
|
313 |
$methods = 'GET';
|
314 |
}
|
315 |
|
316 |
$arguments = array(
|
317 |
+
self::ROUTE_METHODS => $methods,
|
318 |
+
self::ROUTE_CALLBACK => $callback,
|
319 |
+
self::ROUTE_PERMISSION_CALLBACK => $permission_callback
|
320 |
);
|
321 |
|
322 |
+
register_rest_route(self::API_NAMESPACE, $path, $arguments);
|
323 |
+
}
|
324 |
+
|
325 |
+
/**
|
326 |
+
* Refreshes the WC REST API key.
|
327 |
+
*
|
328 |
+
* @since 1.1.0
|
329 |
+
*
|
330 |
+
* @param int $user_id WordPress user ID
|
331 |
+
* @return object|bool
|
332 |
+
* @throws Exception
|
333 |
+
*/
|
334 |
+
public function refresh_key( $user_id = null ) {
|
335 |
+
|
336 |
+
$this->revoke_key();
|
337 |
+
|
338 |
+
return $this->create_key( $user_id );
|
339 |
+
}
|
340 |
+
|
341 |
+
|
342 |
+
/**
|
343 |
+
* Generates a WC REST API key for Jilt to use.
|
344 |
+
*
|
345 |
+
* @since 1.1.0
|
346 |
+
*
|
347 |
+
* @param int $user_id WordPress user ID
|
348 |
+
* @return object
|
349 |
+
* @throws Exception
|
350 |
+
*/
|
351 |
+
public function create_key( $user_id = null ) {
|
352 |
+
global $wpdb;
|
353 |
+
|
354 |
+
// if no user is specified, try the current user or find an eligible admin
|
355 |
+
if ( ! $user_id ) {
|
356 |
+
|
357 |
+
$user_id = get_current_user_id();
|
358 |
+
|
359 |
+
// if the current user can't manage WC, try and get the first admin
|
360 |
+
if ( ! user_can( $user_id, 'manage_woocommerce' ) ) {
|
361 |
+
|
362 |
+
$user_id = null;
|
363 |
+
|
364 |
+
$administrator_ids = get_users( array(
|
365 |
+
'role' => 'administrator',
|
366 |
+
'fields' => 'ID',
|
367 |
+
) );
|
368 |
+
|
369 |
+
foreach ( $administrator_ids as $administrator_id ) {
|
370 |
+
|
371 |
+
if ( user_can( $administrator_id, 'manage_woocommerce' ) ) {
|
372 |
+
|
373 |
+
$user_id = $administrator_id;
|
374 |
+
break;
|
375 |
+
}
|
376 |
+
}
|
377 |
+
|
378 |
+
if ( ! $user_id ) {
|
379 |
+
throw new Exception( 'No eligible users could be found' );
|
380 |
+
}
|
381 |
+
}
|
382 |
+
|
383 |
+
// otherwise, check the user that's specified
|
384 |
+
} elseif ( ! user_can( $user_id, 'manage_woocommerce' ) ) {
|
385 |
+
|
386 |
+
throw new Exception( "User {$user_id} does not have permission" );
|
387 |
+
}
|
388 |
+
|
389 |
+
$user = get_userdata( $user_id );
|
390 |
+
|
391 |
+
if ( ! $user ) {
|
392 |
+
throw new Exception( 'Invalid user' );
|
393 |
+
}
|
394 |
+
|
395 |
+
$consumer_key = 'ck_' . wc_rand_hash();
|
396 |
+
$consumer_secret = 'cs_' . wc_rand_hash();
|
397 |
+
|
398 |
+
$result = $wpdb->insert(
|
399 |
+
$wpdb->prefix . 'woocommerce_api_keys',
|
400 |
+
array(
|
401 |
+
'user_id' => $user->ID,
|
402 |
+
'description' => 'CreativeMail',
|
403 |
+
'permissions' => 'read_write',
|
404 |
+
'consumer_key' => wc_api_hash( $consumer_key ),
|
405 |
+
'consumer_secret' => $consumer_secret,
|
406 |
+
'truncated_key' => substr( $consumer_key, -7 ),
|
407 |
+
),
|
408 |
+
array(
|
409 |
+
'%d',
|
410 |
+
'%s',
|
411 |
+
'%s',
|
412 |
+
'%s',
|
413 |
+
'%s',
|
414 |
+
'%s',
|
415 |
+
)
|
416 |
+
);
|
417 |
+
|
418 |
+
if ( ! $result ) {
|
419 |
+
throw new Exception( 'The key could not be saved' );
|
420 |
}
|
421 |
|
422 |
+
$key = new \stdClass();
|
423 |
|
424 |
+
$key->key_id = $wpdb->insert_id;
|
425 |
+
$key->user_id = $user->ID;
|
426 |
+
$key->consumer_key = $consumer_key;
|
427 |
+
$key->consumer_secret = $consumer_secret;
|
428 |
+
|
429 |
+
// store the new key ID
|
430 |
+
$this->set_key_id( $key->key_id );
|
431 |
+
$this->set_consumer_key($consumer_key);
|
432 |
+
|
433 |
+
return $key;
|
434 |
}
|
435 |
|
436 |
+
|
437 |
/**
|
438 |
+
* Revokes the configured WC REST API key.
|
439 |
+
*
|
440 |
+
* @since 1.1.0
|
441 |
+
*/
|
442 |
+
public function revoke_key() {
|
443 |
+
global $wpdb;
|
444 |
+
|
445 |
+
if ( $key_id = $this->get_key_id() ) {
|
446 |
+
$wpdb->delete( $wpdb->prefix . 'woocommerce_api_keys', array( 'key_id' => $key_id ), array( '%d' ) );
|
|
|
447 |
}
|
448 |
|
449 |
+
OptionsHelper::delete_wc_api_key_id();
|
450 |
+
OptionsHelper::delete_wc_consumer_key();
|
451 |
}
|
452 |
|
453 |
+
|
454 |
+
/**
|
455 |
+
* Gets the configured WC REST API key.
|
456 |
+
*
|
457 |
+
* @since 1.1.0
|
458 |
+
*
|
459 |
+
* @return object|null
|
460 |
+
*/
|
461 |
+
public function get_key() {
|
462 |
+
global $wpdb;
|
463 |
+
|
464 |
+
$key = null;
|
465 |
+
|
466 |
+
if ( $id = $this->get_key_id() ) {
|
467 |
+
$key = $wpdb->get_row( $wpdb->prepare( "
|
468 |
+
SELECT key_id, user_id, permissions, consumer_secret
|
469 |
+
FROM {$wpdb->prefix}woocommerce_api_keys
|
470 |
+
WHERE key_id = %d
|
471 |
+
", $id ) );
|
472 |
+
|
473 |
+
if ( isset( $key ) ) {
|
474 |
+
$key->consumer_key = $this->get_consumer_key();
|
475 |
+
}
|
476 |
+
}
|
477 |
+
|
478 |
+
return $key;
|
479 |
+
}
|
480 |
+
|
481 |
+
/**
|
482 |
+
* Gets or generate the configured WC REST API key.
|
483 |
+
*
|
484 |
+
* @since 1.1.0
|
485 |
+
*
|
486 |
+
* @return object|null
|
487 |
+
*/
|
488 |
+
public function get_or_generate_key() {
|
489 |
+
$key = $this->get_key();
|
490 |
+
|
491 |
+
if ($key == null) {
|
492 |
+
$key = $this->refresh_key();
|
493 |
+
}
|
494 |
+
|
495 |
+
return $key;
|
496 |
+
}
|
497 |
+
|
498 |
+
|
499 |
+
/**
|
500 |
+
* Gets the configured WC REST API key ID.
|
501 |
+
*
|
502 |
+
* @since 1.1.0
|
503 |
+
*
|
504 |
+
* @return int
|
505 |
+
*/
|
506 |
+
public function get_key_id() {
|
507 |
+
|
508 |
+
return OptionsHelper::get_wc_api_key_id();
|
509 |
+
}
|
510 |
+
|
511 |
+
public function get_consumer_key() {
|
512 |
+
|
513 |
+
return OptionsHelper::get_wc_consumer_key();
|
514 |
+
}
|
515 |
+
|
516 |
+
/**
|
517 |
+
* Sets a WC REST API key ID.
|
518 |
+
*
|
519 |
+
* @since 1.1.0
|
520 |
+
*
|
521 |
+
* @param int $id key ID
|
522 |
+
*/
|
523 |
+
public function set_key_id( $id )
|
524 |
+
{
|
525 |
+
OptionsHelper::set_wc_api_key_id($id);
|
526 |
+
}
|
527 |
+
|
528 |
+
public function set_consumer_key( $key )
|
529 |
+
{
|
530 |
+
OptionsHelper::set_wc_consumer_key($key);
|
531 |
+
}
|
532 |
}
|
src/managers/email-manager.php
ADDED
@@ -0,0 +1,499 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
|
4 |
+
namespace CreativeMail\Managers;
|
5 |
+
|
6 |
+
use CreativeMail\CreativeMail;
|
7 |
+
use CreativeMail\Helpers\EnvironmentHelper;
|
8 |
+
use CreativeMail\Helpers\OptionsHelper;
|
9 |
+
use CreativeMail\Modules\Api\Models\ApiRequestItem;
|
10 |
+
use stdClass;
|
11 |
+
|
12 |
+
/**
|
13 |
+
* Class EmailManager
|
14 |
+
* @package CreativeMail\Managers
|
15 |
+
*/
|
16 |
+
class EmailManager
|
17 |
+
{
|
18 |
+
/** @var array email ids being managed by CreativeMail */
|
19 |
+
protected $managed_email_notifications;
|
20 |
+
|
21 |
+
public function __construct() {
|
22 |
+
|
23 |
+
}
|
24 |
+
|
25 |
+
public function add_hooks() {
|
26 |
+
// check if woocommerce is active
|
27 |
+
if (in_array('woocommerce/woocommerce.php', apply_filters('active_plugins', get_option('active_plugins'))))
|
28 |
+
{
|
29 |
+
add_action('init', array($this, 'manage_emails'));
|
30 |
+
|
31 |
+
// email settings table customizations
|
32 |
+
add_filter('woocommerce_email_setting_columns', array($this, 'customize_email_setting_columns'));
|
33 |
+
add_action('woocommerce_email_setting_column_wc_ce_status', array($this, 'render_email_status_column'));
|
34 |
+
add_action('woocommerce_email_settings_before', array($this, 'redirect_managed_email_settings_to_creative_mail'));
|
35 |
+
|
36 |
+
//woocommerce hooks
|
37 |
+
add_action( 'woocommerce_new_order', array($this, 'ce_email_notification_new_order'), 10, 2);
|
38 |
+
add_action( 'woocommerce_order_status_cancelled', array($this, 'ce_email_notification_cancelled'), 10, 2);
|
39 |
+
add_action( 'woocommerce_order_status_failed', array($this, 'ce_email_notification_failed'), 10, 2);
|
40 |
+
add_action( 'woocommerce_order_status_on-hold', array($this, 'ce_email_notification_hold'), 10, 2);
|
41 |
+
add_action( 'woocommerce_order_status_processing', array($this, 'ce_email_notification_processing'), 10, 2);
|
42 |
+
add_action( 'woocommerce_order_status_completed', array($this, 'ce_email_notification_completed'), 10, 2);
|
43 |
+
add_action( 'woocommerce_order_status_refunded', array($this, 'ce_email_notification_refunded'), 10, 2);
|
44 |
+
add_action( 'woocommerce_after_resend_order_email', array($this, 'ce_email_notification_invoice'), 10, 2);
|
45 |
+
//payment complete
|
46 |
+
add_action( 'woocommerce_payment_complete', array( $this, 'ce_email_notification_payment_complete'), 10, 1 );
|
47 |
+
//
|
48 |
+
add_action( 'woocommerce_new_customer_note', array( $this, 'ce_email_notification_new_customer_note'), 10, 2 );
|
49 |
+
//
|
50 |
+
add_action( 'woocommerce_reset_password_notification', array( $this, 'ce_email_notification_customer_reset_password' ), 10, 2 );
|
51 |
+
add_action( 'woocommerce_created_customer', array( $this, 'ce_email_notification_customer_new_account' ), 10, 3 );
|
52 |
+
// replace wc email settings
|
53 |
+
add_filter('woocommerce_email_settings', array($this, 'replace_wc_email_settings'));
|
54 |
+
add_action('woocommerce_admin_field_ce_manage_button', array($this, 'print_ce_manage_button'));
|
55 |
+
}
|
56 |
+
}
|
57 |
+
|
58 |
+
public function replace_wc_email_settings($settings)
|
59 |
+
{
|
60 |
+
$default_setting_replacement = array(
|
61 |
+
'woocommerce_email_header_image' => 'header_image',
|
62 |
+
'woocommerce_email_footer_text' => 'footer_content_text',
|
63 |
+
'woocommerce_email_base_color' => null,
|
64 |
+
'woocommerce_email_background_color' => 'background_color',
|
65 |
+
'woocommerce_email_body_background_color' => 'email_background_color',
|
66 |
+
'woocommerce_email_text_color' => 'text_color'
|
67 |
+
);
|
68 |
+
|
69 |
+
// Define options that need to be replaced
|
70 |
+
$replace = array_merge(array_keys($default_setting_replacement), array('email_template_options'));
|
71 |
+
|
72 |
+
// remove settings
|
73 |
+
foreach ($settings as $setting_key => $setting) {
|
74 |
+
if (isset($setting['id']) && in_array($setting['id'], $replace, true)) {
|
75 |
+
unset($settings[$setting_key]);
|
76 |
+
}
|
77 |
+
}
|
78 |
+
|
79 |
+
$settings[] = array(
|
80 |
+
'id' => 'ce_manage',
|
81 |
+
'type' => 'title',
|
82 |
+
'title' => __('Creative Mail', 'ce_manage_mail'),
|
83 |
+
);
|
84 |
+
|
85 |
+
$settings[] = array(
|
86 |
+
'id' => 'ce_manage_button',
|
87 |
+
'type' => 'ce_manage_button',
|
88 |
+
);
|
89 |
+
|
90 |
+
$settings[] = array(
|
91 |
+
'id' => 'ce_manage',
|
92 |
+
'type' => 'sectionend',
|
93 |
+
);
|
94 |
+
return $settings;
|
95 |
+
}
|
96 |
+
|
97 |
+
public function print_ce_manage_button($options)
|
98 |
+
{
|
99 |
+
?><tr valign="top">
|
100 |
+
<th scope="row" class="titledesc">Customize Emails</th>
|
101 |
+
<td class="forminp forminp-<?php echo sanitize_title($options['type']); ?>">
|
102 |
+
<a href="admin.php?page=creativemail">
|
103 |
+
<button type="button" class="button button-secondary" value="<?php _e('Manage', 'ce-manage-button-text'); ?>">Manage</button>
|
104 |
+
</a>
|
105 |
+
<p class="description">Manage all your email settings and templates with Creative Mail</p>
|
106 |
+
</td>
|
107 |
+
</tr><?php
|
108 |
+
}
|
109 |
+
|
110 |
+
public function get_managed_email_notifications()
|
111 |
+
{
|
112 |
+
return OptionsHelper::get_managed_email_notifications();
|
113 |
+
}
|
114 |
+
|
115 |
+
public function set_managed_email_notifications($body) {
|
116 |
+
if ( empty( $body ) || $body === null ) {
|
117 |
+
return null;
|
118 |
+
}
|
119 |
+
|
120 |
+
if ( property_exists( $body, 'name' ) ) {
|
121 |
+
$valid_names = [
|
122 |
+
'customer_completed_order',
|
123 |
+
'customer_refunded_order',
|
124 |
+
'customer_processing_order',
|
125 |
+
'customer_on_hold_order',
|
126 |
+
'customer_new_account',
|
127 |
+
'customer_reset_password',
|
128 |
+
'customer_invoice',
|
129 |
+
'customer_note'
|
130 |
+
];
|
131 |
+
if ( in_array( $body->name, $valid_names ) ) {
|
132 |
+
OptionsHelper::set_managed_email_notification( $body->name, $body->active == true ? 'true' : 'false' );
|
133 |
+
return $body;
|
134 |
+
}
|
135 |
+
}
|
136 |
+
|
137 |
+
return null;
|
138 |
+
}
|
139 |
+
|
140 |
+
/**
|
141 |
+
* Renders the custom email status column.
|
142 |
+
*
|
143 |
+
* @internal
|
144 |
+
*
|
145 |
+
* @since 1.1.0
|
146 |
+
*
|
147 |
+
* @param \WC_Email $email the email
|
148 |
+
*/
|
149 |
+
public function render_email_status_column( \WC_Email $email ) {
|
150 |
+
|
151 |
+
echo '<td class="wc-email-settings-table-status">';
|
152 |
+
|
153 |
+
if ( $this->is_email_managed( $email->id ) ) {
|
154 |
+
echo '<span class="status-creativemail tips" data-tip="' . esc_attr__( 'Managed by Creative Mail', 'creativ-email-wordpress-plugin' ) . '">' . esc_html__( 'Managed by CreativeMail', 'creativ-email-wordpress-plugin' ) . '</span>';
|
155 |
+
} elseif ( $email->is_manual() ) {
|
156 |
+
echo '<span class="status-manual tips" data-tip="' . esc_attr__( 'Manually sent', 'woocommerce' ) . '">' . esc_html__( 'Manual', 'woocommerce' ) . '</span>';
|
157 |
+
} elseif ( $email->is_enabled() ) {
|
158 |
+
echo '<span class="status-enabled tips" data-tip="' . esc_attr__( 'Enabled', 'woocommerce' ) . '">' . esc_html__( 'Yes', 'woocommerce' ) . '</span>';
|
159 |
+
} else {
|
160 |
+
echo '<span class="status-disabled tips" data-tip="' . esc_attr__( 'Disabled', 'woocommerce' ) . '">-</span>';
|
161 |
+
}
|
162 |
+
|
163 |
+
echo '</td>';
|
164 |
+
}
|
165 |
+
|
166 |
+
public function customize_email_setting_columns( $columns ) {
|
167 |
+
|
168 |
+
$column_keys = array_keys( $columns );
|
169 |
+
|
170 |
+
// replace the status column, or put at the beginning if status isn't found
|
171 |
+
$status_index = array_search( 'status', $column_keys, true );
|
172 |
+
array_splice( $column_keys, is_numeric( $status_index ) ? $status_index : 0, is_numeric( $status_index ) ? 1 : 0, 'wc_ce_status' );
|
173 |
+
|
174 |
+
$new_columns = array();
|
175 |
+
$columns['wc_ce_status'] = '';
|
176 |
+
|
177 |
+
foreach ( $column_keys as $column_key )
|
178 |
+
{
|
179 |
+
if ( isset( $columns[ $column_key ] ) ) {
|
180 |
+
$new_columns[ $column_key ] = $columns[ $column_key ];
|
181 |
+
}
|
182 |
+
}
|
183 |
+
|
184 |
+
return $new_columns;
|
185 |
+
}
|
186 |
+
|
187 |
+
public function ce_email_notification_new_customer_note($array) {
|
188 |
+
$data = new stdClass();
|
189 |
+
$data->order_id = $array['order_id'];
|
190 |
+
$data->note = $array['customer_note'];
|
191 |
+
$data->order_url = $this->get_view_order_url($data->order_id, null);
|
192 |
+
|
193 |
+
$this->execute_trigger("customer_note", $data);
|
194 |
+
}
|
195 |
+
|
196 |
+
public function ce_email_notification_customer_new_account($customer_id) {
|
197 |
+
$data = new stdClass();
|
198 |
+
$data->customer_id = $customer_id;
|
199 |
+
$data->account_url = $this->get_my_account_url();
|
200 |
+
|
201 |
+
$this->execute_trigger("customer_new_account", $data);
|
202 |
+
}
|
203 |
+
|
204 |
+
public function ce_email_notification_customer_reset_password($user_login = '', $reset_key = '') {
|
205 |
+
if ( $user_login && $reset_key ) {
|
206 |
+
$data = new stdClass();
|
207 |
+
$user = get_user_by( 'login', $user_login );
|
208 |
+
$data->customer_id = $user->ID;
|
209 |
+
$data->account_url = $this->get_my_account_url();
|
210 |
+
$data->reset_url = add_query_arg( array(
|
211 |
+
'key' => $reset_key,
|
212 |
+
'id' => $data->customer_id
|
213 |
+
), wc_get_endpoint_url( 'lost-password', '', $data->account_url ) );
|
214 |
+
|
215 |
+
$this->execute_trigger( "customer_reset_password", $data );
|
216 |
+
}
|
217 |
+
}
|
218 |
+
|
219 |
+
public function ce_email_notification_payment_complete( $order_id ) {
|
220 |
+
$data = new stdClass();
|
221 |
+
$data->order_id = $order_id;
|
222 |
+
$data->order_url = $this->get_view_order_url($order_id, null);
|
223 |
+
|
224 |
+
$this->execute_trigger("payment_received", $data);
|
225 |
+
}
|
226 |
+
|
227 |
+
public function ce_email_notification_failed($order_id, $order) {
|
228 |
+
$data = new stdClass();
|
229 |
+
$data->order_id = $order_id;
|
230 |
+
$data->order_url = $this->get_view_order_url($order_id, $order);
|
231 |
+
|
232 |
+
$this->execute_trigger("failed_order", $data);
|
233 |
+
}
|
234 |
+
public function ce_email_notification_hold($order_id, $order) {
|
235 |
+
$data = new stdClass();
|
236 |
+
$data->order_id = $order_id;
|
237 |
+
$data->order_url = $this->get_view_order_url($order_id, $order);
|
238 |
+
|
239 |
+
$this->execute_trigger("customer_on_hold_order", $data);
|
240 |
+
}
|
241 |
+
public function ce_email_notification_processing($order_id, $order) {
|
242 |
+
$data = new stdClass();
|
243 |
+
$data->order_id = $order_id;
|
244 |
+
$data->order_url = $this->get_view_order_url($order_id, $order);
|
245 |
+
|
246 |
+
$this->execute_trigger("customer_processing_order", $data);
|
247 |
+
}
|
248 |
+
public function ce_email_notification_completed($order_id, $order) {
|
249 |
+
$data = new stdClass();
|
250 |
+
$data->order_id = $order_id;
|
251 |
+
$data->order_url = $this->get_view_order_url($order_id, $order);
|
252 |
+
|
253 |
+
$this->execute_trigger("customer_completed_order", $data);
|
254 |
+
}
|
255 |
+
public function ce_email_notification_refunded($order_id, $order) {
|
256 |
+
$data = new stdClass();
|
257 |
+
$data->order_id = $order_id;
|
258 |
+
$data->order_url = $this->get_view_order_url($order_id, $order);
|
259 |
+
|
260 |
+
$this->execute_trigger("customer_refunded_order", $data);
|
261 |
+
}
|
262 |
+
public function ce_email_notification_cancelled($order_id, $order) {
|
263 |
+
$data = new stdClass();
|
264 |
+
$data->order_id = $order_id;
|
265 |
+
$data->order_url = $this->get_view_order_url($order_id, $order);
|
266 |
+
|
267 |
+
$this->execute_trigger("cancelled_order", $data);
|
268 |
+
}
|
269 |
+
|
270 |
+
public function ce_email_notification_new_order($order_id, $order) {
|
271 |
+
$data = new stdClass();
|
272 |
+
$data->order_id = $order_id;
|
273 |
+
$data->order_url = $this->get_view_order_url($order_id, $order);
|
274 |
+
|
275 |
+
$this->execute_trigger("new_order", $data);
|
276 |
+
}
|
277 |
+
|
278 |
+
public function ce_email_notification_invoice($order, $type) {
|
279 |
+
if ( $type === 'new_order' ) {
|
280 |
+
$this->ce_email_notification_new_order( $order->id, $order );
|
281 |
+
return;
|
282 |
+
}
|
283 |
+
|
284 |
+
$data = new stdClass();
|
285 |
+
$data->order_id = $order->id;
|
286 |
+
$data->order_url = $this->get_view_order_url( $order->id, $order );
|
287 |
+
|
288 |
+
$this->execute_trigger( "customer_invoice", $data );
|
289 |
+
}
|
290 |
+
|
291 |
+
public function execute_trigger($type, $data ) {
|
292 |
+
// if not managed do not trigger
|
293 |
+
if (!$this->is_email_managed($type)) {
|
294 |
+
return;
|
295 |
+
}
|
296 |
+
|
297 |
+
$item = new stdClass;
|
298 |
+
$item->type = $type;
|
299 |
+
$item->data = wp_json_encode($data);
|
300 |
+
|
301 |
+
wp_remote_post(EnvironmentHelper::get_app_gateway_url('wordpress').'/v1.0/wc/trigger', array(
|
302 |
+
'method' => 'POST',
|
303 |
+
'headers' => array(
|
304 |
+
'x-account-id' => OptionsHelper::get_connected_account_id(),
|
305 |
+
'x-api-key' => OptionsHelper::get_instance_api_key(),
|
306 |
+
'content-type' => 'application/json'
|
307 |
+
),
|
308 |
+
'body' => wp_json_encode($item)
|
309 |
+
));
|
310 |
+
}
|
311 |
+
|
312 |
+
/**
|
313 |
+
* Initializes email management.
|
314 |
+
*
|
315 |
+
* @internal
|
316 |
+
*
|
317 |
+
* @since 1.1.0
|
318 |
+
*/
|
319 |
+
public function manage_emails() {
|
320 |
+
|
321 |
+
$this->managed_email_notifications = $this->get_managed_email_notifications();
|
322 |
+
|
323 |
+
if ( empty( $this->managed_email_notifications ) || ! is_array( $this->managed_email_notifications ) ) {
|
324 |
+
return;
|
325 |
+
}
|
326 |
+
|
327 |
+
// disable managed emails
|
328 |
+
foreach ( $this->managed_email_notifications as $notification )
|
329 |
+
{
|
330 |
+
if ( $this->is_email_managed( $notification->name ) ) {
|
331 |
+
add_filter( "woocommerce_email_enabled_". $notification->name ."", '__return_false' );
|
332 |
+
}
|
333 |
+
}
|
334 |
+
|
335 |
+
add_filter( 'woocommerce_email_title', array( $this, 'override_managed_email_title' ), 10, 2 );
|
336 |
+
add_filter( 'woocommerce_email_description', array( $this, 'override_managed_email_description' ), 10, 2 );
|
337 |
+
}
|
338 |
+
|
339 |
+
|
340 |
+
/**
|
341 |
+
* Overrides email titles for managed emails.
|
342 |
+
*
|
343 |
+
* @internal
|
344 |
+
*
|
345 |
+
* @since 1.1.0
|
346 |
+
*
|
347 |
+
* @param string $title the email title
|
348 |
+
* @param \WC_Email $email the email object
|
349 |
+
* @return string
|
350 |
+
*/
|
351 |
+
public function override_managed_email_title( $title, $email ) {
|
352 |
+
|
353 |
+
if ( isset( $email->id ) && $this->is_email_managed( $email->id ) ) {
|
354 |
+
|
355 |
+
$title .= __( ' (Managed by Creative Mail)', 'creativ-email-wordpress-plugin' );
|
356 |
+
}
|
357 |
+
|
358 |
+
return $title;
|
359 |
+
}
|
360 |
+
|
361 |
+
|
362 |
+
/**
|
363 |
+
* Overrides email description for managed emails.
|
364 |
+
*
|
365 |
+
* @internal
|
366 |
+
*
|
367 |
+
* @since 1.1.0
|
368 |
+
*
|
369 |
+
* @param string $description description text
|
370 |
+
* @param \WC_Email $email the email object
|
371 |
+
* @return string
|
372 |
+
*/
|
373 |
+
public function override_managed_email_description( $description, $email ) {
|
374 |
+
|
375 |
+
if ( isset( $email->id ) && $this->is_email_managed( $email->id ) ) {
|
376 |
+
|
377 |
+
$description .= __( ' This email is being managed and sent by Creative Mail.', 'creativ-email-wordpress-plugin' );
|
378 |
+
}
|
379 |
+
|
380 |
+
return $description;
|
381 |
+
}
|
382 |
+
|
383 |
+
/**
|
384 |
+
* Redirects the settings page of a managed email to the CreativeMail transactional notification for that email.
|
385 |
+
*
|
386 |
+
* @since 1.1.0
|
387 |
+
*
|
388 |
+
* @param \WC_Email $email the email object
|
389 |
+
*/
|
390 |
+
public function redirect_managed_email_settings_to_creative_mail( $email ) {
|
391 |
+
|
392 |
+
if ( $this->is_email_managed( $email->id )) {
|
393 |
+
wp_redirect(admin_url( 'admin.php?page=creativemail' ));
|
394 |
+
exit;
|
395 |
+
}
|
396 |
+
}
|
397 |
+
|
398 |
+
/**
|
399 |
+
* Checks if a given email ID is being managed by CreativeMail and is active.
|
400 |
+
*
|
401 |
+
* @since 1.1.0
|
402 |
+
*
|
403 |
+
* @param string $email_id woocommerce email ID
|
404 |
+
* @return bool
|
405 |
+
*/
|
406 |
+
public function is_email_managed( $email_id ) {
|
407 |
+
return (bool) $this->get_managed_notification_param( $email_id, 'active' );
|
408 |
+
}
|
409 |
+
|
410 |
+
/**
|
411 |
+
* Gets a param from the managed email notification for the given email ID.
|
412 |
+
*
|
413 |
+
* @since 1.1.0
|
414 |
+
*
|
415 |
+
* @param string $email_id woocommerce email ID
|
416 |
+
* @param string $param param name
|
417 |
+
* @return mixed|null
|
418 |
+
*/
|
419 |
+
public function get_managed_notification_param( $email_id, $param ) {
|
420 |
+
|
421 |
+
foreach($this->managed_email_notifications as $managed_email_notification) {
|
422 |
+
if ($email_id == $managed_email_notification->name && property_exists($managed_email_notification, $param)) {
|
423 |
+
return $managed_email_notification->$param;
|
424 |
+
}
|
425 |
+
}
|
426 |
+
return null;
|
427 |
+
}
|
428 |
+
|
429 |
+
/**
|
430 |
+
* Gets the managed email notification for the given email ID.
|
431 |
+
*
|
432 |
+
* @since 1.1.0
|
433 |
+
*
|
434 |
+
* @param array $items managed email notifications
|
435 |
+
* @param string $email_id woocommerce email ID
|
436 |
+
* @return mixed|null
|
437 |
+
*/
|
438 |
+
public function get_managed_notification( $items, $email_id ) {
|
439 |
+
|
440 |
+
foreach($items as $managed_email_notification) {
|
441 |
+
if ($email_id == $managed_email_notification->name) {
|
442 |
+
return $managed_email_notification;
|
443 |
+
}
|
444 |
+
}
|
445 |
+
return null;
|
446 |
+
}
|
447 |
+
|
448 |
+
/**
|
449 |
+
* Gets the transactional notification ID for a given notification.
|
450 |
+
*
|
451 |
+
* @since 1.1.0
|
452 |
+
*
|
453 |
+
* @param string $email_id woocommerce email ID
|
454 |
+
* @return int|null
|
455 |
+
*/
|
456 |
+
public function get_transactional_notification_id( $email_id ) {
|
457 |
+
|
458 |
+
return $this->get_managed_notification_param( $email_id, 'transactional_notification_id' );
|
459 |
+
}
|
460 |
+
|
461 |
+
/**
|
462 |
+
* Gets the transactional notification state.
|
463 |
+
*
|
464 |
+
* @since 1.1.0
|
465 |
+
*
|
466 |
+
* @param string $email_id woocommerce email ID
|
467 |
+
* @return string|null
|
468 |
+
*/
|
469 |
+
public function get_managed_notification_state( $email_id ) {
|
470 |
+
|
471 |
+
return $this->get_managed_notification_param( $email_id, 'state' );
|
472 |
+
}
|
473 |
+
|
474 |
+
private function get_view_order_url($order_id, $order) {
|
475 |
+
try {
|
476 |
+
if (!isset($order)) {
|
477 |
+
$order = wc_get_order( $order_id );
|
478 |
+
}
|
479 |
+
|
480 |
+
if ( isset( $order ) && method_exists( $order, 'get_view_order_url' ) ) {
|
481 |
+
return $order->get_view_order_url();
|
482 |
+
}
|
483 |
+
} catch ( \Exception $exception ) {
|
484 |
+
// silent exception
|
485 |
+
}
|
486 |
+
|
487 |
+
return null;
|
488 |
+
}
|
489 |
+
|
490 |
+
private function get_my_account_url() {
|
491 |
+
try {
|
492 |
+
return wc_get_page_permalink( 'myaccount' );
|
493 |
+
} catch ( \Exception $exception ) {
|
494 |
+
// silent exception
|
495 |
+
}
|
496 |
+
|
497 |
+
return null;
|
498 |
+
}
|
499 |
+
}
|
src/managers/instance-manager.php
CHANGED
@@ -3,6 +3,7 @@
|
|
3 |
|
4 |
namespace CreativeMail\Managers;
|
5 |
|
|
|
6 |
use CreativeMail\Helpers\OptionsHelper;
|
7 |
use WP_Error;
|
8 |
|
@@ -25,30 +26,23 @@ class InstanceManager
|
|
25 |
* @param $request
|
26 |
* @return bool|WP_Error
|
27 |
*/
|
28 |
-
public function handle_callback($request)
|
29 |
-
|
30 |
$account_information = json_decode($request->get_body());
|
31 |
if ($account_information === null) {
|
32 |
return new WP_Error( 'rest_bad_request', 'Invalid account details', array('status' => 400));
|
33 |
}
|
34 |
|
35 |
-
// Verify handshake expiration
|
36 |
-
$expiration = OptionsHelper::get_handshake_expiration();
|
37 |
-
if ($expiration === null || $expiration < time()) {
|
38 |
-
return new WP_Error( 'rest_unauthorized', 'Unauthorized', array('status' => 401));
|
39 |
-
}
|
40 |
-
|
41 |
-
// Verify handshake
|
42 |
-
$apiKey = $request->get_header('x-api-key');
|
43 |
-
if($apiKey !== OptionsHelper::get_handshake_token()){
|
44 |
-
return new WP_Error( 'rest_unauthorized', 'Unauthorized', array('status' => 401));
|
45 |
-
}
|
46 |
-
|
47 |
// Store the account information in the settings
|
48 |
OptionsHelper::set_instance_id($account_information->site_id);
|
49 |
OptionsHelper::set_instance_api_key($account_information->api_key);
|
50 |
OptionsHelper::set_connected_account_id($account_information->account_id);
|
51 |
|
|
|
|
|
|
|
|
|
|
|
52 |
return true;
|
53 |
}
|
54 |
-
}
|
3 |
|
4 |
namespace CreativeMail\Managers;
|
5 |
|
6 |
+
use CreativeMail\CreativeMail;
|
7 |
use CreativeMail\Helpers\OptionsHelper;
|
8 |
use WP_Error;
|
9 |
|
26 |
* @param $request
|
27 |
* @return bool|WP_Error
|
28 |
*/
|
29 |
+
public function handle_callback($request)
|
30 |
+
{
|
31 |
$account_information = json_decode($request->get_body());
|
32 |
if ($account_information === null) {
|
33 |
return new WP_Error( 'rest_bad_request', 'Invalid account details', array('status' => 400));
|
34 |
}
|
35 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
36 |
// Store the account information in the settings
|
37 |
OptionsHelper::set_instance_id($account_information->site_id);
|
38 |
OptionsHelper::set_instance_api_key($account_information->api_key);
|
39 |
OptionsHelper::set_connected_account_id($account_information->account_id);
|
40 |
|
41 |
+
// refresh woo commerce api key
|
42 |
+
if (in_array('woocommerce/woocommerce.php', apply_filters('active_plugins', get_option('active_plugins')))) {
|
43 |
+
CreativeMail::get_instance()->get_api_manager()->refresh_key();
|
44 |
+
}
|
45 |
+
|
46 |
return true;
|
47 |
}
|
48 |
+
}
|
src/managers/integration-manager.php
CHANGED
@@ -6,9 +6,12 @@ namespace CreativeMail\Managers;
|
|
6 |
use CreativeMail\Helpers\OptionsHelper;
|
7 |
use CreativeMail\Integrations\Integration;
|
8 |
use CreativeMail\Modules\Contacts\Handlers\ContactFormSevenPluginHandler;
|
|
|
9 |
use CreativeMail\Modules\Contacts\Handlers\NewsLetterContactFormPluginHandler;
|
10 |
use CreativeMail\Modules\Contacts\Handlers\WooCommercePluginHandler;
|
11 |
use CreativeMail\Modules\Contacts\Handlers\WpFormsLitePluginHandler;
|
|
|
|
|
12 |
use ReflectionClass;
|
13 |
|
14 |
/**
|
@@ -25,15 +28,16 @@ class IntegrationManager
|
|
25 |
|
26 |
public function __construct()
|
27 |
{
|
28 |
-
|
29 |
$this->active_integrations = array();
|
30 |
|
31 |
// Setup the default integrations
|
32 |
$this->supported_integrations = array(
|
|
|
|
|
33 |
new Integration('contact-form-7', 'Contact Form 7', 'contact-form-7/wp-contact-form-7.php', ContactFormSevenPluginHandler::class),
|
34 |
new Integration('newsletter','Newsletter', 'newsletter/plugin.php', NewsLetterContactFormPluginHandler::class),
|
35 |
-
new Integration('
|
36 |
-
new Integration('
|
37 |
);
|
38 |
}
|
39 |
|
@@ -95,6 +99,10 @@ class IntegrationManager
|
|
95 |
return $activated_plugins;
|
96 |
}
|
97 |
|
|
|
|
|
|
|
|
|
98 |
/**
|
99 |
* Stores the plugins that were activated by the user.
|
100 |
* @param $plugins
|
@@ -147,4 +155,8 @@ class IntegrationManager
|
|
147 |
{
|
148 |
return $this->supported_integrations;
|
149 |
}
|
|
|
|
|
|
|
|
|
150 |
}
|
6 |
use CreativeMail\Helpers\OptionsHelper;
|
7 |
use CreativeMail\Integrations\Integration;
|
8 |
use CreativeMail\Modules\Contacts\Handlers\ContactFormSevenPluginHandler;
|
9 |
+
use CreativeMail\Modules\Contacts\Handlers\GravityFormsPluginHandler;
|
10 |
use CreativeMail\Modules\Contacts\Handlers\NewsLetterContactFormPluginHandler;
|
11 |
use CreativeMail\Modules\Contacts\Handlers\WooCommercePluginHandler;
|
12 |
use CreativeMail\Modules\Contacts\Handlers\WpFormsLitePluginHandler;
|
13 |
+
use CreativeMail\Modules\Contacts\Handlers\JetpackPluginHandler;
|
14 |
+
use CreativeMail\Modules\Contacts\Processes\ContactUploadProcess;
|
15 |
use ReflectionClass;
|
16 |
|
17 |
/**
|
28 |
|
29 |
public function __construct()
|
30 |
{
|
|
|
31 |
$this->active_integrations = array();
|
32 |
|
33 |
// Setup the default integrations
|
34 |
$this->supported_integrations = array(
|
35 |
+
new Integration('jetpack', 'Jetpack Forms', 'jetpack/jetpack.php', JetpackPluginHandler::class),
|
36 |
+
new Integration('woocommerce','WooCommerce', 'woocommerce/woocommerce.php', WooCommercePluginHandler::class),
|
37 |
new Integration('contact-form-7', 'Contact Form 7', 'contact-form-7/wp-contact-form-7.php', ContactFormSevenPluginHandler::class),
|
38 |
new Integration('newsletter','Newsletter', 'newsletter/plugin.php', NewsLetterContactFormPluginHandler::class),
|
39 |
+
new Integration('wpformslite', 'WPForms Lite', 'wpforms-lite/wpforms.php', WpFormsLitePluginHandler::class),
|
40 |
+
new Integration('gravityforms', 'GravityForms', 'gravityforms/gravityforms.php', GravityFormsPluginHandler::class)
|
41 |
);
|
42 |
}
|
43 |
|
99 |
return $activated_plugins;
|
100 |
}
|
101 |
|
102 |
+
public function is_plugin_active($slug) {
|
103 |
+
return array_key_exists($slug, $this->active_integrations);
|
104 |
+
}
|
105 |
+
|
106 |
/**
|
107 |
* Stores the plugins that were activated by the user.
|
108 |
* @param $plugins
|
155 |
{
|
156 |
return $this->supported_integrations;
|
157 |
}
|
158 |
+
|
159 |
+
public function get_permalinks_enabled() {
|
160 |
+
return get_option( 'permalink_structure' ) !== '';
|
161 |
+
}
|
162 |
}
|
src/modules/api/Models/ApiRequestItem.php
ADDED
@@ -0,0 +1,31 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace CreativeMail\Modules\Api\Models;
|
4 |
+
|
5 |
+
use CreativeMail\Helpers\EnvironmentHelper;
|
6 |
+
use CreativeMail\Helpers\OptionsHelper;
|
7 |
+
|
8 |
+
class ApiRequestItem
|
9 |
+
{
|
10 |
+
|
11 |
+
public $httpMethod;
|
12 |
+
public $contentType;
|
13 |
+
public $endpoint;
|
14 |
+
public $payload;
|
15 |
+
public $apiKey;
|
16 |
+
public $accountId;
|
17 |
+
|
18 |
+
function __construct($httpMethod, $contentType, $endpoint, $payload) {
|
19 |
+
|
20 |
+
$apiKey = OptionsHelper::get_instance_api_key();
|
21 |
+
$accountId = OptionsHelper::get_connected_account_id();
|
22 |
+
$baseUrl = EnvironmentHelper::get_app_gateway_url('wordpress');
|
23 |
+
|
24 |
+
$this->httpMethod = $httpMethod;
|
25 |
+
$this->contentType = $contentType;
|
26 |
+
$this->endpoint = $baseUrl.$endpoint;
|
27 |
+
$this->payload = $payload;
|
28 |
+
$this->apiKey = $apiKey;
|
29 |
+
$this->accountId = $accountId;
|
30 |
+
}
|
31 |
+
}
|
src/modules/api/Processes/ApiBackgroundProcess.php
ADDED
@@ -0,0 +1,68 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace CreativeMail\Modules\Api\Processes;
|
4 |
+
|
5 |
+
use CreativeMail\Modules\Api\Models\ApiRequestItem;
|
6 |
+
use WP_Background_Process;
|
7 |
+
|
8 |
+
class ApiBackgroundProcess extends WP_Background_Process {
|
9 |
+
|
10 |
+
protected $action = 'ce_api_background_process';
|
11 |
+
|
12 |
+
/**
|
13 |
+
* Task
|
14 |
+
*
|
15 |
+
* Override this method to perform any actions required on each
|
16 |
+
* queue item. Return the modified item for further processing
|
17 |
+
* in the next pass through. Or, return false to remove the
|
18 |
+
* item from the queue.
|
19 |
+
*
|
20 |
+
* @param ApiRequestItem $item Queue item to iterate over
|
21 |
+
*
|
22 |
+
* @return mixed
|
23 |
+
*/
|
24 |
+
protected function task( $item ) {
|
25 |
+
if (!isset($item->httpMethod) || empty($item->httpMethod)) {
|
26 |
+
return false;
|
27 |
+
}
|
28 |
+
|
29 |
+
if (!isset($item->endpoint) || empty($item->endpoint)) {
|
30 |
+
return false;
|
31 |
+
}
|
32 |
+
|
33 |
+
$httpMethod = strtoupper($item->httpMethod);
|
34 |
+
|
35 |
+
if ($httpMethod === 'POST') {
|
36 |
+
wp_remote_post($item->endpoint, array(
|
37 |
+
'method' => $httpMethod,
|
38 |
+
'headers' => array(
|
39 |
+
'x-account-id' => $item->accountId,
|
40 |
+
'x-api-key' => $item->apiKey,
|
41 |
+
'content-type' => $item->contentType
|
42 |
+
),
|
43 |
+
'body' => $item->payload
|
44 |
+
));
|
45 |
+
return false;
|
46 |
+
}
|
47 |
+
|
48 |
+
wp_remote_get($item->endpoint, array(
|
49 |
+
'method' => $httpMethod,
|
50 |
+
'headers' => array(
|
51 |
+
'x-account-id' => $item->accountId,
|
52 |
+
'x-api-key' => $item->apiKey,
|
53 |
+
'content-type' => $item->contentType
|
54 |
+
)
|
55 |
+
));
|
56 |
+
return false;
|
57 |
+
}
|
58 |
+
|
59 |
+
/**
|
60 |
+
* Complete
|
61 |
+
*
|
62 |
+
* Override if applicable, but ensure that the below actions are
|
63 |
+
* performed, or, call parent::complete().
|
64 |
+
*/
|
65 |
+
protected function complete() {
|
66 |
+
parent::complete();
|
67 |
+
}
|
68 |
+
}
|
src/modules/blog/models/BlogAttachment.php
CHANGED
@@ -9,7 +9,7 @@ class BlogAttachment {
|
|
9 |
public $modified;
|
10 |
public $url;
|
11 |
public $thumbnail;
|
12 |
-
|
13 |
function __construct($wp_attachment) {
|
14 |
$this->id = $wp_attachment->ID;
|
15 |
$this->name = $wp_attachment->post_title;
|
@@ -17,5 +17,11 @@ class BlogAttachment {
|
|
17 |
$this->modified = $wp_attachment->post_modified;
|
18 |
$this->url = wp_get_attachment_url($wp_attachment->ID);
|
19 |
$this->thumbnail = wp_get_attachment_image_url($wp_attachment->ID, 'medium_large');
|
|
|
|
|
|
|
|
|
|
|
|
|
20 |
}
|
21 |
-
}
|
9 |
public $modified;
|
10 |
public $url;
|
11 |
public $thumbnail;
|
12 |
+
|
13 |
function __construct($wp_attachment) {
|
14 |
$this->id = $wp_attachment->ID;
|
15 |
$this->name = $wp_attachment->post_title;
|
17 |
$this->modified = $wp_attachment->post_modified;
|
18 |
$this->url = wp_get_attachment_url($wp_attachment->ID);
|
19 |
$this->thumbnail = wp_get_attachment_image_url($wp_attachment->ID, 'medium_large');
|
20 |
+
$this->meta_data = wp_get_attachment_metadata($wp_attachment->ID);
|
21 |
+
// in case false on failure
|
22 |
+
if ($this->meta_data === false)
|
23 |
+
{
|
24 |
+
$this->meta_data = array();
|
25 |
+
}
|
26 |
}
|
27 |
+
}
|
src/modules/blog/models/BlogInformation.php
CHANGED
@@ -1,4 +1,4 @@
|
|
1 |
-
<?php
|
2 |
|
3 |
namespace CreativeMail\Modules\Blog\Models;
|
4 |
|
@@ -18,10 +18,11 @@ class BlogInformation {
|
|
18 |
public $last_name;
|
19 |
public $company;
|
20 |
public $email;
|
21 |
-
|
22 |
public $woocommerce;
|
23 |
|
24 |
function __construct() {
|
|
|
25 |
$this->title = get_bloginfo('name');
|
26 |
$this->description = get_bloginfo('description');
|
27 |
$this->url = get_bloginfo('url');
|
@@ -34,4 +35,4 @@ class BlogInformation {
|
|
34 |
$this->template = get_template();
|
35 |
$this->woocommerce = new WCStoreInformation();
|
36 |
}
|
37 |
-
}
|
1 |
+
<?php
|
2 |
|
3 |
namespace CreativeMail\Modules\Blog\Models;
|
4 |
|
18 |
public $last_name;
|
19 |
public $company;
|
20 |
public $email;
|
21 |
+
|
22 |
public $woocommerce;
|
23 |
|
24 |
function __construct() {
|
25 |
+
$this->plugin_version = CE4WP_PLUGIN_VERSION;
|
26 |
$this->title = get_bloginfo('name');
|
27 |
$this->description = get_bloginfo('description');
|
28 |
$this->url = get_bloginfo('url');
|
35 |
$this->template = get_template();
|
36 |
$this->woocommerce = new WCStoreInformation();
|
37 |
}
|
38 |
+
}
|
src/modules/contacts/Handlers/ContactFormSevenPluginHandler.php
CHANGED
@@ -109,6 +109,7 @@ class ContactFormSevenPluginHandler extends BaseContactFormPluginHandler {
|
|
109 |
$form_data = unserialize($formSubmission->form_value);
|
110 |
$contactModel = new ContactModel();
|
111 |
$contactModel->setOptIn(true);
|
|
|
112 |
$contactModel->setOptActionBy(OptActionBy::Visitor);
|
113 |
$email = $this->findValueFromDb($form_data, $this->emailFields);
|
114 |
if ($this->isNotNullOrEmpty($email)) {
|
109 |
$form_data = unserialize($formSubmission->form_value);
|
110 |
$contactModel = new ContactModel();
|
111 |
$contactModel->setOptIn(true);
|
112 |
+
$contactModel->setOptOut(false);
|
113 |
$contactModel->setOptActionBy(OptActionBy::Visitor);
|
114 |
$email = $this->findValueFromDb($form_data, $this->emailFields);
|
115 |
if ($this->isNotNullOrEmpty($email)) {
|
src/modules/contacts/Handlers/GravityFormsPluginHandler.php
ADDED
@@ -0,0 +1,202 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace CreativeMail\Modules\Contacts\Handlers;
|
4 |
+
|
5 |
+
define('CE4WP_GF_EventType', 'WordPress - GravityForms');
|
6 |
+
|
7 |
+
use CreativeMail\Modules\Contacts\Models\ContactModel;
|
8 |
+
use CreativeMail\Modules\Contacts\Models\OptActionBy;
|
9 |
+
|
10 |
+
class GravityFormsPluginHandler extends BaseContactFormPluginHandler
|
11 |
+
{
|
12 |
+
private $textFormFields = array('text', 'textarea');
|
13 |
+
private $emailNames = array('e-mail', 'email', 'emailaddress', 'email address', 'e-mail address', 'email-address');
|
14 |
+
|
15 |
+
public function convertToContactModel($user)
|
16 |
+
{
|
17 |
+
$contactModel = new ContactModel();
|
18 |
+
|
19 |
+
$contactModel->setEventType(CE4WP_GF_EventType);
|
20 |
+
$contactModel->setOptIn(true);
|
21 |
+
$contactModel->setOptOut(false);
|
22 |
+
$contactModel->setOptActionBy(OptActionBy::Visitor);
|
23 |
+
|
24 |
+
$email = $user->email;
|
25 |
+
if ($this->isNotNullOrEmpty($email)) {
|
26 |
+
$contactModel->setEmail($email);
|
27 |
+
}
|
28 |
+
|
29 |
+
$firstName = $user->name['firstName'];
|
30 |
+
$insertion = $user->name['insertion'];
|
31 |
+
$lastName = $user->name['lastName'];
|
32 |
+
|
33 |
+
if ($this->isNotNullOrEmpty($firstName)) {
|
34 |
+
$contactModel->setFirstName($firstName);
|
35 |
+
}
|
36 |
+
|
37 |
+
if ($this->isNotNullOrEmpty($lastName)) {
|
38 |
+
if ($this->isNotNullOrEmpty($insertion)) {
|
39 |
+
$lastName = implode(' ', [$insertion, $lastName]);
|
40 |
+
}
|
41 |
+
$contactModel->setLastName($lastName);
|
42 |
+
}
|
43 |
+
|
44 |
+
return $contactModel;
|
45 |
+
}
|
46 |
+
|
47 |
+
//Gets the first name, optional insertion and last name from the contactform
|
48 |
+
//Returns the concatenated name
|
49 |
+
/**
|
50 |
+
* @param $entry (The form submission)
|
51 |
+
* @param $form (The form used)
|
52 |
+
* @return string (concatenated firstname, insertion and lastname)
|
53 |
+
*/
|
54 |
+
private function GetNameValuesFromForm($entry, $form)
|
55 |
+
{
|
56 |
+
$nameValues = array();
|
57 |
+
foreach ($form['fields'] as $field) {
|
58 |
+
if ($field["type"] == "name") {
|
59 |
+
$values = $field["inputs"];
|
60 |
+
$nameValues["firstName"] = rgar($entry, $values[1]["id"]); //first name
|
61 |
+
$nameValues["insertion"] = rgar($entry, $values[2]["id"]); //insertion
|
62 |
+
$nameValues["lastName"] = rgar($entry, $values[3]["id"]); //last name
|
63 |
+
}
|
64 |
+
}
|
65 |
+
return $nameValues;
|
66 |
+
}
|
67 |
+
|
68 |
+
//Attempts to get the email from the email field if present,
|
69 |
+
//otherwise searches text fields for email labels and values
|
70 |
+
//Returns the value of the email field or the first valid email found in an "email" labelled text field, or NULL
|
71 |
+
/**
|
72 |
+
* @param $entry (The form submission)
|
73 |
+
* @param $form (The form used)
|
74 |
+
* @return string (either a validated email or NULL)
|
75 |
+
*/
|
76 |
+
private function GetEmailFromForm($entry, $form)
|
77 |
+
{
|
78 |
+
$email = null;
|
79 |
+
//Check for email type in form
|
80 |
+
foreach ($form['fields'] as $field) {
|
81 |
+
if ($field["type"] == "email") {
|
82 |
+
$email = rgar($entry, $field["id"]);
|
83 |
+
//Check if the values is a valid email
|
84 |
+
if (filter_var($email, FILTER_VALIDATE_EMAIL)) {
|
85 |
+
return $email;
|
86 |
+
}
|
87 |
+
}
|
88 |
+
}
|
89 |
+
//Else check if we can find an email value in text fields
|
90 |
+
foreach ($form['fields'] as $field) {
|
91 |
+
if (in_array(strtolower($field["type"]), $this->textFormFields) && in_array(strtolower($field["label"]), $this->emailNames)) {
|
92 |
+
$possibleEmail = rgar($entry, $field["id"]);
|
93 |
+
if (filter_var($possibleEmail, FILTER_VALIDATE_EMAIL)) {
|
94 |
+
return $possibleEmail;
|
95 |
+
}
|
96 |
+
}
|
97 |
+
}
|
98 |
+
return $email;
|
99 |
+
}
|
100 |
+
|
101 |
+
public function ceHandleGravityFormSubmission($entry, $form)
|
102 |
+
{
|
103 |
+
try {
|
104 |
+
$contact = new \stdClass();
|
105 |
+
$contact->name = $this->GetNameValuesFromForm($entry, $form);
|
106 |
+
$contact->email = $this->GetEmailFromForm($entry, $form);
|
107 |
+
if (empty($contact->email)) {
|
108 |
+
return;
|
109 |
+
};
|
110 |
+
$this->upsertContact($this->convertToContactModel($contact));
|
111 |
+
} catch (\Exception $exception) {
|
112 |
+
// silent exception
|
113 |
+
}
|
114 |
+
}
|
115 |
+
|
116 |
+
public function registerHooks()
|
117 |
+
{
|
118 |
+
add_action('gform_after_submission', array($this, 'ceHandleGravityFormSubmission'), 10, 2);
|
119 |
+
// add hook function to synchronize
|
120 |
+
add_action(CE4WP_SYNCHRONIZE_ACTION, array($this, 'syncAction'));
|
121 |
+
}
|
122 |
+
|
123 |
+
public function unregisterHooks()
|
124 |
+
{
|
125 |
+
remove_action('gform_after_submission', array($this, 'ceHandleGravityFormSubmission'));
|
126 |
+
// remove hook function to synchronize
|
127 |
+
remove_action(CE4WP_SYNCHRONIZE_ACTION, array($this, 'syncAction'));
|
128 |
+
}
|
129 |
+
|
130 |
+
public function syncAction($limit = null)
|
131 |
+
{
|
132 |
+
if (!is_int($limit) || $limit <= 0) {
|
133 |
+
$limit = null;
|
134 |
+
}
|
135 |
+
|
136 |
+
// Relies on plugin => GravityForms
|
137 |
+
if (in_array('gravityforms/gravityforms.php', apply_filters('active_plugins', get_option('active_plugins')))) {
|
138 |
+
global $wpdb;
|
139 |
+
|
140 |
+
$contactsArray = array();
|
141 |
+
|
142 |
+
//get the forms and their fields
|
143 |
+
$formsQuery = 'SELECT form_id, display_meta FROM wp_gf_form_meta';
|
144 |
+
$formsResult = $wpdb->get_results($wpdb->prepare($formsQuery));
|
145 |
+
|
146 |
+
//loop through the forms and get their respective entries
|
147 |
+
foreach ($formsResult as $form) {
|
148 |
+
//get the entries and their meta (i think only meta is needed)
|
149 |
+
$entriesQuery = 'SELECT entry_id, meta_key, meta_value FROM wp_gf_entry_meta';
|
150 |
+
$entriesQuery .= " WHERE form_id = $form->form_id";
|
151 |
+
$entryResults = $wpdb->get_results($entriesQuery);
|
152 |
+
if (empty($entryResults)) {
|
153 |
+
continue;
|
154 |
+
}
|
155 |
+
|
156 |
+
//combine all entry meta into their respective entries
|
157 |
+
$entries = array();
|
158 |
+
foreach ($entryResults as $entry) {
|
159 |
+
$entries[$entry->entry_id][$entry->meta_key] = $entry->meta_value;
|
160 |
+
}
|
161 |
+
|
162 |
+
//Get the contact data for each entry
|
163 |
+
foreach ($entries as $entry) {
|
164 |
+
$contact = new \stdClass();
|
165 |
+
|
166 |
+
//Get the formArray from the display_meta
|
167 |
+
$formArray = json_decode($form->display_meta, true);
|
168 |
+
|
169 |
+
$contact->email = $this->GetEmailFromForm($entry, $formArray);
|
170 |
+
if (empty($contact->email)) {
|
171 |
+
continue;
|
172 |
+
}
|
173 |
+
$contact->name = $this->GetNameValuesFromForm($entry, $formArray);
|
174 |
+
|
175 |
+
//Convert to contactModel
|
176 |
+
$contactModel = $this->convertToContactModel($contact);
|
177 |
+
array_push($contactsArray, $contactModel);
|
178 |
+
|
179 |
+
if (isset($limit) && count($contactsArray) >= $limit) {
|
180 |
+
break;
|
181 |
+
}
|
182 |
+
}
|
183 |
+
|
184 |
+
if (isset($limit) && count($contactsArray) >= $limit) {
|
185 |
+
break;
|
186 |
+
}
|
187 |
+
}
|
188 |
+
}
|
189 |
+
|
190 |
+
if (!empty($contactsArray)) {
|
191 |
+
$batches = array_chunk($contactsArray, CE4WP_BATCH_SIZE);
|
192 |
+
foreach ($batches as $batch) {
|
193 |
+
$this->batchUpsertContacts($batch);
|
194 |
+
}
|
195 |
+
}
|
196 |
+
}
|
197 |
+
|
198 |
+
function __construct()
|
199 |
+
{
|
200 |
+
parent::__construct();
|
201 |
+
}
|
202 |
+
}
|
src/modules/contacts/Handlers/JetpackPluginHandler.php
ADDED
@@ -0,0 +1,159 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace CreativeMail\Modules\Contacts\Handlers;
|
4 |
+
|
5 |
+
define('CE4WP_JP_EventType', 'WordPress - Jetpack');
|
6 |
+
|
7 |
+
use CreativeMail\Modules\Contacts\Models\ContactModel;
|
8 |
+
use CreativeMail\Modules\Contacts\Models\OptActionBy;
|
9 |
+
|
10 |
+
class JetpackPluginHandler extends BaseContactFormPluginHandler
|
11 |
+
{
|
12 |
+
function __construct()
|
13 |
+
{
|
14 |
+
parent::__construct();
|
15 |
+
}
|
16 |
+
|
17 |
+
public function convertToContactModel($contact)
|
18 |
+
{
|
19 |
+
$contactModel = new ContactModel();
|
20 |
+
|
21 |
+
$contactModel->setEventType(CE4WP_JP_EventType);
|
22 |
+
|
23 |
+
//email_marketing_consent
|
24 |
+
if ($contact->opt_in) {
|
25 |
+
$contactModel->setOptIn(true);
|
26 |
+
$contactModel->setOptOut(false);
|
27 |
+
$contactModel->setOptActionBy(OptActionBy::Visitor);
|
28 |
+
}
|
29 |
+
|
30 |
+
$email = $contact->email;
|
31 |
+
if ($this->isNotNullOrEmpty($email)) {
|
32 |
+
$contactModel->setEmail($email);
|
33 |
+
}
|
34 |
+
|
35 |
+
$values = explode(' ', $contact->name);
|
36 |
+
$firstName = array_shift($values);
|
37 |
+
$lastName = implode(' ', $values);
|
38 |
+
|
39 |
+
if ($this->isNotNullOrEmpty($firstName)) {
|
40 |
+
$contactModel->setFirstName($firstName);
|
41 |
+
}
|
42 |
+
if ($this->isNotNullOrEmpty($lastName)) {
|
43 |
+
$contactModel->setLastName($lastName);
|
44 |
+
}
|
45 |
+
|
46 |
+
return $contactModel;
|
47 |
+
}
|
48 |
+
|
49 |
+
private function GetNameAndEmailFromHeader($header)
|
50 |
+
{
|
51 |
+
$headerRegex = '/(?:^Reply-To: ")(.*)(?:" <)(.*)(?:>)/mi';
|
52 |
+
preg_match($headerRegex, $header, $regexMatches);
|
53 |
+
$values = null;
|
54 |
+
|
55 |
+
//Check if the name isn't an email address (happens when no name is supplied)
|
56 |
+
$values["name"] = (!filter_var($regexMatches[1], FILTER_VALIDATE_EMAIL)) ? $regexMatches[1] : null;
|
57 |
+
//Check if email is valid
|
58 |
+
$values["email"] = (filter_var($regexMatches[2], FILTER_VALIDATE_EMAIL)) ? $regexMatches[2] : null;
|
59 |
+
|
60 |
+
return $values;
|
61 |
+
}
|
62 |
+
|
63 |
+
public function ceHandleJetpackFormSubmission($post_id, $to, $subject, $message, $headers, $all_values, $extra_values)
|
64 |
+
{
|
65 |
+
try {
|
66 |
+
$contact = new \stdClass();
|
67 |
+
$nameAndEmail = $this->GetNameAndEmailFromHeader($headers);
|
68 |
+
$contact->email = $nameAndEmail["email"];
|
69 |
+
$contact->name = $nameAndEmail["name"];
|
70 |
+
|
71 |
+
$contact->opt_in = boolval($all_values['email_marketing_consent']);
|
72 |
+
|
73 |
+
if (empty($contact->email)) {
|
74 |
+
return;
|
75 |
+
}
|
76 |
+
$this->upsertContact($this->convertToContactModel($contact));
|
77 |
+
} catch (\Exception $exception) {
|
78 |
+
// silent exception
|
79 |
+
}
|
80 |
+
}
|
81 |
+
|
82 |
+
public function registerHooks()
|
83 |
+
{
|
84 |
+
add_action('grunion_after_message_sent', array($this, 'ceHandleJetpackFormSubmission'), 10, 7);
|
85 |
+
// add hook function to synchronize
|
86 |
+
add_action(CE4WP_SYNCHRONIZE_ACTION, array($this, 'syncAction'));
|
87 |
+
}
|
88 |
+
|
89 |
+
public function unregisterHooks()
|
90 |
+
{
|
91 |
+
remove_action('jetpack_subscriptions_form_submission', array($this, 'ceHandleJetpackFormSubmission')); //figure out the correct hook for jetpack
|
92 |
+
// remove hook function to synchronize
|
93 |
+
remove_action(CE4WP_SYNCHRONIZE_ACTION, array($this, 'syncAction'));
|
94 |
+
}
|
95 |
+
|
96 |
+
public function syncAction($limit = null)
|
97 |
+
{
|
98 |
+
if (!is_int($limit) || $limit <= 0) {
|
99 |
+
$limit = null;
|
100 |
+
}
|
101 |
+
|
102 |
+
// Relies on plugin => GravityForms
|
103 |
+
if (in_array('jetpack/jetpack.php', apply_filters('active_plugins', get_option('active_plugins')))) {
|
104 |
+
$authorRegex = '/(?:^AUTHOR: )(.*)/mi';
|
105 |
+
$authorMailRegex = '/(?:^AUTHOR EMAIL: )(.*)/mi';
|
106 |
+
|
107 |
+
$contactsArray = array();
|
108 |
+
|
109 |
+
//get all posts with type->feedback (i think these are all the contact forms submitted)
|
110 |
+
$feedbackResults = get_posts(array('post_type' => 'feedback'));
|
111 |
+
|
112 |
+
//loop through the feedbacks and get each blocks innerHTML
|
113 |
+
foreach ($feedbackResults as $feedback) {
|
114 |
+
foreach (parse_blocks($feedback->post_content) as $block) {
|
115 |
+
$feedbackHtml = $block['innerHTML'];
|
116 |
+
|
117 |
+
//extract email and name from submission
|
118 |
+
preg_match($authorRegex, $feedbackHtml, $authorMatches);
|
119 |
+
$author = $authorMatches[1];
|
120 |
+
|
121 |
+
preg_match($authorMailRegex, $feedbackHtml, $authorEmailMatches);
|
122 |
+
$authorEmail = $authorEmailMatches[1];
|
123 |
+
|
124 |
+
$contact = new \stdClass();
|
125 |
+
$contact->email = filter_var($authorEmail, FILTER_VALIDATE_EMAIL);
|
126 |
+
if (empty($contact->email)) {
|
127 |
+
continue;
|
128 |
+
}
|
129 |
+
|
130 |
+
if (!filter_var($author, FILTER_VALIDATE_EMAIL)) { //if the author field also contains an email, ignore it (this happens when no name is provided)
|
131 |
+
$contact->name = $author;
|
132 |
+
} else {
|
133 |
+
$contact->name = null;
|
134 |
+
}
|
135 |
+
|
136 |
+
//Convert to contactModel and push to the array
|
137 |
+
$contactModel = $this->convertToContactModel($contact);
|
138 |
+
array_push($contactsArray, $contactModel);
|
139 |
+
|
140 |
+
if (isset($limit) && count($contactsArray) >= $limit) {
|
141 |
+
break;
|
142 |
+
}
|
143 |
+
}
|
144 |
+
|
145 |
+
if (isset($limit) && count($contactsArray) >= $limit) {
|
146 |
+
break;
|
147 |
+
}
|
148 |
+
}
|
149 |
+
|
150 |
+
//upsert the contacts
|
151 |
+
if (!empty($contactsArray)) {
|
152 |
+
$batches = array_chunk($contactsArray, CE4WP_BATCH_SIZE);
|
153 |
+
foreach ($batches as $batch) {
|
154 |
+
$this->batchUpsertContacts($batch);
|
155 |
+
}
|
156 |
+
}
|
157 |
+
}
|
158 |
+
}
|
159 |
+
}
|
src/modules/contacts/Handlers/NewsLetterContactFormPluginHandler.php
CHANGED
@@ -84,7 +84,8 @@ class NewsLetterContactFormPluginHandler extends BaseContactFormPluginHandler
|
|
84 |
foreach ($result as $contact) {
|
85 |
$contactModel = new ContactModel();
|
86 |
$contactModel->setEventType(CE4WP_NL_EventType);
|
87 |
-
$contactModel->setOptIn(
|
|
|
88 |
$contactModel->setOptActionBy(OptActionBy::Visitor);
|
89 |
|
90 |
$email = $contact->email;
|
84 |
foreach ($result as $contact) {
|
85 |
$contactModel = new ContactModel();
|
86 |
$contactModel->setEventType(CE4WP_NL_EventType);
|
87 |
+
$contactModel->setOptIn($contact->status !== "U");
|
88 |
+
$contactModel->setOptOut($contact->status === "U");
|
89 |
$contactModel->setOptActionBy(OptActionBy::Visitor);
|
90 |
|
91 |
$email = $contact->email;
|
src/modules/contacts/Handlers/WooCommercePluginHandler.php
CHANGED
@@ -33,8 +33,9 @@ class WooCommercePluginHandler extends BaseContactFormPluginHandler
|
|
33 |
|
34 |
if ($this->isNotNullOrEmpty($contactModel->getEmail())) {
|
35 |
$contactModel->setEventType(CE4WP_WC_EventType);
|
36 |
-
$contactModel->setOptActionBy(
|
37 |
$contactModel->setOptIn(true);
|
|
|
38 |
}
|
39 |
}
|
40 |
return $contactModel;
|
33 |
|
34 |
if ($this->isNotNullOrEmpty($contactModel->getEmail())) {
|
35 |
$contactModel->setEventType(CE4WP_WC_EventType);
|
36 |
+
$contactModel->setOptActionBy(2);
|
37 |
$contactModel->setOptIn(true);
|
38 |
+
$contactModel->setOptOut(false);
|
39 |
}
|
40 |
}
|
41 |
return $contactModel;
|
src/modules/contacts/Handlers/WpFormsLitePluginHandler.php
CHANGED
@@ -26,6 +26,7 @@ class WpFormsLitePluginHandler extends BaseContactFormPluginHandler
|
|
26 |
|
27 |
$contactModel->setEventType(CE4WP_WPF_EventType);
|
28 |
$contactModel->setOptIn(true);
|
|
|
29 |
$contactModel->setOptActionBy(OptActionBy::Visitor);
|
30 |
|
31 |
$emailField = $this->get_form_type_field($formData, 'email');
|
26 |
|
27 |
$contactModel->setEventType(CE4WP_WPF_EventType);
|
28 |
$contactModel->setOptIn(true);
|
29 |
+
$contactModel->setOptOut(false);
|
30 |
$contactModel->setOptActionBy(OptActionBy::Visitor);
|
31 |
|
32 |
$emailField = $this->get_form_type_field($formData, 'email');
|
src/modules/contacts/Services/ContactsSyncService.php
CHANGED
@@ -2,17 +2,13 @@
|
|
2 |
|
3 |
namespace CreativeMail\Modules\Contacts\Services;
|
4 |
|
5 |
-
use CreativeMail\
|
6 |
-
use CreativeMail\
|
7 |
use CreativeMail\Modules\Contacts\Models\ContactModel;
|
8 |
use Exception;
|
9 |
|
10 |
class ContactsSyncService
|
11 |
{
|
12 |
-
private $apiKey;
|
13 |
-
private $baseUrl;
|
14 |
-
private $accountId;
|
15 |
-
|
16 |
private function validate_email_address($emailAddress) {
|
17 |
if (!isset($emailAddress) && empty($emailAddress)) {
|
18 |
throw new Exception('No valid email address provided');
|
@@ -28,15 +24,6 @@ class ContactsSyncService
|
|
28 |
return 'WordPress';
|
29 |
}
|
30 |
|
31 |
-
// private function buildInstanceJwt() {
|
32 |
-
// $payload = array(
|
33 |
-
// 'instanceId' => $this->instanceId,
|
34 |
-
// 'exp' => time() + 3600
|
35 |
-
// );
|
36 |
-
//
|
37 |
-
// return JWT::encode($payload, $this->apiSecret, 'HS256');
|
38 |
-
// }
|
39 |
-
|
40 |
private function build_payload($contactModels) {
|
41 |
$contacts = array();
|
42 |
foreach ($contactModels as $model) {
|
@@ -50,40 +37,6 @@ class ContactsSyncService
|
|
50 |
return wp_json_encode($data);
|
51 |
}
|
52 |
|
53 |
-
private function send($httpMethod, $endpoint, $payload) {
|
54 |
-
|
55 |
-
if (!isset($httpMethod) || empty($httpMethod)) {
|
56 |
-
// throw exception
|
57 |
-
}
|
58 |
-
|
59 |
-
if (!isset($endpoint) || empty($endpoint)) {
|
60 |
-
throw new Exception('No endpoint provided');
|
61 |
-
}
|
62 |
-
|
63 |
-
$httpMethod = strtoupper($httpMethod);
|
64 |
-
|
65 |
-
if ($httpMethod === 'POST') {
|
66 |
-
return wp_remote_post($endpoint, array(
|
67 |
-
'method' => 'POST',
|
68 |
-
'headers' => array(
|
69 |
-
'x-account-id' => $this->accountId,
|
70 |
-
'x-api-key' => $this->apiKey,
|
71 |
-
'content-type' => 'application/json'
|
72 |
-
),
|
73 |
-
'body' => $payload
|
74 |
-
));
|
75 |
-
}
|
76 |
-
|
77 |
-
return wp_remote_get($endpoint, array(
|
78 |
-
'method' => 'GET',
|
79 |
-
'headers' => array(
|
80 |
-
'x-account-id' => $this->accountId,
|
81 |
-
'x-api-key' => $this->apiKey,
|
82 |
-
'content-type' => 'application/json'
|
83 |
-
)
|
84 |
-
));
|
85 |
-
}
|
86 |
-
|
87 |
public function upsertContact(ContactModel $contactModel) {
|
88 |
if(!isset($contactModel)) {
|
89 |
return false;
|
@@ -92,24 +45,32 @@ class ContactsSyncService
|
|
92 |
$this->validate_email_address($contactModel->getEmail());
|
93 |
$contactModel->setEventType($this->ensure_event_type($contactModel->getEventType()));
|
94 |
|
95 |
-
$
|
96 |
-
|
97 |
-
|
98 |
-
return (isset($result) && !empty($result));
|
99 |
}
|
100 |
|
101 |
-
public function upsertContacts($contactModels) {
|
102 |
|
103 |
-
$
|
104 |
-
$jsonData = $this->build_payload($contactModels);
|
105 |
-
$result = $this->send('POST', $url, $jsonData);
|
106 |
|
107 |
-
|
108 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
109 |
|
110 |
-
|
111 |
-
$this->apiKey = OptionsHelper::get_instance_api_key();
|
112 |
-
$this->accountId = OptionsHelper::get_connected_account_id();
|
113 |
-
$this->baseUrl = EnvironmentHelper::get_app_gateway_url('wordpress');
|
114 |
}
|
115 |
}
|
2 |
|
3 |
namespace CreativeMail\Modules\Contacts\Services;
|
4 |
|
5 |
+
use CreativeMail\CreativeMail;
|
6 |
+
use CreativeMail\Modules\Api\Models\ApiRequestItem;
|
7 |
use CreativeMail\Modules\Contacts\Models\ContactModel;
|
8 |
use Exception;
|
9 |
|
10 |
class ContactsSyncService
|
11 |
{
|
|
|
|
|
|
|
|
|
12 |
private function validate_email_address($emailAddress) {
|
13 |
if (!isset($emailAddress) && empty($emailAddress)) {
|
14 |
throw new Exception('No valid email address provided');
|
24 |
return 'WordPress';
|
25 |
}
|
26 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
27 |
private function build_payload($contactModels) {
|
28 |
$contacts = array();
|
29 |
foreach ($contactModels as $model) {
|
37 |
return wp_json_encode($data);
|
38 |
}
|
39 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
40 |
public function upsertContact(ContactModel $contactModel) {
|
41 |
if(!isset($contactModel)) {
|
42 |
return false;
|
45 |
$this->validate_email_address($contactModel->getEmail());
|
46 |
$contactModel->setEventType($this->ensure_event_type($contactModel->getEventType()));
|
47 |
|
48 |
+
$this->upsertContacts(array($contactModel), 1);
|
49 |
+
|
50 |
+
return true;
|
|
|
51 |
}
|
52 |
|
53 |
+
public function upsertContacts($contactModels, $batchSize = 250) {
|
54 |
|
55 |
+
$creativemail = CreativeMail::get_instance();
|
|
|
|
|
56 |
|
57 |
+
// split in chunks of $batchSize
|
58 |
+
$chunks = array_chunk($contactModels, $batchSize);
|
59 |
+
foreach ($chunks as $chunk)
|
60 |
+
{
|
61 |
+
$jsonData = $this->build_payload($chunk);
|
62 |
+
|
63 |
+
$creativemail->get_api_manager()->get_api_background_process()->push_to_queue( new ApiRequestItem(
|
64 |
+
'POST',
|
65 |
+
'application/json',
|
66 |
+
'/v1.0/contacts',
|
67 |
+
$jsonData
|
68 |
+
));
|
69 |
+
}
|
70 |
+
|
71 |
+
// Start the queue.
|
72 |
+
$creativemail->get_api_manager()->get_api_background_process()->save()->dispatch();
|
73 |
|
74 |
+
return true;
|
|
|
|
|
|
|
75 |
}
|
76 |
}
|
src/modules/contacts/models/ContactModel.php
CHANGED
@@ -11,6 +11,7 @@ class ContactModel
|
|
11 |
public $firstName;
|
12 |
public $lastName;
|
13 |
public $optIn;
|
|
|
14 |
public $optActionBy;
|
15 |
public $contactAddresses;
|
16 |
public $eventType;
|
@@ -75,10 +76,18 @@ class ContactModel
|
|
75 |
$this->optIn = $optIn;
|
76 |
}
|
77 |
|
|
|
|
|
|
|
|
|
78 |
public function getOptIn() {
|
79 |
return $this->optIn;
|
80 |
}
|
81 |
|
|
|
|
|
|
|
|
|
82 |
public function setOptActionBy($optActionBy) {
|
83 |
$this->optActionBy = $optActionBy;
|
84 |
}
|
@@ -112,6 +121,7 @@ class ContactModel
|
|
112 |
"first_name" => $this->getFirstName(),
|
113 |
"last_name" => $this->getLastName(),
|
114 |
"opt_in" => $this->getOptIn(),
|
|
|
115 |
"opt_action_by" => $this->getOptActionBy(),
|
116 |
"event_type" => $this->getEventType()
|
117 |
);
|
@@ -127,4 +137,4 @@ class ContactModel
|
|
127 |
function toJson() {
|
128 |
return wp_json_encode($this->toArray());
|
129 |
}
|
130 |
-
}
|
11 |
public $firstName;
|
12 |
public $lastName;
|
13 |
public $optIn;
|
14 |
+
public $optOut;
|
15 |
public $optActionBy;
|
16 |
public $contactAddresses;
|
17 |
public $eventType;
|
76 |
$this->optIn = $optIn;
|
77 |
}
|
78 |
|
79 |
+
public function setOptOut($optOut) {
|
80 |
+
$this->optOut = $optOut;
|
81 |
+
}
|
82 |
+
|
83 |
public function getOptIn() {
|
84 |
return $this->optIn;
|
85 |
}
|
86 |
|
87 |
+
public function getOptOut() {
|
88 |
+
return $this->optOut;
|
89 |
+
}
|
90 |
+
|
91 |
public function setOptActionBy($optActionBy) {
|
92 |
$this->optActionBy = $optActionBy;
|
93 |
}
|
121 |
"first_name" => $this->getFirstName(),
|
122 |
"last_name" => $this->getLastName(),
|
123 |
"opt_in" => $this->getOptIn(),
|
124 |
+
"opt_out" => $this->getOptOut(),
|
125 |
"opt_action_by" => $this->getOptActionBy(),
|
126 |
"event_type" => $this->getEventType()
|
127 |
);
|
137 |
function toJson() {
|
138 |
return wp_json_encode($this->toArray());
|
139 |
}
|
140 |
+
}
|
src/modules/woocommerce/models/WCInformationModel.php
ADDED
@@ -0,0 +1,21 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace CreativeMail\Modules\WooCommerce\Models;
|
4 |
+
use CreativeMail\CreativeMail;
|
5 |
+
|
6 |
+
class WCInformationModel {
|
7 |
+
public $wc_installed;
|
8 |
+
public $wc_version;
|
9 |
+
public $plugin_version;
|
10 |
+
|
11 |
+
function __construct() {
|
12 |
+
$this->wc_installed = in_array( 'woocommerce/woocommerce.php', apply_filters( 'active_plugins', get_option( 'active_plugins' ) ) );
|
13 |
+
if ($this->wc_installed) {
|
14 |
+
global $woocommerce;
|
15 |
+
$this->wc_version = $woocommerce->version;
|
16 |
+
}
|
17 |
+
|
18 |
+
$this->plugin_version = CE4WP_PLUGIN_VERSION;
|
19 |
+
$this->perma_links = CreativeMail::get_instance()->get_integration_manager()->get_permalinks_enabled();
|
20 |
+
}
|
21 |
+
}
|
src/modules/woocommerce/models/WCStoreInformation.php
CHANGED
@@ -15,7 +15,9 @@ class WCStoreInformation
|
|
15 |
public $country;
|
16 |
public $currency;
|
17 |
public $currency_symbol;
|
18 |
-
|
|
|
|
|
19 |
function __construct()
|
20 |
{
|
21 |
if (in_array('woocommerce/woocommerce.php', apply_filters('active_plugins', get_option('active_plugins'))))
|
@@ -29,6 +31,8 @@ class WCStoreInformation
|
|
29 |
$this->country = apply_filters( 'woocommerce_countries_base_country', $location );
|
30 |
$this->currency_symbol = get_woocommerce_currency_symbol();
|
31 |
$this->currency = get_woocommerce_currency();
|
|
|
|
|
32 |
}
|
33 |
}
|
34 |
-
}
|
15 |
public $country;
|
16 |
public $currency;
|
17 |
public $currency_symbol;
|
18 |
+
public $email_from;
|
19 |
+
public $email_name;
|
20 |
+
|
21 |
function __construct()
|
22 |
{
|
23 |
if (in_array('woocommerce/woocommerce.php', apply_filters('active_plugins', get_option('active_plugins'))))
|
31 |
$this->country = apply_filters( 'woocommerce_countries_base_country', $location );
|
32 |
$this->currency_symbol = get_woocommerce_currency_symbol();
|
33 |
$this->currency = get_woocommerce_currency();
|
34 |
+
$this->email_from = apply_filters( 'woocommerce_email_from_address', get_option( 'woocommerce_email_from_address' ));
|
35 |
+
$this->email_name = apply_filters( 'woocommerce_email_from_name', get_option( 'woocommerce_email_from_name' ));
|
36 |
}
|
37 |
}
|
38 |
+
}
|
src/views/dashboard.php
CHANGED
@@ -25,6 +25,22 @@ use CreativeMail\Helpers\EnvironmentHelper;
|
|
25 |
Go to Creative Mail dashboard
|
26 |
</a>
|
27 |
</div>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
28 |
</div>
|
29 |
</div>
|
30 |
<div class="col-auto">
|
@@ -40,6 +56,7 @@ use CreativeMail\Helpers\EnvironmentHelper;
|
|
40 |
window.onblur = function() {
|
41 |
blurred = true;
|
42 |
document.getElementById('ce4wp-go-button').style.display = "none";
|
|
|
43 |
};
|
44 |
window.onfocus = function() { blurred && (location.reload()); };
|
45 |
</script>
|
25 |
Go to Creative Mail dashboard
|
26 |
</a>
|
27 |
</div>
|
28 |
+
|
29 |
+
<div id="ce4wp-sub-apps-container" style="margin-top: 20px">
|
30 |
+
<h6 class="ce4wp-typography-root ce4wp-subtitle1 ce4wp-typography-gutter-bottom">
|
31 |
+
Or go directly to:
|
32 |
+
</h6>
|
33 |
+
|
34 |
+
<div class="ce4wp-pt-1 ce4wp-pb-1">
|
35 |
+
<a id="ce4wp-go-contacts-button" href="<?php echo esc_url($this->dashboard_url . '&dashboard=Contacts') ?>" class="ce4wp-button-base-root ce4wp-button-root ce4wp-button-outlined ce4wp-button-outlined-primary" target="_blank">
|
36 |
+
Contacts
|
37 |
+
</a>
|
38 |
+
|
39 |
+
<a id="ce4wp-go-logomaker-button" href="<?php echo esc_url($this->dashboard_url . '&dashboard=LogoMaker') ?>" class="ce4wp-button-base-root ce4wp-button-root ce4wp-button-outlined ce4wp-button-outlined-primary" target="_blank">
|
40 |
+
LogoMaker
|
41 |
+
</a>
|
42 |
+
</div>
|
43 |
+
</div>
|
44 |
</div>
|
45 |
</div>
|
46 |
<div class="col-auto">
|
56 |
window.onblur = function() {
|
57 |
blurred = true;
|
58 |
document.getElementById('ce4wp-go-button').style.display = "none";
|
59 |
+
document.getElementById('ce4wp-sub-apps-container').style.display = "none";
|
60 |
};
|
61 |
window.onfocus = function() { blurred && (location.reload()); };
|
62 |
</script>
|
src/views/onboarding.php
CHANGED
@@ -1,5 +1,6 @@
|
|
1 |
<?php
|
2 |
use CreativeMail\Helpers\EnvironmentHelper;
|
|
|
3 |
|
4 |
$redirectUrl = EnvironmentHelper::get_app_gateway_url('wordpress/v1.0/instances/open?clearSession=true&redirectUrl=');
|
5 |
$onboardingUrl = EnvironmentHelper::get_app_url() . 'marketing/onboarding/signup?wp_site_name=' . $this->instance_name
|
@@ -9,6 +10,10 @@
|
|
9 |
. '&wp_instance_url=' . $this->instance_url
|
10 |
. '&wp_version=' . get_bloginfo('version')
|
11 |
. '&plugin_version=' . CE4WP_PLUGIN_VERSION;
|
|
|
|
|
|
|
|
|
12 |
?>
|
13 |
|
14 |
<div class="ce4wp-admin-wrapper">
|
1 |
<?php
|
2 |
use CreativeMail\Helpers\EnvironmentHelper;
|
3 |
+
use CreativeMail\Helpers\OptionsHelper;
|
4 |
|
5 |
$redirectUrl = EnvironmentHelper::get_app_gateway_url('wordpress/v1.0/instances/open?clearSession=true&redirectUrl=');
|
6 |
$onboardingUrl = EnvironmentHelper::get_app_url() . 'marketing/onboarding/signup?wp_site_name=' . $this->instance_name
|
10 |
. '&wp_instance_url=' . $this->instance_url
|
11 |
. '&wp_version=' . get_bloginfo('version')
|
12 |
. '&plugin_version=' . CE4WP_PLUGIN_VERSION;
|
13 |
+
$referred_by = OptionsHelper::get_referred_by();
|
14 |
+
if (isset($referred_by)) {
|
15 |
+
$onboardingUrl .= '&utm_source=wordpress&utm_medium=plugin&utm_campaign=' . str_replace(';', '|', $referred_by);
|
16 |
+
}
|
17 |
?>
|
18 |
|
19 |
<div class="ce4wp-admin-wrapper">
|
vendor/a5hleyrich/wp-background-processing/.gitignore
ADDED
@@ -0,0 +1 @@
|
|
|
1 |
+
/vendor/
|
vendor/a5hleyrich/wp-background-processing/README.md
ADDED
@@ -0,0 +1,158 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# WP Background Processing
|
2 |
+
|
3 |
+
WP Background Processing can be used to fire off non-blocking asynchronous requests or as a background processing tool, allowing you to queue tasks. Check out the [example plugin](https://github.com/A5hleyRich/wp-background-processing-example) or read the [accompanying article](https://deliciousbrains.com/background-processing-wordpress/).
|
4 |
+
|
5 |
+
Inspired by [TechCrunch WP Asynchronous Tasks](https://github.com/techcrunch/wp-async-task).
|
6 |
+
|
7 |
+
__Requires PHP 5.2+__
|
8 |
+
|
9 |
+
### Async Request
|
10 |
+
|
11 |
+
Async requests are useful for pushing slow one-off tasks such as sending emails to a background process. Once the request has been dispatched it will process in the background instantly.
|
12 |
+
|
13 |
+
Extend the `WP_Async_Request` class:
|
14 |
+
|
15 |
+
```php
|
16 |
+
class WP_Example_Request extends WP_Async_Request {
|
17 |
+
|
18 |
+
/**
|
19 |
+
* @var string
|
20 |
+
*/
|
21 |
+
protected $action = 'example_request';
|
22 |
+
|
23 |
+
/**
|
24 |
+
* Handle
|
25 |
+
*
|
26 |
+
* Override this method to perform any actions required
|
27 |
+
* during the async request.
|
28 |
+
*/
|
29 |
+
protected function handle() {
|
30 |
+
// Actions to perform
|
31 |
+
}
|
32 |
+
|
33 |
+
}
|
34 |
+
```
|
35 |
+
|
36 |
+
##### `protected $action`
|
37 |
+
|
38 |
+
Should be set to a unique name.
|
39 |
+
|
40 |
+
##### `protected function handle()`
|
41 |
+
|
42 |
+
Should contain any logic to perform during the non-blocking request. The data passed to the request will be accessible via `$_POST`.
|
43 |
+
|
44 |
+
##### Dispatching Requests
|
45 |
+
|
46 |
+
Instantiate your request:
|
47 |
+
|
48 |
+
`$this->example_request = new WP_Example_Request();`
|
49 |
+
|
50 |
+
Add data to the request if required:
|
51 |
+
|
52 |
+
`$this->example_request->data( array( 'value1' => $value1, 'value2' => $value2 ) );`
|
53 |
+
|
54 |
+
Fire off the request:
|
55 |
+
|
56 |
+
`$this->example_request->dispatch();`
|
57 |
+
|
58 |
+
Chaining is also supported:
|
59 |
+
|
60 |
+
`$this->example_request->data( array( 'data' => $data ) )->dispatch();`
|
61 |
+
|
62 |
+
### Background Process
|
63 |
+
|
64 |
+
Background processes work in a similar fashion to async requests but they allow you to queue tasks. Items pushed onto the queue will be processed in the background once the queue has been dispatched. Queues will also scale based on available server resources, so higher end servers will process more items per batch. Once a batch has completed the next batch will start instantly.
|
65 |
+
|
66 |
+
Health checks run by default every 5 minutes to ensure the queue is running when queued items exist. If the queue has failed it will be restarted.
|
67 |
+
|
68 |
+
Queues work on a first in first out basis, which allows additional items to be pushed to the queue even if it’s already processing.
|
69 |
+
|
70 |
+
Extend the `WP_Background_Process` class:
|
71 |
+
|
72 |
+
```php
|
73 |
+
class WP_Example_Process extends WP_Background_Process {
|
74 |
+
|
75 |
+
/**
|
76 |
+
* @var string
|
77 |
+
*/
|
78 |
+
protected $action = 'example_process';
|
79 |
+
|
80 |
+
/**
|
81 |
+
* Task
|
82 |
+
*
|
83 |
+
* Override this method to perform any actions required on each
|
84 |
+
* queue item. Return the modified item for further processing
|
85 |
+
* in the next pass through. Or, return false to remove the
|
86 |
+
* item from the queue.
|
87 |
+
*
|
88 |
+
* @param mixed $item Queue item to iterate over
|
89 |
+
*
|
90 |
+
* @return mixed
|
91 |
+
*/
|
92 |
+
protected function task( $item ) {
|
93 |
+
// Actions to perform
|
94 |
+
|
95 |
+
return false;
|
96 |
+
}
|
97 |
+
|
98 |
+
/**
|
99 |
+
* Complete
|
100 |
+
*
|
101 |
+
* Override if applicable, but ensure that the below actions are
|
102 |
+
* performed, or, call parent::complete().
|
103 |
+
*/
|
104 |
+
protected function complete() {
|
105 |
+
parent::complete();
|
106 |
+
|
107 |
+
// Show notice to user or perform some other arbitrary task...
|
108 |
+
}
|
109 |
+
|
110 |
+
}
|
111 |
+
```
|
112 |
+
|
113 |
+
##### `protected $action`
|
114 |
+
|
115 |
+
Should be set to a unique name.
|
116 |
+
|
117 |
+
##### `protected function task( $item )`
|
118 |
+
|
119 |
+
Should contain any logic to perform on the queued item. Return `false` to remove the item from the queue or return `$item` to push it back onto the queue for further processing. If the item has been modified and is pushed back onto the queue the current state will be saved before the batch is exited.
|
120 |
+
|
121 |
+
##### `protected function complete()`
|
122 |
+
|
123 |
+
Optionally contain any logic to perform once the queue has completed.
|
124 |
+
|
125 |
+
##### Dispatching Processes
|
126 |
+
|
127 |
+
Instantiate your process:
|
128 |
+
|
129 |
+
`$this->example_process = new WP_Example_Process();`
|
130 |
+
|
131 |
+
Push items to the queue:
|
132 |
+
|
133 |
+
```php
|
134 |
+
foreach ( $items as $item ) {
|
135 |
+
$this->example_process->push_to_queue( $item );
|
136 |
+
}
|
137 |
+
```
|
138 |
+
|
139 |
+
Save and dispatch the queue:
|
140 |
+
|
141 |
+
`$this->example_process->save()->dispatch();`
|
142 |
+
|
143 |
+
### BasicAuth
|
144 |
+
|
145 |
+
If your site is behind BasicAuth, both async requests and background processes will fail to complete. This is because WP Background Processing relies on the [WordPress HTTP API](http://codex.wordpress.org/HTTP_API), which requires you to attach your BasicAuth credentials to requests. The easiest way to do this is using the following filter:
|
146 |
+
|
147 |
+
```php
|
148 |
+
function wpbp_http_request_args( $r, $url ) {
|
149 |
+
$r['headers']['Authorization'] = 'Basic ' . base64_encode( USERNAME . ':' . PASSWORD );
|
150 |
+
|
151 |
+
return $r;
|
152 |
+
}
|
153 |
+
add_filter( 'http_request_args', 'wpbp_http_request_args', 10, 2);
|
154 |
+
```
|
155 |
+
|
156 |
+
## License
|
157 |
+
|
158 |
+
[GPLv2+](http://www.gnu.org/licenses/gpl-2.0.html)
|
vendor/a5hleyrich/wp-background-processing/classes/wp-async-request.php
ADDED
@@ -0,0 +1,163 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* WP Async Request
|
4 |
+
*
|
5 |
+
* @package WP-Background-Processing
|
6 |
+
*/
|
7 |
+
|
8 |
+
if ( ! class_exists( 'WP_Async_Request' ) ) {
|
9 |
+
|
10 |
+
/**
|
11 |
+
* Abstract WP_Async_Request class.
|
12 |
+
*
|
13 |
+
* @abstract
|
14 |
+
*/
|
15 |
+
abstract class WP_Async_Request {
|
16 |
+
|
17 |
+
/**
|
18 |
+
* Prefix
|
19 |
+
*
|
20 |
+
* (default value: 'wp')
|
21 |
+
*
|
22 |
+
* @var string
|
23 |
+
* @access protected
|
24 |
+
*/
|
25 |
+
protected $prefix = 'wp';
|
26 |
+
|
27 |
+
/**
|
28 |
+
* Action
|
29 |
+
*
|
30 |
+
* (default value: 'async_request')
|
31 |
+
*
|
32 |
+
* @var string
|
33 |
+
* @access protected
|
34 |
+
*/
|
35 |
+
protected $action = 'async_request';
|
36 |
+
|
37 |
+
/**
|
38 |
+
* Identifier
|
39 |
+
*
|
40 |
+
* @var mixed
|
41 |
+
* @access protected
|
42 |
+
*/
|
43 |
+
protected $identifier;
|
44 |
+
|
45 |
+
/**
|
46 |
+
* Data
|
47 |
+
*
|
48 |
+
* (default value: array())
|
49 |
+
*
|
50 |
+
* @var array
|
51 |
+
* @access protected
|
52 |
+
*/
|
53 |
+
protected $data = array();
|
54 |
+
|
55 |
+
/**
|
56 |
+
* Initiate new async request
|
57 |
+
*/
|
58 |
+
public function __construct() {
|
59 |
+
$this->identifier = $this->prefix . '_' . $this->action;
|
60 |
+
|
61 |
+
add_action( 'wp_ajax_' . $this->identifier, array( $this, 'maybe_handle' ) );
|
62 |
+
add_action( 'wp_ajax_nopriv_' . $this->identifier, array( $this, 'maybe_handle' ) );
|
63 |
+
}
|
64 |
+
|
65 |
+
/**
|
66 |
+
* Set data used during the request
|
67 |
+
*
|
68 |
+
* @param array $data Data.
|
69 |
+
*
|
70 |
+
* @return $this
|
71 |
+
*/
|
72 |
+
public function data( $data ) {
|
73 |
+
$this->data = $data;
|
74 |
+
|
75 |
+
return $this;
|
76 |
+
}
|
77 |
+
|
78 |
+
/**
|
79 |
+
* Dispatch the async request
|
80 |
+
*
|
81 |
+
* @return array|WP_Error
|
82 |
+
*/
|
83 |
+
public function dispatch() {
|
84 |
+
$url = add_query_arg( $this->get_query_args(), $this->get_query_url() );
|
85 |
+
$args = $this->get_post_args();
|
86 |
+
|
87 |
+
return wp_remote_post( esc_url_raw( $url ), $args );
|
88 |
+
}
|
89 |
+
|
90 |
+
/**
|
91 |
+
* Get query args
|
92 |
+
*
|
93 |
+
* @return array
|
94 |
+
*/
|
95 |
+
protected function get_query_args() {
|
96 |
+
if ( property_exists( $this, 'query_args' ) ) {
|
97 |
+
return $this->query_args;
|
98 |
+
}
|
99 |
+
|
100 |
+
return array(
|
101 |
+
'action' => $this->identifier,
|
102 |
+
'nonce' => wp_create_nonce( $this->identifier ),
|
103 |
+
);
|
104 |
+
}
|
105 |
+
|
106 |
+
/**
|
107 |
+
* Get query URL
|
108 |
+
*
|
109 |
+
* @return string
|
110 |
+
*/
|
111 |
+
protected function get_query_url() {
|
112 |
+
if ( property_exists( $this, 'query_url' ) ) {
|
113 |
+
return $this->query_url;
|
114 |
+
}
|
115 |
+
|
116 |
+
return admin_url( 'admin-ajax.php' );
|
117 |
+
}
|
118 |
+
|
119 |
+
/**
|
120 |
+
* Get post args
|
121 |
+
*
|
122 |
+
* @return array
|
123 |
+
*/
|
124 |
+
protected function get_post_args() {
|
125 |
+
if ( property_exists( $this, 'post_args' ) ) {
|
126 |
+
return $this->post_args;
|
127 |
+
}
|
128 |
+
|
129 |
+
return array(
|
130 |
+
'timeout' => 0.01,
|
131 |
+
'blocking' => false,
|
132 |
+
'body' => $this->data,
|
133 |
+
'cookies' => $_COOKIE,
|
134 |
+
'sslverify' => apply_filters( 'https_local_ssl_verify', false ),
|
135 |
+
);
|
136 |
+
}
|
137 |
+
|
138 |
+
/**
|
139 |
+
* Maybe handle
|
140 |
+
*
|
141 |
+
* Check for correct nonce and pass to handler.
|
142 |
+
*/
|
143 |
+
public function maybe_handle() {
|
144 |
+
// Don't lock up other requests while processing
|
145 |
+
session_write_close();
|
146 |
+
|
147 |
+
check_ajax_referer( $this->identifier, 'nonce' );
|
148 |
+
|
149 |
+
$this->handle();
|
150 |
+
|
151 |
+
wp_die();
|
152 |
+
}
|
153 |
+
|
154 |
+
/**
|
155 |
+
* Handle
|
156 |
+
*
|
157 |
+
* Override this method to perform any actions required
|
158 |
+
* during the async request.
|
159 |
+
*/
|
160 |
+
abstract protected function handle();
|
161 |
+
|
162 |
+
}
|
163 |
+
}
|
vendor/a5hleyrich/wp-background-processing/classes/wp-background-process.php
ADDED
@@ -0,0 +1,506 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* WP Background Process
|
4 |
+
*
|
5 |
+
* @package WP-Background-Processing
|
6 |
+
*/
|
7 |
+
|
8 |
+
if ( ! class_exists( 'WP_Background_Process' ) ) {
|
9 |
+
|
10 |
+
/**
|
11 |
+
* Abstract WP_Background_Process class.
|
12 |
+
*
|
13 |
+
* @abstract
|
14 |
+
* @extends WP_Async_Request
|
15 |
+
*/
|
16 |
+
abstract class WP_Background_Process extends WP_Async_Request {
|
17 |
+
|
18 |
+
/**
|
19 |
+
* Action
|
20 |
+
*
|
21 |
+
* (default value: 'background_process')
|
22 |
+
*
|
23 |
+
* @var string
|
24 |
+
* @access protected
|
25 |
+
*/
|
26 |
+
protected $action = 'background_process';
|
27 |
+
|
28 |
+
/**
|
29 |
+
* Start time of current process.
|
30 |
+
*
|
31 |
+
* (default value: 0)
|
32 |
+
*
|
33 |
+
* @var int
|
34 |
+
* @access protected
|
35 |
+
*/
|
36 |
+
protected $start_time = 0;
|
37 |
+
|
38 |
+
/**
|
39 |
+
* Cron_hook_identifier
|
40 |
+
*
|
41 |
+
* @var mixed
|
42 |
+
* @access protected
|
43 |
+
*/
|
44 |
+
protected $cron_hook_identifier;
|
45 |
+
|
46 |
+
/**
|
47 |
+
* Cron_interval_identifier
|
48 |
+
*
|
49 |
+
* @var mixed
|
50 |
+
* @access protected
|
51 |
+
*/
|
52 |
+
protected $cron_interval_identifier;
|
53 |
+
|
54 |
+
/**
|
55 |
+
* Initiate new background process
|
56 |
+
*/
|
57 |
+
public function __construct() {
|
58 |
+
parent::__construct();
|
59 |
+
|
60 |
+
$this->cron_hook_identifier = $this->identifier . '_cron';
|
61 |
+
$this->cron_interval_identifier = $this->identifier . '_cron_interval';
|
62 |
+
|
63 |
+
add_action( $this->cron_hook_identifier, array( $this, 'handle_cron_healthcheck' ) );
|
64 |
+
add_filter( 'cron_schedules', array( $this, 'schedule_cron_healthcheck' ) );
|
65 |
+
}
|
66 |
+
|
67 |
+
/**
|
68 |
+
* Dispatch
|
69 |
+
*
|
70 |
+
* @access public
|
71 |
+
* @return void
|
72 |
+
*/
|
73 |
+
public function dispatch() {
|
74 |
+
// Schedule the cron healthcheck.
|
75 |
+
$this->schedule_event();
|
76 |
+
|
77 |
+
// Perform remote post.
|
78 |
+
return parent::dispatch();
|
79 |
+
}
|
80 |
+
|
81 |
+
/**
|
82 |
+
* Push to queue
|
83 |
+
*
|
84 |
+
* @param mixed $data Data.
|
85 |
+
*
|
86 |
+
* @return $this
|
87 |
+
*/
|
88 |
+
public function push_to_queue( $data ) {
|
89 |
+
$this->data[] = $data;
|
90 |
+
|
91 |
+
return $this;
|
92 |
+
}
|
93 |
+
|
94 |
+
/**
|
95 |
+
* Save queue
|
96 |
+
*
|
97 |
+
* @return $this
|
98 |
+
*/
|
99 |
+
public function save() {
|
100 |
+
$key = $this->generate_key();
|
101 |
+
|
102 |
+
if ( ! empty( $this->data ) ) {
|
103 |
+
update_site_option( $key, $this->data );
|
104 |
+
}
|
105 |
+
|
106 |
+
return $this;
|
107 |
+
}
|
108 |
+
|
109 |
+
/**
|
110 |
+
* Update queue
|
111 |
+
*
|
112 |
+
* @param string $key Key.
|
113 |
+
* @param array $data Data.
|
114 |
+
*
|
115 |
+
* @return $this
|
116 |
+
*/
|
117 |
+
public function update( $key, $data ) {
|
118 |
+
if ( ! empty( $data ) ) {
|
119 |
+
update_site_option( $key, $data );
|
120 |
+
}
|
121 |
+
|
122 |
+
return $this;
|
123 |
+
}
|
124 |
+
|
125 |
+
/**
|
126 |
+
* Delete queue
|
127 |
+
*
|
128 |
+
* @param string $key Key.
|
129 |
+
*
|
130 |
+
* @return $this
|
131 |
+
*/
|
132 |
+
public function delete( $key ) {
|
133 |
+
delete_site_option( $key );
|
134 |
+
|
135 |
+
return $this;
|
136 |
+
}
|
137 |
+
|
138 |
+
/**
|
139 |
+
* Generate key
|
140 |
+
*
|
141 |
+
* Generates a unique key based on microtime. Queue items are
|
142 |
+
* given a unique key so that they can be merged upon save.
|
143 |
+
*
|
144 |
+
* @param int $length Length.
|
145 |
+
*
|
146 |
+
* @return string
|
147 |
+
*/
|
148 |
+
protected function generate_key( $length = 64 ) {
|
149 |
+
$unique = md5( microtime() . rand() );
|
150 |
+
$prepend = $this->identifier . '_batch_';
|
151 |
+
|
152 |
+
return substr( $prepend . $unique, 0, $length );
|
153 |
+
}
|
154 |
+
|
155 |
+
/**
|
156 |
+
* Maybe process queue
|
157 |
+
*
|
158 |
+
* Checks whether data exists within the queue and that
|
159 |
+
* the process is not already running.
|
160 |
+
*/
|
161 |
+
public function maybe_handle() {
|
162 |
+
// Don't lock up other requests while processing
|
163 |
+
session_write_close();
|
164 |
+
|
165 |
+
if ( $this->is_process_running() ) {
|
166 |
+
// Background process already running.
|
167 |
+
wp_die();
|
168 |
+
}
|
169 |
+
|
170 |
+
if ( $this->is_queue_empty() ) {
|
171 |
+
// No data to process.
|
172 |
+
wp_die();
|
173 |
+
}
|
174 |
+
|
175 |
+
check_ajax_referer( $this->identifier, 'nonce' );
|
176 |
+
|
177 |
+
$this->handle();
|
178 |
+
|
179 |
+
wp_die();
|
180 |
+
}
|
181 |
+
|
182 |
+
/**
|
183 |
+
* Is queue empty
|
184 |
+
*
|
185 |
+
* @return bool
|
186 |
+
*/
|
187 |
+
protected function is_queue_empty() {
|
188 |
+
global $wpdb;
|
189 |
+
|
190 |
+
$table = $wpdb->options;
|
191 |
+
$column = 'option_name';
|
192 |
+
|
193 |
+
if ( is_multisite() ) {
|
194 |
+
$table = $wpdb->sitemeta;
|
195 |
+
$column = 'meta_key';
|
196 |
+
}
|
197 |
+
|
198 |
+
$key = $wpdb->esc_like( $this->identifier . '_batch_' ) . '%';
|
199 |
+
|
200 |
+
$count = $wpdb->get_var( $wpdb->prepare( "
|
201 |
+
SELECT COUNT(*)
|
202 |
+
FROM {$table}
|
203 |
+
WHERE {$column} LIKE %s
|
204 |
+
", $key ) );
|
205 |
+
|
206 |
+
return ( $count > 0 ) ? false : true;
|
207 |
+
}
|
208 |
+
|
209 |
+
/**
|
210 |
+
* Is process running
|
211 |
+
*
|
212 |
+
* Check whether the current process is already running
|
213 |
+
* in a background process.
|
214 |
+
*/
|
215 |
+
protected function is_process_running() {
|
216 |
+
if ( get_site_transient( $this->identifier . '_process_lock' ) ) {
|
217 |
+
// Process already running.
|
218 |
+
return true;
|
219 |
+
}
|
220 |
+
|
221 |
+
return false;
|
222 |
+
}
|
223 |
+
|
224 |
+
/**
|
225 |
+
* Lock process
|
226 |
+
*
|
227 |
+
* Lock the process so that multiple instances can't run simultaneously.
|
228 |
+
* Override if applicable, but the duration should be greater than that
|
229 |
+
* defined in the time_exceeded() method.
|
230 |
+
*/
|
231 |
+
protected function lock_process() {
|
232 |
+
$this->start_time = time(); // Set start time of current process.
|
233 |
+
|
234 |
+
$lock_duration = ( property_exists( $this, 'queue_lock_time' ) ) ? $this->queue_lock_time : 60; // 1 minute
|
235 |
+
$lock_duration = apply_filters( $this->identifier . '_queue_lock_time', $lock_duration );
|
236 |
+
|
237 |
+
set_site_transient( $this->identifier . '_process_lock', microtime(), $lock_duration );
|
238 |
+
}
|
239 |
+
|
240 |
+
/**
|
241 |
+
* Unlock process
|
242 |
+
*
|
243 |
+
* Unlock the process so that other instances can spawn.
|
244 |
+
*
|
245 |
+
* @return $this
|
246 |
+
*/
|
247 |
+
protected function unlock_process() {
|
248 |
+
delete_site_transient( $this->identifier . '_process_lock' );
|
249 |
+
|
250 |
+
return $this;
|
251 |
+
}
|
252 |
+
|
253 |
+
/**
|
254 |
+
* Get batch
|
255 |
+
*
|
256 |
+
* @return stdClass Return the first batch from the queue
|
257 |
+
*/
|
258 |
+
protected function get_batch() {
|
259 |
+
global $wpdb;
|
260 |
+
|
261 |
+
$table = $wpdb->options;
|
262 |
+
$column = 'option_name';
|
263 |
+
$key_column = 'option_id';
|
264 |
+
$value_column = 'option_value';
|
265 |
+
|
266 |
+
if ( is_multisite() ) {
|
267 |
+
$table = $wpdb->sitemeta;
|
268 |
+
$column = 'meta_key';
|
269 |
+
$key_column = 'meta_id';
|
270 |
+
$value_column = 'meta_value';
|
271 |
+
}
|
272 |
+
|
273 |
+
$key = $wpdb->esc_like( $this->identifier . '_batch_' ) . '%';
|
274 |
+
|
275 |
+
$query = $wpdb->get_row( $wpdb->prepare( "
|
276 |
+
SELECT *
|
277 |
+
FROM {$table}
|
278 |
+
WHERE {$column} LIKE %s
|
279 |
+
ORDER BY {$key_column} ASC
|
280 |
+
LIMIT 1
|
281 |
+
", $key ) );
|
282 |
+
|
283 |
+
$batch = new stdClass();
|
284 |
+
$batch->key = $query->$column;
|
285 |
+
$batch->data = maybe_unserialize( $query->$value_column );
|
286 |
+
|
287 |
+
return $batch;
|
288 |
+
}
|
289 |
+
|
290 |
+
/**
|
291 |
+
* Handle
|
292 |
+
*
|
293 |
+
* Pass each queue item to the task handler, while remaining
|
294 |
+
* within server memory and time limit constraints.
|
295 |
+
*/
|
296 |
+
protected function handle() {
|
297 |
+
$this->lock_process();
|
298 |
+
|
299 |
+
do {
|
300 |
+
$batch = $this->get_batch();
|
301 |
+
|
302 |
+
foreach ( $batch->data as $key => $value ) {
|
303 |
+
$task = $this->task( $value );
|
304 |
+
|
305 |
+
if ( false !== $task ) {
|
306 |
+
$batch->data[ $key ] = $task;
|
307 |
+
} else {
|
308 |
+
unset( $batch->data[ $key ] );
|
309 |
+
}
|
310 |
+
|
311 |
+
if ( $this->time_exceeded() || $this->memory_exceeded() ) {
|
312 |
+
// Batch limits reached.
|
313 |
+
break;
|
314 |
+
}
|
315 |
+
}
|
316 |
+
|
317 |
+
// Update or delete current batch.
|
318 |
+
if ( ! empty( $batch->data ) ) {
|
319 |
+
$this->update( $batch->key, $batch->data );
|
320 |
+
} else {
|
321 |
+
$this->delete( $batch->key );
|
322 |
+
}
|
323 |
+
} while ( ! $this->time_exceeded() && ! $this->memory_exceeded() && ! $this->is_queue_empty() );
|
324 |
+
|
325 |
+
$this->unlock_process();
|
326 |
+
|
327 |
+
// Start next batch or complete process.
|
328 |
+
if ( ! $this->is_queue_empty() ) {
|
329 |
+
$this->dispatch();
|
330 |
+
} else {
|
331 |
+
$this->complete();
|
332 |
+
}
|
333 |
+
|
334 |
+
wp_die();
|
335 |
+
}
|
336 |
+
|
337 |
+
/**
|
338 |
+
* Memory exceeded
|
339 |
+
*
|
340 |
+
* Ensures the batch process never exceeds 90%
|
341 |
+
* of the maximum WordPress memory.
|
342 |
+
*
|
343 |
+
* @return bool
|
344 |
+
*/
|
345 |
+
protected function memory_exceeded() {
|
346 |
+
$memory_limit = $this->get_memory_limit() * 0.9; // 90% of max memory
|
347 |
+
$current_memory = memory_get_usage( true );
|
348 |
+
$return = false;
|
349 |
+
|
350 |
+
if ( $current_memory >= $memory_limit ) {
|
351 |
+
$return = true;
|
352 |
+
}
|
353 |
+
|
354 |
+
return apply_filters( $this->identifier . '_memory_exceeded', $return );
|
355 |
+
}
|
356 |
+
|
357 |
+
/**
|
358 |
+
* Get memory limit
|
359 |
+
*
|
360 |
+
* @return int
|
361 |
+
*/
|
362 |
+
protected function get_memory_limit() {
|
363 |
+
if ( function_exists( 'ini_get' ) ) {
|
364 |
+
$memory_limit = ini_get( 'memory_limit' );
|
365 |
+
} else {
|
366 |
+
// Sensible default.
|
367 |
+
$memory_limit = '128M';
|
368 |
+
}
|
369 |
+
|
370 |
+
if ( ! $memory_limit || -1 === intval( $memory_limit ) ) {
|
371 |
+
// Unlimited, set to 32GB.
|
372 |
+
$memory_limit = '32000M';
|
373 |
+
}
|
374 |
+
|
375 |
+
return intval( $memory_limit ) * 1024 * 1024;
|
376 |
+
}
|
377 |
+
|
378 |
+
/**
|
379 |
+
* Time exceeded.
|
380 |
+
*
|
381 |
+
* Ensures the batch never exceeds a sensible time limit.
|
382 |
+
* A timeout limit of 30s is common on shared hosting.
|
383 |
+
*
|
384 |
+
* @return bool
|
385 |
+
*/
|
386 |
+
protected function time_exceeded() {
|
387 |
+
$finish = $this->start_time + apply_filters( $this->identifier . '_default_time_limit', 20 ); // 20 seconds
|
388 |
+
$return = false;
|
389 |
+
|
390 |
+
if ( time() >= $finish ) {
|
391 |
+
$return = true;
|
392 |
+
}
|
393 |
+
|
394 |
+
return apply_filters( $this->identifier . '_time_exceeded', $return );
|
395 |
+
}
|
396 |
+
|
397 |
+
/**
|
398 |
+
* Complete.
|
399 |
+
*
|
400 |
+
* Override if applicable, but ensure that the below actions are
|
401 |
+
* performed, or, call parent::complete().
|
402 |
+
*/
|
403 |
+
protected function complete() {
|
404 |
+
// Unschedule the cron healthcheck.
|
405 |
+
$this->clear_scheduled_event();
|
406 |
+
}
|
407 |
+
|
408 |
+
/**
|
409 |
+
* Schedule cron healthcheck
|
410 |
+
*
|
411 |
+
* @access public
|
412 |
+
* @param mixed $schedules Schedules.
|
413 |
+
* @return mixed
|
414 |
+
*/
|
415 |
+
public function schedule_cron_healthcheck( $schedules ) {
|
416 |
+
$interval = apply_filters( $this->identifier . '_cron_interval', 5 );
|
417 |
+
|
418 |
+
if ( property_exists( $this, 'cron_interval' ) ) {
|
419 |
+
$interval = apply_filters( $this->identifier . '_cron_interval', $this->cron_interval );
|
420 |
+
}
|
421 |
+
|
422 |
+
// Adds every 5 minutes to the existing schedules.
|
423 |
+
$schedules[ $this->identifier . '_cron_interval' ] = array(
|
424 |
+
'interval' => MINUTE_IN_SECONDS * $interval,
|
425 |
+
'display' => sprintf( __( 'Every %d Minutes' ), $interval ),
|
426 |
+
);
|
427 |
+
|
428 |
+
return $schedules;
|
429 |
+
}
|
430 |
+
|
431 |
+
/**
|
432 |
+
* Handle cron healthcheck
|
433 |
+
*
|
434 |
+
* Restart the background process if not already running
|
435 |
+
* and data exists in the queue.
|
436 |
+
*/
|
437 |
+
public function handle_cron_healthcheck() {
|
438 |
+
if ( $this->is_process_running() ) {
|
439 |
+
// Background process already running.
|
440 |
+
exit;
|
441 |
+
}
|
442 |
+
|
443 |
+
if ( $this->is_queue_empty() ) {
|
444 |
+
// No data to process.
|
445 |
+
$this->clear_scheduled_event();
|
446 |
+
exit;
|
447 |
+
}
|
448 |
+
|
449 |
+
$this->handle();
|
450 |
+
|
451 |
+
exit;
|
452 |
+
}
|
453 |
+
|
454 |
+
/**
|
455 |
+
* Schedule event
|
456 |
+
*/
|
457 |
+
protected function schedule_event() {
|
458 |
+
if ( ! wp_next_scheduled( $this->cron_hook_identifier ) ) {
|
459 |
+
wp_schedule_event( time(), $this->cron_interval_identifier, $this->cron_hook_identifier );
|
460 |
+
}
|
461 |
+
}
|
462 |
+
|
463 |
+
/**
|
464 |
+
* Clear scheduled event
|
465 |
+
*/
|
466 |
+
protected function clear_scheduled_event() {
|
467 |
+
$timestamp = wp_next_scheduled( $this->cron_hook_identifier );
|
468 |
+
|
469 |
+
if ( $timestamp ) {
|
470 |
+
wp_unschedule_event( $timestamp, $this->cron_hook_identifier );
|
471 |
+
}
|
472 |
+
}
|
473 |
+
|
474 |
+
/**
|
475 |
+
* Cancel Process
|
476 |
+
*
|
477 |
+
* Stop processing queue items, clear cronjob and delete batch.
|
478 |
+
*
|
479 |
+
*/
|
480 |
+
public function cancel_process() {
|
481 |
+
if ( ! $this->is_queue_empty() ) {
|
482 |
+
$batch = $this->get_batch();
|
483 |
+
|
484 |
+
$this->delete( $batch->key );
|
485 |
+
|
486 |
+
wp_clear_scheduled_hook( $this->cron_hook_identifier );
|
487 |
+
}
|
488 |
+
|
489 |
+
}
|
490 |
+
|
491 |
+
/**
|
492 |
+
* Task
|
493 |
+
*
|
494 |
+
* Override this method to perform any actions required on each
|
495 |
+
* queue item. Return the modified item for further processing
|
496 |
+
* in the next pass through. Or, return false to remove the
|
497 |
+
* item from the queue.
|
498 |
+
*
|
499 |
+
* @param mixed $item Queue item to iterate over.
|
500 |
+
*
|
501 |
+
* @return mixed
|
502 |
+
*/
|
503 |
+
abstract protected function task( $item );
|
504 |
+
|
505 |
+
}
|
506 |
+
}
|
vendor/a5hleyrich/wp-background-processing/composer.json
ADDED
@@ -0,0 +1,18 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
{
|
2 |
+
"name": "a5hleyrich/wp-background-processing",
|
3 |
+
"description": "WP Background Processing can be used to fire off non-blocking asynchronous requests or as a background processing tool, allowing you to queue tasks.",
|
4 |
+
"type": "library",
|
5 |
+
"require": {
|
6 |
+
"php": ">=5.2"
|
7 |
+
},
|
8 |
+
"license": "GPL-2.0-only",
|
9 |
+
"authors": [
|
10 |
+
{
|
11 |
+
"name": "Ashley Rich",
|
12 |
+
"email": "hello@ashleyrich.com"
|
13 |
+
}
|
14 |
+
],
|
15 |
+
"autoload": {
|
16 |
+
"classmap": [ "classes/" ]
|
17 |
+
}
|
18 |
+
}
|
vendor/a5hleyrich/wp-background-processing/license.txt
ADDED
@@ -0,0 +1,280 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
GNU GENERAL PUBLIC LICENSE
|
2 |
+
Version 2, June 1991
|
3 |
+
|
4 |
+
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
|
5 |
+
51 Franklin St, Fifth Floor, Boston, MA 02110, USA
|
6 |
+
|
7 |
+
Everyone is permitted to copy and distribute verbatim copies
|
8 |
+
of this license document, but changing it is not allowed.
|
9 |
+
|
10 |
+
Preamble
|
11 |
+
|
12 |
+
The licenses for most software are designed to take away your
|
13 |
+
freedom to share and change it. By contrast, the GNU General Public
|
14 |
+
License is intended to guarantee your freedom to share and change free
|
15 |
+
software--to make sure the software is free for all its users. This
|
16 |
+
General Public License applies to most of the Free Software
|
17 |
+
Foundation's software and to any other program whose authors commit to
|
18 |
+
using it. (Some other Free Software Foundation software is covered by
|
19 |
+
the GNU Library General Public License instead.) You can apply it to
|
20 |
+
your programs, too.
|
21 |
+
|
22 |
+
When we speak of free software, we are referring to freedom, not
|
23 |
+
price. Our General Public Licenses are designed to make sure that you
|
24 |
+
have the freedom to distribute copies of free software (and charge for
|
25 |
+
this service if you wish), that you receive source code or can get it
|
26 |
+
if you want it, that you can change the software or use pieces of it
|
27 |
+
in new free programs; and that you know you can do these things.
|
28 |
+
|
29 |
+
To protect your rights, we need to make restrictions that forbid
|
30 |
+
anyone to deny you these rights or to ask you to surrender the rights.
|
31 |
+
These restrictions translate to certain responsibilities for you if you
|
32 |
+
distribute copies of the software, or if you modify it.
|
33 |
+
|
34 |
+
For example, if you distribute copies of such a program, whether
|
35 |
+
gratis or for a fee, you must give the recipients all the rights that
|
36 |
+
you have. You must make sure that they, too, receive or can get the
|
37 |
+
source code. And you must show them these terms so they know their
|
38 |
+
rights.
|
39 |
+
|
40 |
+
We protect your rights with two steps: (1) copyright the software, and
|
41 |
+
(2) offer you this license which gives you legal permission to copy,
|
42 |
+
distribute and/or modify the software.
|
43 |
+
|
44 |
+
Also, for each author's protection and ours, we want to make certain
|
45 |
+
that everyone understands that there is no warranty for this free
|
46 |
+
software. If the software is modified by someone else and passed on, we
|
47 |
+
want its recipients to know that what they have is not the original, so
|
48 |
+
that any problems introduced by others will not reflect on the original
|
49 |
+
authors' reputations.
|
50 |
+
|
51 |
+
Finally, any free program is threatened constantly by software
|
52 |
+
patents. We wish to avoid the danger that redistributors of a free
|
53 |
+
program will individually obtain patent licenses, in effect making the
|
54 |
+
program proprietary. To prevent this, we have made it clear that any
|
55 |
+
patent must be licensed for everyone's free use or not licensed at all.
|
56 |
+
|
57 |
+
The precise terms and conditions for copying, distribution and
|
58 |
+
modification follow.
|
59 |
+
|
60 |
+
GNU GENERAL PUBLIC LICENSE
|
61 |
+
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
62 |
+
|
63 |
+
0. This License applies to any program or other work which contains
|
64 |
+
a notice placed by the copyright holder saying it may be distributed
|
65 |
+
under the terms of this General Public License. The "Program", below,
|
66 |
+
refers to any such program or work, and a "work based on the Program"
|
67 |
+
means either the Program or any derivative work under copyright law:
|
68 |
+
that is to say, a work containing the Program or a portion of it,
|
69 |
+
either verbatim or with modifications and/or translated into another
|
70 |
+
language. (Hereinafter, translation is included without limitation in
|
71 |
+
the term "modification".) Each licensee is addressed as "you".
|
72 |
+
|
73 |
+
Activities other than copying, distribution and modification are not
|
74 |
+
covered by this License; they are outside its scope. The act of
|
75 |
+
running the Program is not restricted, and the output from the Program
|
76 |
+
is covered only if its contents constitute a work based on the
|
77 |
+
Program (independent of having been made by running the Program).
|
78 |
+
Whether that is true depends on what the Program does.
|
79 |
+
|
80 |
+
1. You may copy and distribute verbatim copies of the Program's
|
81 |
+
source code as you receive it, in any medium, provided that you
|
82 |
+
conspicuously and appropriately publish on each copy an appropriate
|
83 |
+
copyright notice and disclaimer of warranty; keep intact all the
|
84 |
+
notices that refer to this License and to the absence of any warranty;
|
85 |
+
and give any other recipients of the Program a copy of this License
|
86 |
+
along with the Program.
|
87 |
+
|
88 |
+
You may charge a fee for the physical act of transferring a copy, and
|
89 |
+
you may at your option offer warranty protection in exchange for a fee.
|
90 |
+
|
91 |
+
2. You may modify your copy or copies of the Program or any portion
|
92 |
+
of it, thus forming a work based on the Program, and copy and
|
93 |
+
distribute such modifications or work under the terms of Section 1
|
94 |
+
above, provided that you also meet all of these conditions:
|
95 |
+
|
96 |
+
a) You must cause the modified files to carry prominent notices
|
97 |
+
stating that you changed the files and the date of any change.
|
98 |
+
|
99 |
+
b) You must cause any work that you distribute or publish, that in
|
100 |
+
whole or in part contains or is derived from the Program or any
|
101 |
+
part thereof, to be licensed as a whole at no charge to all third
|
102 |
+
parties under the terms of this License.
|
103 |
+
|
104 |
+
c) If the modified program normally reads commands interactively
|
105 |
+
when run, you must cause it, when started running for such
|
106 |
+
interactive use in the most ordinary way, to print or display an
|
107 |
+
announcement including an appropriate copyright notice and a
|
108 |
+
notice that there is no warranty (or else, saying that you provide
|
109 |
+
a warranty) and that users may redistribute the program under
|
110 |
+
these conditions, and telling the user how to view a copy of this
|
111 |
+
License. (Exception: if the Program itself is interactive but
|
112 |
+
does not normally print such an announcement, your work based on
|
113 |
+
the Program is not required to print an announcement.)
|
114 |
+
|
115 |
+
These requirements apply to the modified work as a whole. If
|
116 |
+
identifiable sections of that work are not derived from the Program,
|
117 |
+
and can be reasonably considered independent and separate works in
|
118 |
+
themselves, then this License, and its terms, do not apply to those
|
119 |
+
sections when you distribute them as separate works. But when you
|
120 |
+
distribute the same sections as part of a whole which is a work based
|
121 |
+
on the Program, the distribution of the whole must be on the terms of
|
122 |
+
this License, whose permissions for other licensees extend to the
|
123 |
+
entire whole, and thus to each and every part regardless of who wrote it.
|
124 |
+
Thus, it is not the intent of this section to claim rights or contest
|
125 |
+
your rights to work written entirely by you; rather, the intent is to
|
126 |
+
exercise the right to control the distribution of derivative or
|
127 |
+
collective works based on the Program.
|
128 |
+
|
129 |
+
In addition, mere aggregation of another work not based on the Program
|
130 |
+
with the Program (or with a work based on the Program) on a volume of
|
131 |
+
a storage or distribution medium does not bring the other work under
|
132 |
+
the scope of this License.
|
133 |
+
|
134 |
+
3. You may copy and distribute the Program (or a work based on it,
|
135 |
+
under Section 2) in object code or executable form under the terms of
|
136 |
+
Sections 1 and 2 above provided that you also do one of the following:
|
137 |
+
|
138 |
+
a) Accompany it with the complete corresponding machine-readable
|
139 |
+
source code, which must be distributed under the terms of Sections
|
140 |
+
1 and 2 above on a medium customarily used for software interchange; or,
|
141 |
+
|
142 |
+
b) Accompany it with a written offer, valid for at least three
|
143 |
+
years, to give any third party, for a charge no more than your
|
144 |
+
cost of physically performing source distribution, a complete
|
145 |
+
machine-readable copy of the corresponding source code, to be
|
146 |
+
distributed under the terms of Sections 1 and 2 above on a medium
|
147 |
+
customarily used for software interchange; or,
|
148 |
+
|
149 |
+
c) Accompany it with the information you received as to the offer
|
150 |
+
to distribute corresponding source code. (This alternative is
|
151 |
+
allowed only for noncommercial distribution and only if you
|
152 |
+
received the program in object code or executable form with such
|
153 |
+
an offer, in accord with Subsection b above.)
|
154 |
+
|
155 |
+
The source code for a work means the preferred form of the work for
|
156 |
+
making modifications to it. For an executable work, complete source
|
157 |
+
code means all the source code for all modules it contains, plus any
|
158 |
+
associated interface definition files, plus the scripts used to
|
159 |
+
control compilation and installation of the executable. However, as a
|
160 |
+
special exception, the source code distributed need not include
|
161 |
+
anything that is normally distributed (in either source or binary
|
162 |
+
form) with the major components (compiler, kernel, and so on) of the
|
163 |
+
operating system on which the executable runs, unless that component
|
164 |
+
itself accompanies the executable.
|
165 |
+
|
166 |
+
If distribution of executable or object code is made by offering
|
167 |
+
access to copy from a designated place, then offering equivalent
|
168 |
+
access to copy the source code from the same place counts as
|
169 |
+
distribution of the source code, even though third parties are not
|
170 |
+
compelled to copy the source along with the object code.
|
171 |
+
|
172 |
+
4. You may not copy, modify, sublicense, or distribute the Program
|
173 |
+
except as expressly provided under this License. Any attempt
|
174 |
+
otherwise to copy, modify, sublicense or distribute the Program is
|
175 |
+
void, and will automatically terminate your rights under this License.
|
176 |
+
However, parties who have received copies, or rights, from you under
|
177 |
+
this License will not have their licenses terminated so long as such
|
178 |
+
parties remain in full compliance.
|
179 |
+
|
180 |
+
5. You are not required to accept this License, since you have not
|
181 |
+
signed it. However, nothing else grants you permission to modify or
|
182 |
+
distribute the Program or its derivative works. These actions are
|
183 |
+
prohibited by law if you do not accept this License. Therefore, by
|
184 |
+
modifying or distributing the Program (or any work based on the
|
185 |
+
Program), you indicate your acceptance of this License to do so, and
|
186 |
+
all its terms and conditions for copying, distributing or modifying
|
187 |
+
the Program or works based on it.
|
188 |
+
|
189 |
+
6. Each time you redistribute the Program (or any work based on the
|
190 |
+
Program), the recipient automatically receives a license from the
|
191 |
+
original licensor to copy, distribute or modify the Program subject to
|
192 |
+
these terms and conditions. You may not impose any further
|
193 |
+
restrictions on the recipients' exercise of the rights granted herein.
|
194 |
+
You are not responsible for enforcing compliance by third parties to
|
195 |
+
this License.
|
196 |
+
|
197 |
+
7. If, as a consequence of a court judgment or allegation of patent
|
198 |
+
infringement or for any other reason (not limited to patent issues),
|
199 |
+
conditions are imposed on you (whether by court order, agreement or
|
200 |
+
otherwise) that contradict the conditions of this License, they do not
|
201 |
+
excuse you from the conditions of this License. If you cannot
|
202 |
+
distribute so as to satisfy simultaneously your obligations under this
|
203 |
+
License and any other pertinent obligations, then as a consequence you
|
204 |
+
may not distribute the Program at all. For example, if a patent
|
205 |
+
license would not permit royalty-free redistribution of the Program by
|
206 |
+
all those who receive copies directly or indirectly through you, then
|
207 |
+
the only way you could satisfy both it and this License would be to
|
208 |
+
refrain entirely from distribution of the Program.
|
209 |
+
|
210 |
+
If any portion of this section is held invalid or unenforceable under
|
211 |
+
any particular circumstance, the balance of the section is intended to
|
212 |
+
apply and the section as a whole is intended to apply in other
|
213 |
+
circumstances.
|
214 |
+
|
215 |
+
It is not the purpose of this section to induce you to infringe any
|
216 |
+
patents or other property right claims or to contest validity of any
|
217 |
+
such claims; this section has the sole purpose of protecting the
|
218 |
+
integrity of the free software distribution system, which is
|
219 |
+
implemented by public license practices. Many people have made
|
220 |
+
generous contributions to the wide range of software distributed
|
221 |
+
through that system in reliance on consistent application of that
|
222 |
+
system; it is up to the author/donor to decide if he or she is willing
|
223 |
+
to distribute software through any other system and a licensee cannot
|
224 |
+
impose that choice.
|
225 |
+
|
226 |
+
This section is intended to make thoroughly clear what is believed to
|
227 |
+
be a consequence of the rest of this License.
|
228 |
+
|
229 |
+
8. If the distribution and/or use of the Program is restricted in
|
230 |
+
certain countries either by patents or by copyrighted interfaces, the
|
231 |
+
original copyright holder who places the Program under this License
|
232 |
+
may add an explicit geographical distribution limitation excluding
|
233 |
+
those countries, so that distribution is permitted only in or among
|
234 |
+
countries not thus excluded. In such case, this License incorporates
|
235 |
+
the limitation as if written in the body of this License.
|
236 |
+
|
237 |
+
9. The Free Software Foundation may publish revised and/or new versions
|
238 |
+
of the General Public License from time to time. Such new versions will
|
239 |
+
be similar in spirit to the present version, but may differ in detail to
|
240 |
+
address new problems or concerns.
|
241 |
+
|
242 |
+
Each version is given a distinguishing version number. If the Program
|
243 |
+
specifies a version number of this License which applies to it and "any
|
244 |
+
later version", you have the option of following the terms and conditions
|
245 |
+
either of that version or of any later version published by the Free
|
246 |
+
Software Foundation. If the Program does not specify a version number of
|
247 |
+
this License, you may choose any version ever published by the Free Software
|
248 |
+
Foundation.
|
249 |
+
|
250 |
+
10. If you wish to incorporate parts of the Program into other free
|
251 |
+
programs whose distribution conditions are different, write to the author
|
252 |
+
to ask for permission. For software which is copyrighted by the Free
|
253 |
+
Software Foundation, write to the Free Software Foundation; we sometimes
|
254 |
+
make exceptions for this. Our decision will be guided by the two goals
|
255 |
+
of preserving the free status of all derivatives of our free software and
|
256 |
+
of promoting the sharing and reuse of software generally.
|
257 |
+
|
258 |
+
NO WARRANTY
|
259 |
+
|
260 |
+
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
261 |
+
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
262 |
+
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
263 |
+
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
|
264 |
+
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
265 |
+
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
|
266 |
+
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
|
267 |
+
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
|
268 |
+
REPAIR OR CORRECTION.
|
269 |
+
|
270 |
+
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
271 |
+
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
272 |
+
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
|
273 |
+
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
|
274 |
+
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
|
275 |
+
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
|
276 |
+
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
277 |
+
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
278 |
+
POSSIBILITY OF SUCH DAMAGES.
|
279 |
+
|
280 |
+
END OF TERMS AND CONDITIONS
|
vendor/a5hleyrich/wp-background-processing/wp-background-processing.php
ADDED
@@ -0,0 +1,20 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* WP-Background Processing
|
4 |
+
*
|
5 |
+
* @package WP-Background-Processing
|
6 |
+
*/
|
7 |
+
|
8 |
+
/*
|
9 |
+
Plugin Name: WP Background Processing
|
10 |
+
Plugin URI: https://github.com/A5hleyRich/wp-background-processing
|
11 |
+
Description: Asynchronous requests and background processing in WordPress.
|
12 |
+
Author: Delicious Brains Inc.
|
13 |
+
Version: 1.0
|
14 |
+
Author URI: https://deliciousbrains.com/
|
15 |
+
GitHub Plugin URI: https://github.com/A5hleyRich/wp-background-processing
|
16 |
+
GitHub Branch: master
|
17 |
+
*/
|
18 |
+
|
19 |
+
require_once plugin_dir_path( __FILE__ ) . 'classes/wp-async-request.php';
|
20 |
+
require_once plugin_dir_path( __FILE__ ) . 'classes/wp-background-process.php';
|
vendor/autoload.php
CHANGED
@@ -4,4 +4,4 @@
|
|
4 |
|
5 |
require_once __DIR__ . '/composer/autoload_real.php';
|
6 |
|
7 |
-
return
|
4 |
|
5 |
require_once __DIR__ . '/composer/autoload_real.php';
|
6 |
|
7 |
+
return ComposerAutoloaderInit84b4678024c245f52b85a7757a5a448f::getLoader();
|
vendor/composer/autoload_classmap.php
CHANGED
@@ -16,13 +16,18 @@ return array(
|
|
16 |
'CreativeMail\\Integrations\\Integration' => $baseDir . '/src/integrations/integration.php',
|
17 |
'CreativeMail\\Managers\\AdminManager' => $baseDir . '/src/managers/admin-manager.php',
|
18 |
'CreativeMail\\Managers\\ApiManager' => $baseDir . '/src/managers/api-manager.php',
|
|
|
19 |
'CreativeMail\\Managers\\InstanceManager' => $baseDir . '/src/managers/instance-manager.php',
|
20 |
'CreativeMail\\Managers\\IntegrationManager' => $baseDir . '/src/managers/integration-manager.php',
|
|
|
|
|
21 |
'CreativeMail\\Modules\\Blog\\Models\\BlogAttachment' => $baseDir . '/src/modules/blog/models/BlogAttachment.php',
|
22 |
'CreativeMail\\Modules\\Blog\\Models\\BlogInformation' => $baseDir . '/src/modules/blog/models/BlogInformation.php',
|
23 |
'CreativeMail\\Modules\\Blog\\Models\\BlogPost' => $baseDir . '/src/modules/blog/models/BlogPost.php',
|
24 |
'CreativeMail\\Modules\\Contacts\\Handlers\\BaseContactFormPluginHandler' => $baseDir . '/src/modules/contacts/Handlers/BaseContactFormPluginHandler.php',
|
25 |
'CreativeMail\\Modules\\Contacts\\Handlers\\ContactFormSevenPluginHandler' => $baseDir . '/src/modules/contacts/Handlers/ContactFormSevenPluginHandler.php',
|
|
|
|
|
26 |
'CreativeMail\\Modules\\Contacts\\Handlers\\NewsLetterContactFormPluginHandler' => $baseDir . '/src/modules/contacts/Handlers/NewsLetterContactFormPluginHandler.php',
|
27 |
'CreativeMail\\Modules\\Contacts\\Handlers\\WooCommercePluginHandler' => $baseDir . '/src/modules/contacts/Handlers/WooCommercePluginHandler.php',
|
28 |
'CreativeMail\\Modules\\Contacts\\Handlers\\WpFormsLitePluginHandler' => $baseDir . '/src/modules/contacts/Handlers/WpFormsLitePluginHandler.php',
|
@@ -31,6 +36,7 @@ return array(
|
|
31 |
'CreativeMail\\Modules\\Contacts\\Models\\ContactModel' => $baseDir . '/src/modules/contacts/models/ContactModel.php',
|
32 |
'CreativeMail\\Modules\\Contacts\\Models\\OptActionBy' => $baseDir . '/src/modules/contacts/models/OptActionBy.php',
|
33 |
'CreativeMail\\Modules\\Contacts\\Services\\ContactsSyncService' => $baseDir . '/src/modules/contacts/Services/ContactsSyncService.php',
|
|
|
34 |
'CreativeMail\\Modules\\WooCommerce\\Models\\WCProductModel' => $baseDir . '/src/modules/woocommerce/models/WCProductModel.php',
|
35 |
'CreativeMail\\Modules\\WooCommerce\\Models\\WCStoreInformation' => $baseDir . '/src/modules/woocommerce/models/WCStoreInformation.php',
|
36 |
'Defuse\\Crypto\\Core' => $vendorDir . '/defuse/php-encryption/src/Core.php',
|
@@ -52,4 +58,6 @@ return array(
|
|
52 |
'Firebase\\JWT\\JWK' => $vendorDir . '/firebase/php-jwt/src/JWK.php',
|
53 |
'Firebase\\JWT\\JWT' => $vendorDir . '/firebase/php-jwt/src/JWT.php',
|
54 |
'Firebase\\JWT\\SignatureInvalidException' => $vendorDir . '/firebase/php-jwt/src/SignatureInvalidException.php',
|
|
|
|
|
55 |
);
|
16 |
'CreativeMail\\Integrations\\Integration' => $baseDir . '/src/integrations/integration.php',
|
17 |
'CreativeMail\\Managers\\AdminManager' => $baseDir . '/src/managers/admin-manager.php',
|
18 |
'CreativeMail\\Managers\\ApiManager' => $baseDir . '/src/managers/api-manager.php',
|
19 |
+
'CreativeMail\\Managers\\EmailManager' => $baseDir . '/src/managers/email-manager.php',
|
20 |
'CreativeMail\\Managers\\InstanceManager' => $baseDir . '/src/managers/instance-manager.php',
|
21 |
'CreativeMail\\Managers\\IntegrationManager' => $baseDir . '/src/managers/integration-manager.php',
|
22 |
+
'CreativeMail\\Modules\\Api\\Models\\ApiRequestItem' => $baseDir . '/src/modules/api/Models/ApiRequestItem.php',
|
23 |
+
'CreativeMail\\Modules\\Api\\Processes\\ApiBackgroundProcess' => $baseDir . '/src/modules/api/Processes/ApiBackgroundProcess.php',
|
24 |
'CreativeMail\\Modules\\Blog\\Models\\BlogAttachment' => $baseDir . '/src/modules/blog/models/BlogAttachment.php',
|
25 |
'CreativeMail\\Modules\\Blog\\Models\\BlogInformation' => $baseDir . '/src/modules/blog/models/BlogInformation.php',
|
26 |
'CreativeMail\\Modules\\Blog\\Models\\BlogPost' => $baseDir . '/src/modules/blog/models/BlogPost.php',
|
27 |
'CreativeMail\\Modules\\Contacts\\Handlers\\BaseContactFormPluginHandler' => $baseDir . '/src/modules/contacts/Handlers/BaseContactFormPluginHandler.php',
|
28 |
'CreativeMail\\Modules\\Contacts\\Handlers\\ContactFormSevenPluginHandler' => $baseDir . '/src/modules/contacts/Handlers/ContactFormSevenPluginHandler.php',
|
29 |
+
'CreativeMail\\Modules\\Contacts\\Handlers\\GravityFormsPluginHandler' => $baseDir . '/src/modules/contacts/Handlers/GravityFormsPluginHandler.php',
|
30 |
+
'CreativeMail\\Modules\\Contacts\\Handlers\\JetpackPluginHandler' => $baseDir . '/src/modules/contacts/Handlers/JetpackPluginHandler.php',
|
31 |
'CreativeMail\\Modules\\Contacts\\Handlers\\NewsLetterContactFormPluginHandler' => $baseDir . '/src/modules/contacts/Handlers/NewsLetterContactFormPluginHandler.php',
|
32 |
'CreativeMail\\Modules\\Contacts\\Handlers\\WooCommercePluginHandler' => $baseDir . '/src/modules/contacts/Handlers/WooCommercePluginHandler.php',
|
33 |
'CreativeMail\\Modules\\Contacts\\Handlers\\WpFormsLitePluginHandler' => $baseDir . '/src/modules/contacts/Handlers/WpFormsLitePluginHandler.php',
|
36 |
'CreativeMail\\Modules\\Contacts\\Models\\ContactModel' => $baseDir . '/src/modules/contacts/models/ContactModel.php',
|
37 |
'CreativeMail\\Modules\\Contacts\\Models\\OptActionBy' => $baseDir . '/src/modules/contacts/models/OptActionBy.php',
|
38 |
'CreativeMail\\Modules\\Contacts\\Services\\ContactsSyncService' => $baseDir . '/src/modules/contacts/Services/ContactsSyncService.php',
|
39 |
+
'CreativeMail\\Modules\\WooCommerce\\Models\\WCInformationModel' => $baseDir . '/src/modules/woocommerce/models/WCInformationModel.php',
|
40 |
'CreativeMail\\Modules\\WooCommerce\\Models\\WCProductModel' => $baseDir . '/src/modules/woocommerce/models/WCProductModel.php',
|
41 |
'CreativeMail\\Modules\\WooCommerce\\Models\\WCStoreInformation' => $baseDir . '/src/modules/woocommerce/models/WCStoreInformation.php',
|
42 |
'Defuse\\Crypto\\Core' => $vendorDir . '/defuse/php-encryption/src/Core.php',
|
58 |
'Firebase\\JWT\\JWK' => $vendorDir . '/firebase/php-jwt/src/JWK.php',
|
59 |
'Firebase\\JWT\\JWT' => $vendorDir . '/firebase/php-jwt/src/JWT.php',
|
60 |
'Firebase\\JWT\\SignatureInvalidException' => $vendorDir . '/firebase/php-jwt/src/SignatureInvalidException.php',
|
61 |
+
'WP_Async_Request' => $vendorDir . '/a5hleyrich/wp-background-processing/classes/wp-async-request.php',
|
62 |
+
'WP_Background_Process' => $vendorDir . '/a5hleyrich/wp-background-processing/classes/wp-background-process.php',
|
63 |
);
|
vendor/composer/autoload_real.php
CHANGED
@@ -2,7 +2,7 @@
|
|
2 |
|
3 |
// autoload_real.php @generated by Composer
|
4 |
|
5 |
-
class
|
6 |
{
|
7 |
private static $loader;
|
8 |
|
@@ -22,15 +22,15 @@ class ComposerAutoloaderInit3906e6c64758b2e1c597d356b135b123
|
|
22 |
return self::$loader;
|
23 |
}
|
24 |
|
25 |
-
spl_autoload_register(array('
|
26 |
self::$loader = $loader = new \Composer\Autoload\ClassLoader();
|
27 |
-
spl_autoload_unregister(array('
|
28 |
|
29 |
$useStaticLoader = PHP_VERSION_ID >= 50600 && !defined('HHVM_VERSION') && (!function_exists('zend_loader_file_encoded') || !zend_loader_file_encoded());
|
30 |
if ($useStaticLoader) {
|
31 |
require_once __DIR__ . '/autoload_static.php';
|
32 |
|
33 |
-
call_user_func(\Composer\Autoload\
|
34 |
} else {
|
35 |
$map = require __DIR__ . '/autoload_namespaces.php';
|
36 |
foreach ($map as $namespace => $path) {
|
2 |
|
3 |
// autoload_real.php @generated by Composer
|
4 |
|
5 |
+
class ComposerAutoloaderInit84b4678024c245f52b85a7757a5a448f
|
6 |
{
|
7 |
private static $loader;
|
8 |
|
22 |
return self::$loader;
|
23 |
}
|
24 |
|
25 |
+
spl_autoload_register(array('ComposerAutoloaderInit84b4678024c245f52b85a7757a5a448f', 'loadClassLoader'), true, true);
|
26 |
self::$loader = $loader = new \Composer\Autoload\ClassLoader();
|
27 |
+
spl_autoload_unregister(array('ComposerAutoloaderInit84b4678024c245f52b85a7757a5a448f', 'loadClassLoader'));
|
28 |
|
29 |
$useStaticLoader = PHP_VERSION_ID >= 50600 && !defined('HHVM_VERSION') && (!function_exists('zend_loader_file_encoded') || !zend_loader_file_encoded());
|
30 |
if ($useStaticLoader) {
|
31 |
require_once __DIR__ . '/autoload_static.php';
|
32 |
|
33 |
+
call_user_func(\Composer\Autoload\ComposerStaticInit84b4678024c245f52b85a7757a5a448f::getInitializer($loader));
|
34 |
} else {
|
35 |
$map = require __DIR__ . '/autoload_namespaces.php';
|
36 |
foreach ($map as $namespace => $path) {
|
vendor/composer/autoload_static.php
CHANGED
@@ -4,7 +4,7 @@
|
|
4 |
|
5 |
namespace Composer\Autoload;
|
6 |
|
7 |
-
class
|
8 |
{
|
9 |
public static $prefixLengthsPsr4 = array (
|
10 |
'F' =>
|
@@ -72,13 +72,18 @@ class ComposerStaticInit3906e6c64758b2e1c597d356b135b123
|
|
72 |
'CreativeMail\\Integrations\\Integration' => __DIR__ . '/../..' . '/src/integrations/integration.php',
|
73 |
'CreativeMail\\Managers\\AdminManager' => __DIR__ . '/../..' . '/src/managers/admin-manager.php',
|
74 |
'CreativeMail\\Managers\\ApiManager' => __DIR__ . '/../..' . '/src/managers/api-manager.php',
|
|
|
75 |
'CreativeMail\\Managers\\InstanceManager' => __DIR__ . '/../..' . '/src/managers/instance-manager.php',
|
76 |
'CreativeMail\\Managers\\IntegrationManager' => __DIR__ . '/../..' . '/src/managers/integration-manager.php',
|
|
|
|
|
77 |
'CreativeMail\\Modules\\Blog\\Models\\BlogAttachment' => __DIR__ . '/../..' . '/src/modules/blog/models/BlogAttachment.php',
|
78 |
'CreativeMail\\Modules\\Blog\\Models\\BlogInformation' => __DIR__ . '/../..' . '/src/modules/blog/models/BlogInformation.php',
|
79 |
'CreativeMail\\Modules\\Blog\\Models\\BlogPost' => __DIR__ . '/../..' . '/src/modules/blog/models/BlogPost.php',
|
80 |
'CreativeMail\\Modules\\Contacts\\Handlers\\BaseContactFormPluginHandler' => __DIR__ . '/../..' . '/src/modules/contacts/Handlers/BaseContactFormPluginHandler.php',
|
81 |
'CreativeMail\\Modules\\Contacts\\Handlers\\ContactFormSevenPluginHandler' => __DIR__ . '/../..' . '/src/modules/contacts/Handlers/ContactFormSevenPluginHandler.php',
|
|
|
|
|
82 |
'CreativeMail\\Modules\\Contacts\\Handlers\\NewsLetterContactFormPluginHandler' => __DIR__ . '/../..' . '/src/modules/contacts/Handlers/NewsLetterContactFormPluginHandler.php',
|
83 |
'CreativeMail\\Modules\\Contacts\\Handlers\\WooCommercePluginHandler' => __DIR__ . '/../..' . '/src/modules/contacts/Handlers/WooCommercePluginHandler.php',
|
84 |
'CreativeMail\\Modules\\Contacts\\Handlers\\WpFormsLitePluginHandler' => __DIR__ . '/../..' . '/src/modules/contacts/Handlers/WpFormsLitePluginHandler.php',
|
@@ -87,6 +92,7 @@ class ComposerStaticInit3906e6c64758b2e1c597d356b135b123
|
|
87 |
'CreativeMail\\Modules\\Contacts\\Models\\ContactModel' => __DIR__ . '/../..' . '/src/modules/contacts/models/ContactModel.php',
|
88 |
'CreativeMail\\Modules\\Contacts\\Models\\OptActionBy' => __DIR__ . '/../..' . '/src/modules/contacts/models/OptActionBy.php',
|
89 |
'CreativeMail\\Modules\\Contacts\\Services\\ContactsSyncService' => __DIR__ . '/../..' . '/src/modules/contacts/Services/ContactsSyncService.php',
|
|
|
90 |
'CreativeMail\\Modules\\WooCommerce\\Models\\WCProductModel' => __DIR__ . '/../..' . '/src/modules/woocommerce/models/WCProductModel.php',
|
91 |
'CreativeMail\\Modules\\WooCommerce\\Models\\WCStoreInformation' => __DIR__ . '/../..' . '/src/modules/woocommerce/models/WCStoreInformation.php',
|
92 |
'Defuse\\Crypto\\Core' => __DIR__ . '/..' . '/defuse/php-encryption/src/Core.php',
|
@@ -108,14 +114,16 @@ class ComposerStaticInit3906e6c64758b2e1c597d356b135b123
|
|
108 |
'Firebase\\JWT\\JWK' => __DIR__ . '/..' . '/firebase/php-jwt/src/JWK.php',
|
109 |
'Firebase\\JWT\\JWT' => __DIR__ . '/..' . '/firebase/php-jwt/src/JWT.php',
|
110 |
'Firebase\\JWT\\SignatureInvalidException' => __DIR__ . '/..' . '/firebase/php-jwt/src/SignatureInvalidException.php',
|
|
|
|
|
111 |
);
|
112 |
|
113 |
public static function getInitializer(ClassLoader $loader)
|
114 |
{
|
115 |
return \Closure::bind(function () use ($loader) {
|
116 |
-
$loader->prefixLengthsPsr4 =
|
117 |
-
$loader->prefixDirsPsr4 =
|
118 |
-
$loader->classMap =
|
119 |
|
120 |
}, null, ClassLoader::class);
|
121 |
}
|
4 |
|
5 |
namespace Composer\Autoload;
|
6 |
|
7 |
+
class ComposerStaticInit84b4678024c245f52b85a7757a5a448f
|
8 |
{
|
9 |
public static $prefixLengthsPsr4 = array (
|
10 |
'F' =>
|
72 |
'CreativeMail\\Integrations\\Integration' => __DIR__ . '/../..' . '/src/integrations/integration.php',
|
73 |
'CreativeMail\\Managers\\AdminManager' => __DIR__ . '/../..' . '/src/managers/admin-manager.php',
|
74 |
'CreativeMail\\Managers\\ApiManager' => __DIR__ . '/../..' . '/src/managers/api-manager.php',
|
75 |
+
'CreativeMail\\Managers\\EmailManager' => __DIR__ . '/../..' . '/src/managers/email-manager.php',
|
76 |
'CreativeMail\\Managers\\InstanceManager' => __DIR__ . '/../..' . '/src/managers/instance-manager.php',
|
77 |
'CreativeMail\\Managers\\IntegrationManager' => __DIR__ . '/../..' . '/src/managers/integration-manager.php',
|
78 |
+
'CreativeMail\\Modules\\Api\\Models\\ApiRequestItem' => __DIR__ . '/../..' . '/src/modules/api/Models/ApiRequestItem.php',
|
79 |
+
'CreativeMail\\Modules\\Api\\Processes\\ApiBackgroundProcess' => __DIR__ . '/../..' . '/src/modules/api/Processes/ApiBackgroundProcess.php',
|
80 |
'CreativeMail\\Modules\\Blog\\Models\\BlogAttachment' => __DIR__ . '/../..' . '/src/modules/blog/models/BlogAttachment.php',
|
81 |
'CreativeMail\\Modules\\Blog\\Models\\BlogInformation' => __DIR__ . '/../..' . '/src/modules/blog/models/BlogInformation.php',
|
82 |
'CreativeMail\\Modules\\Blog\\Models\\BlogPost' => __DIR__ . '/../..' . '/src/modules/blog/models/BlogPost.php',
|
83 |
'CreativeMail\\Modules\\Contacts\\Handlers\\BaseContactFormPluginHandler' => __DIR__ . '/../..' . '/src/modules/contacts/Handlers/BaseContactFormPluginHandler.php',
|
84 |
'CreativeMail\\Modules\\Contacts\\Handlers\\ContactFormSevenPluginHandler' => __DIR__ . '/../..' . '/src/modules/contacts/Handlers/ContactFormSevenPluginHandler.php',
|
85 |
+
'CreativeMail\\Modules\\Contacts\\Handlers\\GravityFormsPluginHandler' => __DIR__ . '/../..' . '/src/modules/contacts/Handlers/GravityFormsPluginHandler.php',
|
86 |
+
'CreativeMail\\Modules\\Contacts\\Handlers\\JetpackPluginHandler' => __DIR__ . '/../..' . '/src/modules/contacts/Handlers/JetpackPluginHandler.php',
|
87 |
'CreativeMail\\Modules\\Contacts\\Handlers\\NewsLetterContactFormPluginHandler' => __DIR__ . '/../..' . '/src/modules/contacts/Handlers/NewsLetterContactFormPluginHandler.php',
|
88 |
'CreativeMail\\Modules\\Contacts\\Handlers\\WooCommercePluginHandler' => __DIR__ . '/../..' . '/src/modules/contacts/Handlers/WooCommercePluginHandler.php',
|
89 |
'CreativeMail\\Modules\\Contacts\\Handlers\\WpFormsLitePluginHandler' => __DIR__ . '/../..' . '/src/modules/contacts/Handlers/WpFormsLitePluginHandler.php',
|
92 |
'CreativeMail\\Modules\\Contacts\\Models\\ContactModel' => __DIR__ . '/../..' . '/src/modules/contacts/models/ContactModel.php',
|
93 |
'CreativeMail\\Modules\\Contacts\\Models\\OptActionBy' => __DIR__ . '/../..' . '/src/modules/contacts/models/OptActionBy.php',
|
94 |
'CreativeMail\\Modules\\Contacts\\Services\\ContactsSyncService' => __DIR__ . '/../..' . '/src/modules/contacts/Services/ContactsSyncService.php',
|
95 |
+
'CreativeMail\\Modules\\WooCommerce\\Models\\WCInformationModel' => __DIR__ . '/../..' . '/src/modules/woocommerce/models/WCInformationModel.php',
|
96 |
'CreativeMail\\Modules\\WooCommerce\\Models\\WCProductModel' => __DIR__ . '/../..' . '/src/modules/woocommerce/models/WCProductModel.php',
|
97 |
'CreativeMail\\Modules\\WooCommerce\\Models\\WCStoreInformation' => __DIR__ . '/../..' . '/src/modules/woocommerce/models/WCStoreInformation.php',
|
98 |
'Defuse\\Crypto\\Core' => __DIR__ . '/..' . '/defuse/php-encryption/src/Core.php',
|
114 |
'Firebase\\JWT\\JWK' => __DIR__ . '/..' . '/firebase/php-jwt/src/JWK.php',
|
115 |
'Firebase\\JWT\\JWT' => __DIR__ . '/..' . '/firebase/php-jwt/src/JWT.php',
|
116 |
'Firebase\\JWT\\SignatureInvalidException' => __DIR__ . '/..' . '/firebase/php-jwt/src/SignatureInvalidException.php',
|
117 |
+
'WP_Async_Request' => __DIR__ . '/..' . '/a5hleyrich/wp-background-processing/classes/wp-async-request.php',
|
118 |
+
'WP_Background_Process' => __DIR__ . '/..' . '/a5hleyrich/wp-background-processing/classes/wp-background-process.php',
|
119 |
);
|
120 |
|
121 |
public static function getInitializer(ClassLoader $loader)
|
122 |
{
|
123 |
return \Closure::bind(function () use ($loader) {
|
124 |
+
$loader->prefixLengthsPsr4 = ComposerStaticInit84b4678024c245f52b85a7757a5a448f::$prefixLengthsPsr4;
|
125 |
+
$loader->prefixDirsPsr4 = ComposerStaticInit84b4678024c245f52b85a7757a5a448f::$prefixDirsPsr4;
|
126 |
+
$loader->classMap = ComposerStaticInit84b4678024c245f52b85a7757a5a448f::$classMap;
|
127 |
|
128 |
}, null, ClassLoader::class);
|
129 |
}
|
vendor/composer/installed.json
CHANGED
@@ -1,4 +1,42 @@
|
|
1 |
[
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2 |
{
|
3 |
"name": "defuse/php-encryption",
|
4 |
"version": "v2.2.1",
|
1 |
[
|
2 |
+
{
|
3 |
+
"name": "a5hleyrich/wp-background-processing",
|
4 |
+
"version": "1.0.1",
|
5 |
+
"version_normalized": "1.0.1.0",
|
6 |
+
"source": {
|
7 |
+
"type": "git",
|
8 |
+
"url": "https://github.com/A5hleyRich/wp-background-processing.git",
|
9 |
+
"reference": "1f070aab5058dbaf45d5435a343033ddd8a641b1"
|
10 |
+
},
|
11 |
+
"dist": {
|
12 |
+
"type": "zip",
|
13 |
+
"url": "https://api.github.com/repos/A5hleyRich/wp-background-processing/zipball/1f070aab5058dbaf45d5435a343033ddd8a641b1",
|
14 |
+
"reference": "1f070aab5058dbaf45d5435a343033ddd8a641b1",
|
15 |
+
"shasum": ""
|
16 |
+
},
|
17 |
+
"require": {
|
18 |
+
"php": ">=5.2"
|
19 |
+
},
|
20 |
+
"time": "2018-02-12T09:24:05+00:00",
|
21 |
+
"type": "library",
|
22 |
+
"installation-source": "dist",
|
23 |
+
"autoload": {
|
24 |
+
"classmap": [
|
25 |
+
"classes/"
|
26 |
+
]
|
27 |
+
},
|
28 |
+
"notification-url": "https://packagist.org/downloads/",
|
29 |
+
"license": [
|
30 |
+
"GPL-2.0-only"
|
31 |
+
],
|
32 |
+
"authors": [
|
33 |
+
{
|
34 |
+
"name": "Ashley Rich",
|
35 |
+
"email": "hello@ashleyrich.com"
|
36 |
+
}
|
37 |
+
],
|
38 |
+
"description": "WP Background Processing can be used to fire off non-blocking asynchronous requests or as a background processing tool, allowing you to queue tasks."
|
39 |
+
},
|
40 |
{
|
41 |
"name": "defuse/php-encryption",
|
42 |
"version": "v2.2.1",
|