PluginProbe
Kit (formerly ConvertKit) – Email Newsletter, Email Marketing, Membership, Subscribers and Landing Pages / 3.4.3
Kit (formerly ConvertKit) – Email Newsletter, Email Marketing, Membership, Subscribers and Landing Pages v3.4.3
3.4.3 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 All 196 releases
convertkit / includes / class-wp-convertkit.php

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

493 lines 14.6 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * ConvertKit class.
4 *
5 * @package ConvertKit
6 * @author ConvertKit
7 */
8
9 /**
10 * Class ConvertKit
11 *
12 * @package ConvertKit
13 * @author ConvertKit
14 */
15 class WP_ConvertKit {
16
17 /**
18 * Holds the class object.
19 *
20 * @since 1.9.6
21 *
22 * @var object
23 */
24 private static $instance;
25
26 /**
27 * Holds singleton initialized classes that include
28 * action and filter hooks.
29 *
30 * @since 1.9.6
31 *
32 * @var array
33 */
34 private $classes = array();
35
36 /**
37 * Constructor. Acts as a bootstrap to load the rest of the plugin
38 *
39 * @since 1.9.6
40 */
41 public function __construct() {
42
43 // Initialize classes that have hooks prior to the `init` hook.
44 // Divi Theme requires us to do this, although the Divi Builder Plugin works fine when loading
45 // our integration on `init`.
46 $this->classes['divi'] = new ConvertKit_Divi();
47 $this->classes['widgets'] = new ConvertKit_Widgets();
48
49 // Initialize Plugin classes on init, so the `_load_textdomain_just_in_time` warning isn't triggered.
50 add_action( 'init', array( $this, 'initialize' ), 1 );
51 add_action( 'init', array( $this, 'setup' ), 2 );
52
53 }
54
55 /**
56 * Initialize classes.
57 *
58 * @since 2.7.7
59 */
60 public function initialize() {
61
62 $this->initialize_admin();
63 $this->initialize_admin_or_frontend_editor();
64 $this->initialize_cli_cron();
65 $this->initialize_frontend();
66 $this->initialize_global();
67 $this->initialize_mcp();
68
69 }
70
71 /**
72 * Initialize classes for the WordPress Administration interface
73 *
74 * @since 1.9.6
75 */
76 private function initialize_admin() {
77
78 // Bail if this request isn't for the WordPress Administration interface.
79 if ( ! is_admin() ) {
80 return;
81 }
82
83 $this->classes['admin_bulk_edit'] = new ConvertKit_Admin_Bulk_Edit();
84 $this->classes['admin_cache_plugins'] = new ConvertKit_Admin_Cache_Plugins();
85 $this->classes['admin_category'] = new ConvertKit_Admin_Category();
86 $this->classes['admin_landing_page'] = new ConvertKit_Admin_Landing_Page();
87 $this->classes['admin_legacy_resource_notice'] = new ConvertKit_Admin_Legacy_Resource_Notice();
88 $this->classes['admin_importer_activecampaign'] = new ConvertKit_Admin_Importer_ActiveCampaign();
89 $this->classes['admin_importer_aweber'] = new ConvertKit_Admin_Importer_AWeber();
90 $this->classes['admin_importer_campaignmonitor'] = new ConvertKit_Admin_Importer_CampaignMonitor();
91 $this->classes['admin_importer_convertkit_legacy_forms'] = new ConvertKit_Admin_Importer_ConvertKit_Legacy_Forms();
92 $this->classes['admin_importer_mc4wp'] = new ConvertKit_Admin_Importer_MC4WP();
93 $this->classes['admin_importer_mailpoet'] = new ConvertKit_Admin_Importer_Mailpoet();
94 $this->classes['admin_importer_newsletter'] = new ConvertKit_Admin_Importer_Newsletter();
95 $this->classes['admin_post'] = new ConvertKit_Admin_Post();
96 $this->classes['admin_quick_edit'] = new ConvertKit_Admin_Quick_Edit();
97 $this->classes['admin_restrict_content'] = new ConvertKit_Admin_Restrict_Content();
98 $this->classes['admin_settings'] = new ConvertKit_Admin_Settings();
99 $this->classes['admin_setup_wizard_landing_page'] = new ConvertKit_Admin_Setup_Wizard_Landing_Page();
100 $this->classes['admin_setup_wizard_plugin'] = new ConvertKit_Admin_Setup_Wizard_Plugin();
101 $this->classes['admin_setup_wizard_restrict_content'] = new ConvertKit_Admin_Setup_Wizard_Restrict_Content();
102
103 /**
104 * Initialize integration classes for the WordPress Administration interface.
105 *
106 * @since 1.9.6
107 */
108 do_action( 'convertkit_initialize_admin' );
109
110 }
111
112 /**
113 * Initialize classes for the WordPress Administration interface or a frontend Page Builder
114 *
115 * @since 1.9.6
116 */
117 private function initialize_admin_or_frontend_editor() {
118
119 // Bail if this request isn't for the WordPress Administration interface and isn't for a frontend Page Builder.
120 if ( ! $this->is_admin_or_frontend_editor() ) {
121 return;
122 }
123
124 /**
125 * Initialize integration classes for the WordPress Administration interface or a frontend Page Builder.
126 *
127 * @since 1.9.6
128 */
129 do_action( 'convertkit_initialize_admin_or_frontend_editor' );
130
131 }
132
133 /**
134 * Initialize classes for WP-CLI and WP-Cron
135 *
136 * @since 2.5.2
137 */
138 private function initialize_cli_cron() {
139
140 // Bail if this isn't a CLI or CRON request.
141 if ( ! $this->is_cli() && ! $this->is_cron() ) {
142 return;
143 }
144
145 /**
146 * Initialize integration classes for WP-CLI and WP-Cron.
147 *
148 * @since 1.9.6
149 */
150 do_action( 'convertkit_initialize_cli_cron' );
151
152 }
153
154 /**
155 * Initialize classes for the frontend web site
156 *
157 * @since 1.9.6
158 */
159 private function initialize_frontend() {
160
161 // Bail if this request isn't for the frontend web site.
162 if ( is_admin() ) {
163 return;
164 }
165
166 $this->classes['cache_plugins'] = new ConvertKit_Cache_Plugins();
167 $this->classes['output'] = new ConvertKit_Output();
168 $this->classes['output_broadcasts'] = new ConvertKit_Output_Broadcasts();
169
170 /**
171 * Initialize integration classes for the frontend web site.
172 *
173 * @since 1.9.6
174 */
175 do_action( 'convertkit_initialize_frontend' );
176
177 }
178
179 /**
180 * Initialize classes required globally, across the WordPress Administration, CLI, Cron and Frontend
181 * web site.
182 *
183 * @since 1.9.6
184 */
185 private function initialize_global() {
186
187 $this->classes['admin_notices'] = new ConvertKit_Admin_Notices();
188 $this->classes['admin_tinymce'] = new ConvertKit_Admin_TinyMCE();
189 $this->classes['admin_refresh_resources'] = new ConvertKit_Admin_Refresh_Resources();
190 $this->classes['blocks_convertkit_broadcasts'] = new ConvertKit_Block_Broadcasts();
191 $this->classes['blocks_convertkit_content'] = new ConvertKit_Block_Content();
192 $this->classes['blocks_convertkit_formtrigger'] = new ConvertKit_Block_Form_Trigger();
193 $this->classes['blocks_convertkit_form'] = new ConvertKit_Block_Form();
194 $this->classes['blocks_convertkit_form_builder'] = new ConvertKit_Block_Form_Builder();
195 $this->classes['blocks_convertkit_form_builder_field_email'] = new ConvertKit_Block_Form_Builder_Field_Email();
196 $this->classes['blocks_convertkit_form_builder_field_name'] = new ConvertKit_Block_Form_Builder_Field_Name();
197 $this->classes['blocks_convertkit_form_builder_field_custom'] = new ConvertKit_Block_Form_Builder_Field_Custom();
198 $this->classes['blocks_convertkit_member_content_login'] = new ConvertKit_Block_Member_Content_Login();
199 $this->classes['blocks_convertkit_product'] = new ConvertKit_Block_Product();
200 $this->classes['block_formatter_form_link'] = new ConvertKit_Block_Formatter_Form_Link();
201 $this->classes['block_formatter_product_link'] = new ConvertKit_Block_Formatter_Product_Link();
202 $this->classes['pre_publish_action_broadcast_export'] = new ConvertKit_Pre_Publish_Action_Broadcast_Export();
203 $this->classes['plugin_sidebar_post_settings'] = new ConvertKit_Plugin_Sidebar_Post_Settings();
204 $this->classes['broadcasts_exporter'] = new ConvertKit_Broadcasts_Exporter();
205 $this->classes['broadcasts_importer'] = new ConvertKit_Broadcasts_Importer();
206 $this->classes['elementor'] = new ConvertKit_Elementor();
207 $this->classes['gutenberg'] = new ConvertKit_Gutenberg();
208 $this->classes['mcp'] = new ConvertKit_MCP();
209 $this->classes['media_library'] = new ConvertKit_Media_Library();
210 $this->classes['output_restrict_content'] = new ConvertKit_Output_Restrict_Content();
211 $this->classes['restrict_content_cache'] = new ConvertKit_Restrict_Content_Cache();
212 $this->classes['review_request'] = new ConvertKit_Review_Request( 'Kit', 'convertkit', CONVERTKIT_PLUGIN_PATH );
213 $this->classes['preview_output'] = new ConvertKit_Preview_Output();
214 $this->classes['setup'] = new ConvertKit_Setup();
215 $this->classes['shortcodes'] = new ConvertKit_Shortcodes();
216
217 /**
218 * Initialize integration classes for the frontend web site.
219 *
220 * @since 1.9.6
221 */
222 do_action( 'convertkit_initialize_global' );
223
224 }
225
226 /**
227 * Initializes the MCP server if enabled in the Plugin's settings.
228 *
229 * @since 3.4.0
230 */
231 public function initialize_mcp() {
232
233 // Bail if the MCP server is not enabled.
234 $settings = new ConvertKit_Settings_MCP();
235 if ( ! $settings->enabled() ) {
236 return;
237 }
238
239 // Bail if the Abilities API is unavailable (WordPress < 6.9).
240 if ( ! function_exists( 'wp_register_ability' ) ) {
241 return;
242 }
243
244 // Bail if PHP 7.4+ is not installed, as this is required for the MCP Adapter classes.
245 if ( version_compare( PHP_VERSION, '7.4', '<' ) ) {
246 return;
247 }
248
249 // Load MCP Adapter if another Plugin hasn't already loaded it.
250 if ( ! class_exists( 'WP\\MCP\\Core\\McpAdapter' ) ) {
251 // Bail if the WordPress MCP Adapter autoloader is missing.
252 if ( ! file_exists( CONVERTKIT_PLUGIN_PATH . '/vendor/autoload.php' ) ) {
253 return;
254 }
255
256 // Load MCP Adapter.
257 require_once CONVERTKIT_PLUGIN_PATH . '/vendor/autoload.php';
258
259 // Bail if the MCP Adapter class doesn't exist - something went wrong with the autoloader.
260 if ( ! class_exists( 'WP\\MCP\\Core\\McpAdapter' ) ) { // @phpstan-ignore-line
261 return;
262 }
263 }
264
265 // Bootstrap the MCP Adapter, per WordPress/mcp-adapter's recommended
266 // integration pattern.
267 // @see https://github.com/WordPress/mcp-adapter#using-mcp-adapter-in-your-plugin.
268 \WP\MCP\Core\McpAdapter::instance();
269
270 }
271
272 /**
273 * Runs the Plugin's initialization and update routines, which checks if
274 * the Plugin has just been updated to a newer version,
275 * and if so runs any specific processes that might be needed.
276 *
277 * @since 1.9.7.4
278 */
279 public function setup() {
280
281 $this->get_class( 'setup' )->initialize();
282 $this->get_class( 'setup' )->update();
283
284 }
285
286 /**
287 * Improved version of WordPress' is_admin(), which includes whether we're
288 * editing on the frontend using a Page Builder.
289 *
290 * @since 1.9.6
291 *
292 * @return bool Is Admin or Frontend Editor Request
293 */
294 public function is_admin_or_frontend_editor() {
295
296 // If we're in the wp-admin, return true.
297 if ( is_admin() ) {
298 return true;
299 }
300
301 // Pro.
302 if ( array_key_exists( 'REQUEST_URI', $_SERVER ) ) {
303 if ( strpos( sanitize_text_field( wp_unslash( $_SERVER['REQUEST_URI'] ) ), '/pro/' ) !== false ) {
304 return true;
305 }
306 if ( strpos( sanitize_text_field( wp_unslash( $_SERVER['REQUEST_URI'] ) ), '/x/' ) !== false ) {
307 return true;
308 }
309 if ( strpos( sanitize_text_field( wp_unslash( $_SERVER['REQUEST_URI'] ) ), 'cornerstone-endpoint' ) !== false ) {
310 return true;
311 }
312 }
313
314 // If the request global exists, check for specific request keys which tell us
315 // that we're using a frontend editor.
316 // Avada Live.
317 // phpcs:disable WordPress.Security.NonceVerification.Recommended
318 if ( array_key_exists( 'fb-edit', $_REQUEST ) ) {
319 return true;
320 }
321
322 // Beaver Builder.
323 if ( array_key_exists( 'fl_builder', $_REQUEST ) ) {
324 return true;
325 }
326
327 // Brizy.
328 if ( array_key_exists( 'brizy-edit', $_REQUEST ) ) {
329 return true;
330 }
331
332 // Cornerstone (AJAX).
333 if ( array_key_exists( '_cs_nonce', $_REQUEST ) ) {
334 return true;
335 }
336
337 // Divi.
338 if ( array_key_exists( 'et_fb', $_REQUEST ) ) {
339 return true;
340 }
341
342 // Elementor.
343 if ( array_key_exists( 'action', $_REQUEST ) && sanitize_text_field( wp_unslash( $_REQUEST['action'] ) ) === 'elementor' ) {
344 return true;
345 }
346
347 // Kallyas.
348 if ( array_key_exists( 'zn_pb_edit', $_REQUEST ) ) {
349 return true;
350 }
351
352 // Oxygen.
353 if ( array_key_exists( 'ct_builder', $_REQUEST ) ) {
354 return true;
355 }
356
357 // Thrive Architect.
358 if ( array_key_exists( 'tve', $_REQUEST ) ) {
359 return true;
360 }
361
362 // Visual Composer.
363 if ( array_key_exists( 'vcv-editable', $_REQUEST ) ) {
364 return true;
365 }
366
367 // WPBakery Page Builder.
368 if ( array_key_exists( 'vc_editable', $_REQUEST ) ) {
369 return true;
370 }
371
372 // Zion Builder.
373 if ( array_key_exists( 'action', $_REQUEST ) && sanitize_text_field( wp_unslash( $_REQUEST['action'] ) ) === 'zion_builder_active' ) {
374 return true;
375 }
376
377 // Assume we're not in the Administration interface.
378 $is_admin_or_frontend_editor = false;
379
380 /**
381 * Filters whether the current request is a WordPress Administration / Frontend Editor request or not.
382 *
383 * Page Builders can set this to true to allow ConvertKit to load its administration functionality.
384 *
385 * @since 1.9.6
386 *
387 * @param bool $is_admin_or_frontend_editor Is WordPress Administration / Frontend Editor request.
388 */
389 $is_admin_or_frontend_editor = apply_filters( 'convertkit_is_admin_or_frontend_editor', $is_admin_or_frontend_editor );
390
391 // phpcs:enable
392
393 // Return filtered result.
394 return $is_admin_or_frontend_editor;
395
396 }
397
398 /**
399 * Detects if the request is through the WP-CLI
400 *
401 * @since 1.9.6
402 *
403 * @return bool Is WP-CLI Request
404 */
405 public function is_cli() {
406
407 if ( ! defined( 'WP_CLI' ) ) {
408 return false;
409 }
410 if ( ! WP_CLI ) {
411 return false;
412 }
413
414 return true;
415
416 }
417
418 /**
419 * Detects if the request is through the WP CRON
420 *
421 * @since 1.9.6
422 *
423 * @return bool Is WP CRON Request
424 */
425 public function is_cron() {
426
427 return wp_doing_cron();
428
429 }
430
431 /**
432 * Returns the given class
433 *
434 * @since 1.9.6
435 *
436 * @param string $name Class Name.
437 * @return object Class Object
438 */
439 public function get_class( $name ) {
440
441 // If the class hasn't been loaded, throw a WordPress die screen
442 // to avoid a PHP fatal error.
443 if ( ! isset( $this->classes[ $name ] ) ) {
444 // Define the error.
445 $error = new WP_Error(
446 'convertkit_get_class',
447 sprintf(
448 /* translators: %1$s: PHP class name */
449 __( 'Kit Error: Could not load Plugin class <strong>%1$s</strong>', 'convertkit' ),
450 $name
451 )
452 );
453
454 // Depending on the request, return or display an error.
455 // Admin UI.
456 if ( is_admin() ) {
457 wp_die(
458 esc_attr( $error->get_error_message() ),
459 esc_html__( 'Kit Error', 'convertkit' ),
460 array(
461 'back_link' => true,
462 )
463 );
464 }
465
466 // Cron / CLI.
467 return $error;
468 }
469
470 // Return the class object.
471 return $this->classes[ $name ];
472
473 }
474
475 /**
476 * Returns the singleton instance of the class.
477 *
478 * @since 1.1.6
479 *
480 * @return object Class.
481 */
482 public static function get_instance() {
483
484 if ( null === self::$instance ) {
485 self::$instance = new self();
486 }
487
488 return self::$instance;
489
490 }
491
492 }
493