PluginProbe
Kit (formerly ConvertKit) – Email Newsletter, Email Marketing, Membership, Subscribers and Landing Pages / 2.6.8
Kit (formerly ConvertKit) – Email Newsletter, Email Marketing, Membership, Subscribers and Landing Pages v2.6.8
3.4.2 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 All 195 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.6.8, at includes/class-convertkit-setup.php

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