PluginProbe
Kit (formerly ConvertKit) – Email Newsletter, Email Marketing, Membership, Subscribers and Landing Pages / 2.5.8
Kit (formerly ConvertKit) – Email Newsletter, Email Marketing, Membership, Subscribers and Landing Pages v2.5.8
3.4.1 3.4.0 3.3.9 3.3.8 3.3.7 3.3.6 3.3.5 3.3.4 3.3.3 3.3.2 3.3.1 2.2.0 2.2.1 2.2.2 2.2.3 2.2.4 2.2.5 2.2.6 2.2.7 2.2.8 2.2.9 2.3.0 2.3.1 2.3.2 2.3.3 All 194 releases
convertkit / includes / class-convertkit-setup.php

class-convertkit-setup.php in Kit (formerly ConvertKit) – Email Newsletter, Email Marketing, Membership, Subscribers and Landing Pages 2.5.8, at includes/class-convertkit-setup.php

532 lines 15.7 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Plugin activation, update and deactivation class.
4 *
5 * @package ConvertKit
6 * @author ConvertKit
7 */
8
9 /**
10 * Runs any steps required on plugin activation, update and deactivation.
11 *
12 * @package ConvertKit
13 * @author ConvertKit
14 * @version 1.9.7.4
15 */
16 class ConvertKit_Setup {
17
18 /**
19 * Runs routines when the Plugin is activated.
20 *
21 * @since 1.9.7.4
22 */
23 public function activate() {
24
25 // Call any functions to e.g. schedule WordPress Cron events now.
26 $posts = new ConvertKit_Resource_Posts( 'cron' );
27 $posts->schedule_cron_event();
28
29 }
30
31 /**
32 * Runs routines when the Plugin version has been updated.
33 *
34 * @since 1.9.7.4
35 */
36 public function update() {
37
38 // Get installed Plugin version.
39 $current_version = get_option( 'convertkit_version' );
40
41 // If the version number matches the plugin version, no update routines
42 // need to run.
43 if ( $current_version === CONVERTKIT_PLUGIN_VERSION ) {
44 return;
45 }
46
47 /**
48 * 2.5.4: Migrate WishList Member to ConvertKit Form Mappings
49 */
50 if ( ! $current_version || version_compare( $current_version, '2.5.4', '<' ) ) {
51 $this->migrate_wlm_none_setting();
52 $this->migrate_wlm_form_tag_mapping_settings();
53 }
54
55 /**
56 * 2.5.3: Migrate Third Party Form integrations' 'None' option values from `default` to blank.
57 */
58 if ( ! $current_version || version_compare( $current_version, '2.5.3', '<' ) ) {
59 $this->migrate_contact_form_7_none_setting();
60 $this->migrate_forminator_none_setting();
61 $this->migrate_wlm_none_setting();
62 }
63
64 /**
65 * 2.5.2: Migrate Forminator to ConvertKit Form Mappings
66 */
67 if ( ! $current_version || version_compare( $current_version, '2.5.2', '<' ) ) {
68 $this->migrate_forminator_form_mapping_settings();
69 }
70
71 /**
72 * 2.5.2: Migrate Contact Form 7 to ConvertKit Form Mappings
73 */
74 if ( ! $current_version || version_compare( $current_version, '2.5.2', '<' ) ) {
75 $this->migrate_contact_form_7_form_mapping_settings();
76 }
77
78 /**
79 * 2.5.0: Get Access token for API version 4.0 using a v3 API Key and Secret.
80 */
81 if ( ! $current_version || version_compare( $current_version, '2.5.0', '<' ) ) {
82 $this->maybe_get_access_token_by_api_key_and_secret();
83 }
84
85 /**
86 * 2.4.9.1+: Migrate ck_default_form to _wp_convertkit_term_meta[form], as Term settings
87 * support multiple options (form, position etc).
88 */
89 if ( version_compare( $current_version, '2.4.9.1', '<' ) ) {
90 $this->migrate_term_form_settings();
91 }
92
93 /**
94 * 1.6.1+: Refresh Forms, Landing Pages and Tags data stored in settings,
95 * to get new Forms Builder Settings.
96 */
97 if ( version_compare( $current_version, '1.6.1', '<' ) ) {
98 $this->refresh_resources();
99 }
100
101 /**
102 * 1.9.6+: Migrate _wp_convertkit_settings[default_form] to _wp_convertkit_settings[page_form] and
103 * _wp_convertkit_settings[post_form], now that each Post Type has its own Default Form setting
104 * in Settings > ConvertKit > General.
105 */
106 if ( version_compare( $current_version, '1.9.6', '<' ) ) {
107 $this->migrate_default_form_settings();
108 }
109
110 /**
111 * 1.9.7.4+: Schedule Post Resources' Cron event to refresh Posts cache hourly,
112 * as the activate() routine won't pick this up for existing active installations.
113 */
114 if ( version_compare( $current_version, '1.9.7.4', '<' ) ) {
115 $posts = new ConvertKit_Resource_Posts( 'cron' );
116 $posts->schedule_cron_event();
117 }
118
119 // Update the installed version number in the options table.
120 update_option( 'convertkit_version', CONVERTKIT_PLUGIN_VERSION );
121
122 }
123
124 /**
125 * 2.5.4: Migrate WLM settings:
126 * - Prefix any WishList Member to ConvertKit Form ID mappings with `form:`,
127 * - Prefix any WishList Member to ConvertKit Tag ID mappings with `tag:`,
128 * - Standardise the settings keys to the format {wlm_level_id}_subscribe
129 * and {wlm_level_id}_unsubscribe.
130 *
131 * @since 2.5.4
132 */
133 private function migrate_wlm_form_tag_mapping_settings() {
134
135 $convertkit_wlm_settings = new ConvertKit_Wishlist_Settings();
136
137 // Bail if no settings exist.
138 if ( ! $convertkit_wlm_settings->has_settings() ) {
139 return;
140 }
141
142 // Define new array for settings.
143 $settings = array();
144
145 // Iterate through settings.
146 foreach ( $convertkit_wlm_settings->get() as $key => $convertkit_form_or_tag_id ) {
147 // Split the settings key.
148 list( $wlm_level_id, $type ) = explode( '_', $key );
149
150 switch ( $type ) {
151 case 'form':
152 // This is the action to perform when the user is added to the WLM Level.
153 // Use a new name for the setting key to reflect this.
154 // < 2.5.4, forms were the only option here, so prefix the resource ID with `form:`.
155 $settings[ $wlm_level_id . '_add' ] = ( empty( $convertkit_form_or_tag_id ) ? '' : 'form:' . $convertkit_form_or_tag_id );
156 break;
157
158 case 'unsubscribe':
159 // This is the action to perform when the user is removed from the WLM Level.
160 // Use a new name for the setting key to reflect this.
161 // < 2.5.4, tags were the only option here, so prefix the resource ID with `tag:`.
162 $settings[ $wlm_level_id . '_remove' ] = ( empty( $convertkit_form_or_tag_id ) ? '' : 'tag:' . $convertkit_form_or_tag_id );
163 break;
164 }
165 }
166
167 // Update settings.
168 update_option( $convertkit_wlm_settings::SETTINGS_NAME, $settings );
169
170 }
171
172 /**
173 * 2.5.3: Migrate Third Party Form integrations' 'None' option values from `default` to blank.
174 *
175 * 2.4.9 changed the 'None' label's value from `default` to a blank string, as the v4 API's
176 * `add_subscriber_to_form()` method introduces type declarations, which would result in
177 * an uncaught TypeError when passing a non integer value.
178 *
179 * The PR for that (https://github.com/ConvertKit/convertkit-wordpress/pull/655) didn't include
180 * any tests or upgrade/migration routines to change any existing saved settings where the 'None'
181 * label's value was stored as `default`.
182 */
183 private function migrate_contact_form_7_none_setting() {
184
185 $convertkit_contact_form_7_settings = new ConvertKit_ContactForm7_Settings();
186
187 // Bail if no settings exist.
188 if ( ! $convertkit_contact_form_7_settings->has_settings() ) {
189 return;
190 }
191
192 // Get settings.
193 $settings = $convertkit_contact_form_7_settings->get();
194
195 // Iterate through settings.
196 foreach ( $settings as $contact_form_7_form_id => $convertkit_form_id ) {
197 // Skip keys that are non-numeric e.g. `creator_network_recommendations_*`.
198 if ( ! is_numeric( $contact_form_7_form_id ) ) {
199 continue;
200 }
201
202 // Change 'default' to a blank string.
203 if ( $convertkit_form_id === 'default' ) {
204 $settings[ $contact_form_7_form_id ] = '';
205 }
206 }
207
208 // Update settings.
209 update_option( $convertkit_contact_form_7_settings::SETTINGS_NAME, $settings );
210
211 }
212
213 /**
214 * 2.5.3: Migrate Third Party Form integrations' 'None' option values from `default` to blank.
215 *
216 * 2.4.9 changed the 'None' label's value from `default` to a blank string, as the v4 API's
217 * `add_subscriber_to_form()` method introduces type declarations, which would result in
218 * an uncaught TypeError when passing a non integer value.
219 *
220 * The PR for that (https://github.com/ConvertKit/convertkit-wordpress/pull/655) didn't include
221 * any tests or upgrade/migration routines to change any existing saved settings where the 'None'
222 * label's value was stored as `default`.
223 */
224 private function migrate_forminator_none_setting() {
225
226 $convertkit_forminator_settings = new ConvertKit_Forminator_Settings();
227
228 // Bail if no settings exist.
229 if ( ! $convertkit_forminator_settings->has_settings() ) {
230 return;
231 }
232
233 // Get settings.
234 $settings = $convertkit_forminator_settings->get();
235
236 // Iterate through settings.
237 foreach ( $settings as $forminator_form_id => $convertkit_form_id ) {
238 // Skip keys that are non-numeric e.g. `creator_network_recommendations_*`.
239 if ( ! is_numeric( $forminator_form_id ) ) {
240 continue;
241 }
242
243 // Change 'default' to a blank string.
244 if ( $convertkit_form_id === 'default' ) {
245 $settings[ $forminator_form_id ] = '';
246 }
247 }
248
249 // Update settings.
250 update_option( $convertkit_forminator_settings::SETTINGS_NAME, $settings );
251
252 }
253
254 /**
255 * 2.5.3: Migrate Third Party Form integrations' 'None' option values from `default` to blank.
256 *
257 * 2.4.9 changed the 'None' label's value from `default` to a blank string, as the v4 API's
258 * `add_subscriber_to_form()` method introduces type declarations, which would result in
259 * an uncaught TypeError when passing a non integer value.
260 *
261 * The PR for that (https://github.com/ConvertKit/convertkit-wordpress/pull/655) didn't include
262 * any tests or upgrade/migration routines to change any existing saved settings where the 'None'
263 * label's value was stored as `default`.
264 */
265 private function migrate_wlm_none_setting() {
266
267 $convertkit_wlm_settings = new ConvertKit_Wishlist_Settings();
268
269 // Bail if no settings exist.
270 if ( ! $convertkit_wlm_settings->has_settings() ) {
271 return;
272 }
273
274 // Get settings.
275 $settings = $convertkit_wlm_settings->get();
276
277 // Iterate through settings.
278 foreach ( $settings as $wlm_level_id => $value ) {
279 // Change 'default' to a blank string.
280 if ( $value === 'default' ) {
281 $settings[ $wlm_level_id ] = '';
282 }
283 }
284
285 // Update settings.
286 update_option( $convertkit_wlm_settings::SETTINGS_NAME, $settings );
287
288 }
289
290 /**
291 * 2.5.2: Prefix any Forminator to ConvertKit Form ID mappings with `form:`, now that
292 * the Plugin supports adding a subscriber to a Form, Tag or Sequence.
293 *
294 * @since 2.5.2
295 */
296 private function migrate_forminator_form_mapping_settings() {
297
298 $convertkit_forminator_settings = new ConvertKit_Forminator_Settings();
299
300 // Bail if no settings exist.
301 if ( ! $convertkit_forminator_settings->has_settings() ) {
302 return;
303 }
304
305 // Get settings.
306 $settings = $convertkit_forminator_settings->get();
307
308 // Iterate through settings.
309 foreach ( $settings as $forminator_form_id => $convertkit_form_id ) {
310 // Skip keys that are non-numeric e.g. `creator_network_recommendations_*`.
311 if ( ! is_numeric( $forminator_form_id ) ) {
312 continue;
313 }
314
315 // Skip values that are blank i.e. no ConvertKit Form ID specified.
316 if ( empty( $convertkit_form_id ) ) {
317 continue;
318 }
319
320 // Skip values that are non-numeric i.e. the `form_` prefix was already added.
321 // This should never happen as this routine runs once, but this is a sanity check.
322 if ( ! is_numeric( $convertkit_form_id ) ) {
323 continue;
324 }
325
326 // Prefix the ConvertKit Form ID with `form_`.
327 $settings[ $forminator_form_id ] = 'form:' . $convertkit_form_id;
328 }
329
330 // Update settings.
331 update_option( $convertkit_forminator_settings::SETTINGS_NAME, $settings );
332
333 }
334
335 /**
336 * 2.5.2: Prefix any Contact Form 7 to ConvertKit Form ID mappings with `form:`, now that
337 * the Plugin supports adding a subscriber to a Form, Tag or Sequence.
338 *
339 * @since 2.5.2
340 */
341 private function migrate_contact_form_7_form_mapping_settings() {
342
343 $convertkit_contact_form_7_settings = new ConvertKit_ContactForm7_Settings();
344
345 // Bail if no settings exist.
346 if ( ! $convertkit_contact_form_7_settings->has_settings() ) {
347 return;
348 }
349
350 // Get settings.
351 $settings = $convertkit_contact_form_7_settings->get();
352
353 // Iterate through settings.
354 foreach ( $settings as $contact_form_7_form_id => $convertkit_form_id ) {
355 // Skip keys that are non-numeric e.g. `creator_network_recommendations_*`.
356 if ( ! is_numeric( $contact_form_7_form_id ) ) {
357 continue;
358 }
359
360 // Skip values that are blank i.e. no ConvertKit Form ID specified.
361 if ( empty( $convertkit_form_id ) ) {
362 continue;
363 }
364
365 // Skip values that are non-numeric i.e. the `form_` prefix was already added.
366 // This should never happen as this routine runs once, but this is a sanity check.
367 if ( ! is_numeric( $convertkit_form_id ) ) {
368 continue;
369 }
370
371 // Prefix the ConvertKit Form ID with `form_`.
372 $settings[ $contact_form_7_form_id ] = 'form:' . $convertkit_form_id;
373 }
374
375 // Update settings.
376 update_option( $convertkit_contact_form_7_settings::SETTINGS_NAME, $settings );
377
378 }
379
380 /**
381 * 2.5.0: Fetch an Access Token, Refresh Token and Expiry for v4 API use
382 * based on the Plugin setting's v3 API Key and Secret.
383 *
384 * @since 2.5.0
385 */
386 private function maybe_get_access_token_by_api_key_and_secret() {
387
388 $convertkit_settings = new ConvertKit_Settings();
389
390 // Bail if an Access Token exists; we don't need to fetch another one.
391 if ( $convertkit_settings->has_access_token() ) {
392 return;
393 }
394
395 // Bail if no API Key or Secret.
396 if ( empty( $convertkit_settings->get_api_key() ) ) {
397 return;
398 }
399 if ( empty( $convertkit_settings->get_api_secret() ) ) {
400 return;
401 }
402
403 // Get Access Token by API Key and Secret.
404 $api = new ConvertKit_API_V4( CONVERTKIT_OAUTH_CLIENT_ID, CONVERTKIT_OAUTH_CLIENT_REDIRECT_URI );
405 $result = $api->get_access_token_by_api_key_and_secret(
406 $convertkit_settings->get_api_key(),
407 $convertkit_settings->get_api_secret()
408 );
409
410 // Bail if an error occured.
411 if ( is_wp_error( $result ) ) {
412 return;
413 }
414
415 // Store the new credentials.
416 // We don't use update_credentials(), because the response
417 // includes an `expires_at`, not a `created_at` and `expires_in`.
418 $convertkit_settings->save(
419 array(
420 'access_token' => $result['oauth']['access_token'],
421 'refresh_token' => $result['oauth']['refresh_token'],
422 'token_expires' => $result['oauth']['expires_at'],
423 )
424 );
425
426 }
427
428 /**
429 * Migrate ck_default_form to _wp_convertkit_term_meta[form], as Term settings
430 * support multiple options (form, position etc).
431 *
432 * @since 2.4.9.1
433 */
434 private function migrate_term_form_settings() {
435
436 // Get all Terms that have ConvertKit settings defined.
437 $query = new WP_Term_Query(
438 array(
439 'taxonomy' => 'category',
440 'hide_empty' => false,
441 'fields' => 'ids',
442 'meta_query' => array(
443 array(
444 'key' => 'ck_default_form',
445 'comparison' => 'EXISTS',
446 ),
447 ),
448 )
449 );
450
451 // Bail if no Terms exist.
452 if ( ! $query->terms ) {
453 return;
454 }
455
456 // Iterate through Terms, mapping settings.
457 foreach ( $query->terms as $term_id ) {
458 $term_settings = new ConvertKit_Term( $term_id );
459 $term_settings->save(
460 array(
461 'form' => get_term_meta( $term_id, 'ck_default_form', true ), // Fetch form setting from old meta key.
462 'form_position' => '', // Default to no position.
463 )
464 );
465
466 // Delete old Term meta.
467 delete_term_meta( $term_id, 'ck_default_form' );
468 }
469
470 }
471
472 /**
473 * 1.9.6+: Migrate _wp_convertkit_settings[default_form] to _wp_convertkit_settings[page_form] and
474 * _wp_convertkit_settings[post_form], now that each Post Type has its own Default Form setting
475 * in Settings > ConvertKit > General.
476 */
477 private function migrate_default_form_settings() {
478
479 $convertkit_settings = new ConvertKit_Settings();
480
481 // Bail if no default_form setting exists.
482 $settings = get_option( $convertkit_settings::SETTINGS_NAME );
483 if ( ! $settings ) {
484 return;
485 }
486 if ( ! array_key_exists( 'default_form', $settings ) ) {
487 return;
488 }
489
490 // Restructure settings.
491 $settings['page_form'] = $settings['default_form'];
492 $settings['post_form'] = $settings['default_form'];
493
494 // Remove obsolete default_form setting.
495 unset( $settings['default_form'] );
496
497 // Update.
498 update_option( $convertkit_settings::SETTINGS_NAME, $settings );
499
500 }
501
502 /**
503 * 1.6.1: Refresh Forms, Landing Pages and Tags data stored in settings,
504 * to get new Forms Builder Settings.
505 */
506 private function refresh_resources() {
507
508 $forms = new ConvertKit_Resource_Forms( 'setup' );
509 $landing_pages = new ConvertKit_Resource_Landing_Pages( 'setup' );
510 $tags = new ConvertKit_Resource_Tags( 'setup' );
511
512 $forms->refresh();
513 $landing_pages->refresh();
514 $tags->refresh();
515
516 }
517
518 /**
519 * Runs routines when the Plugin is deactivated.
520 *
521 * @since 1.9.7.4
522 */
523 public function deactivate() {
524
525 // Call any functions to e.g. unschedule WordPress Cron events now.
526 $posts = new ConvertKit_Resource_Posts( 'cron' );
527 $posts->unschedule_cron_event();
528
529 }
530
531 }
532