PluginProbe
SellKit – Funnel builder and checkout optimizer for WooCommerce to sell more, faster / 2.3.6
SellKit – Funnel builder and checkout optimizer for WooCommerce to sell more, faster v2.3.6
2.6.0 trunk 1.1.0 1.1.4 1.2.1 1.2.2 1.2.3 1.2.5 1.2.9 1.3.1 1.3.2 1.5.0 1.5.1 1.5.4 1.5.7 1.5.8 1.5.9 1.6.2 1.6.5 1.6.8 1.7.2 1.7.4 1.7.5 1.7.9 1.8.1 All 42 releases
sellkit / sellkit.php

sellkit.php in SellKit – Funnel builder and checkout optimizer for WooCommerce to sell more, faster 2.3.6, at sellkit.php

722 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 Name: Sellkit
4 * Plugin URI: https://getsellkit.com/
5 * Description: Build unlimited sales funnels, one-click order bumps and upsells, custom thank you pages, and more. The free version of SellKit also offers a huge round of features to optimize your WooCommerce store: build and style single or multi-step checkout pages with advanced styling options. Add, remove & reorder form fields. Fasten the form submission process with pre-populated form data, Instant form validation, and removing cart page. All this and more is 100% free and for an unlimited number of sites.
6 * Version: 2.3.6
7 * Author: Artbees
8 * Author URI: https://artbees.net
9 * Text Domain: sellkit
10 * License: GPL2
11 *
12 * @package Sellkit
13 */
14
15 use Sellkit\Admin\Funnel\Funnel;
16 use Sellkit\Admin\Settings\Sellkit_Admin_Settings;
17 use Sellkit\Contact_Segmentation\Conditions;
18 use Sellkit\Contact_Segmentation\Operators;
19 use Sellkit\Core\Install;
20 use Sellkit\Database;
21 use Sellkit\Product_Meta_Key\Sellkit_Product_Meta_Key;
22
23 defined( 'ABSPATH' ) || die();
24
25 /**
26 * Check If sellkit Class exists.
27 *
28 * @SuppressWarnings(PHPMD.ExcessiveClassComplexity)
29 */
30 if ( ! class_exists( 'Sellkit' ) ) {
31
32 /**
33 * SellKit class.
34 *
35 * @since 1.1.0
36 */
37 class Sellkit {
38
39 /**
40 * Class instance.
41 *
42 * @since 1.1.0
43 * @var Sellkit
44 */
45 private static $instance = null;
46
47 /**
48 * The plugin version number.
49 *
50 * @since 1.1.0
51 *
52 * @access private
53 * @var string
54 */
55 private static $version;
56
57 /**
58 * The plugin basename.
59 *
60 * @since 1.1.0
61 *
62 * @access private
63 * @var string
64 */
65 private static $plugin_basename;
66
67 /**
68 * The plugin name.
69 *
70 * @since 1.1.0
71 *
72 * @access private
73 * @var string
74 */
75 private static $plugin_name;
76
77 /**
78 * The plugin directory.
79 *
80 * @since 1.1.0
81 *
82 * @access private
83 * @var string
84 */
85 public static $plugin_dir;
86
87 /**
88 * The plugin URL.
89 *
90 * @since 1.1.0
91 *
92 * @access private
93 * @var string
94 */
95 private static $plugin_url;
96
97 /**
98 * The plugin assets URL.
99 *
100 * @since 1.1.0
101 * @access public
102 *
103 * @var string
104 */
105 public static $plugin_assets_url;
106
107 /**
108 * Database object.
109 *
110 * @since 1.1.0
111 * @access public
112 * @var Database
113 */
114 public $db;
115
116 /**
117 * Sellkit menus.
118 *
119 * @since 1.1.0
120 * @var array Sellkit menus.
121 */
122 public $sellkit_menus = [
123 'sellkit-dashboard',
124 'sellkit-funnel',
125 'sellkit-settings',
126 'sellkit-checkout',
127 ];
128
129 /**
130 * Has pro plugin or not.
131 *
132 * @since 1.1.0
133 * @var array Checks if has pro or not.
134 */
135 public $has_pro = false;
136
137 /**
138 * Get a class instance.
139 *
140 * @since 1.1.0
141 *
142 * @return Sellkit Class
143 */
144 public static function get_instance() {
145 if ( is_null( self::$instance ) ) {
146 self::$instance = new self();
147 }
148
149 return self::$instance;
150 }
151
152 /**
153 * Class constructor.
154 *
155 * @since 1.1.0
156 */
157 public function __construct() {
158 $this->define_constants();
159
160 $this->load_files( [
161 'db',
162 'functions',
163 'funnel/redirect',
164 'funnel/homepage',
165 'funnel/analytics/data-updater',
166 'global-checkout/class',
167 'funnel/class',
168 'funnel/contacts/base-contacts',
169 'funnel/steps',
170 ] );
171
172 if ( class_exists( 'SitePress' ) ) {
173 $this->load_files([
174 'compatibility/wpml/module',
175 'compatibility/module',
176 ] );
177 }
178
179 $this->db = new Database();
180
181 add_action( 'plugins_loaded', [ $this, 'check_if_has_sellkit_pro' ], 11 );
182 add_action( 'plugins_loaded', [ $this, 'plugins_loaded' ] );
183 add_action( 'init', [ $this, 'init' ] );
184 add_action( 'admin_init', [ $this, 'admin_init' ] );
185 add_action( 'admin_menu', [ $this, 'register_admin_menu' ] );
186 add_action( 'admin_menu', [ $this, 'register_admin_settings_menu' ], 12 );
187
188 // Editor script.
189 add_action( 'elementor/editor/before_enqueue_scripts', [ $this, 'enqueue_editor_script' ] );
190
191 add_action( 'requests-curl.before_request', [ $this, 'actions_before_curl_requests' ], 9999 );
192
193 // Register activation hook.
194 register_activation_hook( __FILE__, array( $this, 'activation' ) );
195
196 if ( ! $this->is_sellkit_screen() ) {
197 return;
198 }
199
200 add_action( 'admin_enqueue_scripts', [ $this, 'enqueue_admin_scripts' ] );
201 add_action( 'admin_head', [ $this, 'remove_notice_for_sellkit_pages' ] );
202 add_filter( 'admin_body_class', [ $this, 'sellkit_admin_body_class' ] );
203 }
204
205 /**
206 * Actions before all curl requests.
207 *
208 * @since 1.5.4
209 * @return void
210 */
211 public function actions_before_curl_requests() {
212 session_write_close();
213 }
214
215 /**
216 * Has sellKit pro.
217 *
218 * @since 1.1.0
219 */
220 public function check_if_has_sellkit_pro() {
221 if ( class_exists( 'Sellkit_Pro' ) && function_exists( 'sellkit_pro' ) ) {
222 if ( sellkit_pro()->is_active_sellkit_pro ) {
223 $this->has_pro = true;
224 }
225 }
226 }
227
228 /**
229 * Defines constants used by the plugin.
230 *
231 * @since 1.1.0
232 */
233 protected function define_constants() {
234 $plugin_data = get_file_data( __FILE__, array( 'Plugin Name', 'Version' ), 'sellkit' );
235
236 self::$plugin_basename = plugin_basename( __FILE__ );
237 self::$plugin_name = array_shift( $plugin_data );
238 self::$version = array_shift( $plugin_data );
239 self::$plugin_dir = trailingslashit( plugin_dir_path( __FILE__ ) );
240 self::$plugin_url = trailingslashit( plugin_dir_url( __FILE__ ) );
241 self::$plugin_assets_url = trailingslashit( self::$plugin_url . 'assets' );
242 }
243
244 /**
245 * Plugins loaded.
246 *
247 * @since 1.1.0
248 */
249 public function plugins_loaded() {
250 if ( 'elementor' === $this->page_builder() ) {
251 $this->load_files( [
252 'elementor/class',
253 ] );
254 }
255
256 $this->load_files( [
257 'admin/class-promote-sellkit-pro',
258 ] );
259
260 if ( class_exists( 'WooCommerce' ) && 'gutenberg' === $this->page_builder() ) {
261 $this->load_files( [
262 'block-editor/helper',
263 'block-editor/class',
264 ] );
265 }
266 }
267
268 /**
269 * Do some stuff on plugin activation.
270 *
271 * @since NEXT
272 * @return void
273 */
274 public function activation() {
275 $this->load_files( [
276 'core/libraries/wp-async-request',
277 'core/libraries/wp-background-process',
278 'core/install',
279 ] );
280
281 Install::check_database_tables();
282
283 if ( empty( sellkit_get_option( 'current_db_version' ) ) ) {
284 sellkit_update_option( 'current_db_version', '1.2.7' ); // @since 1.5.0
285 }
286
287 if ( ! wp_next_scheduled( 'sellkit_update_rfm_score' ) ) {
288 wp_schedule_event( time(), 'twicedaily', 'sellkit_update_rfm_score' );
289 }
290
291 $this->sellkit_installed_time();
292 }
293
294 /**
295 * Saves sellkit installation time.
296 *
297 * @since 1.5.9
298 */
299 private function sellkit_installed_time() {
300 update_option( 'sellkit-installed-time', time() );
301 }
302
303 /**
304 * Adding sellkit class to body.
305 *
306 * @param string $classes Sellkit the sellkit class.
307 * @return string
308 */
309 public function sellkit_admin_body_class( $classes ) {
310 return "{$classes} sellkit";
311 }
312
313 /**
314 * Initialize admin.
315 *
316 * @since 1.1.0
317 */
318 public function admin_init() {
319 $this->load_files( [
320 'admin/class-notices',
321 'admin/class',
322 ] );
323
324 $this->load_files( [
325 'admin/utilities',
326 'admin/class-components',
327 'admin/components/class-list-table',
328 'admin/components/class-filters',
329 'admin/components/class-analytics',
330 'admin/class-posts',
331 'admin/settings/class-settings',
332 'admin/class-custom-tables',
333 'admin/funnel/class',
334 'admin/class-global-checkout',
335 'core/install',
336 ] );
337 }
338
339 /**
340 * Initialize.
341 *
342 * @since 1.1.0
343 */
344 public function init() {
345 $this->load_files( [
346 'admin/class-steps',
347 'utilities/functions',
348 'contact-segmentation/class',
349 'dynamic-keywords/class',
350 'core/libraries/wp-async-request',
351 'core/libraries/wp-background-process',
352 'settings/class',
353 'contact-segmentation/rfm/class',
354 'admin/settings/integration/class',
355 ] );
356
357 // Register post types.
358 $post_types = [
359 // 'sellkit-analytics',
360 'sellkit-funnels',
361 ];
362
363 foreach ( $post_types as $post_type ) {
364 register_post_type( $post_type, [
365 'public' => false,
366 ] );
367 }
368
369 load_plugin_textdomain( 'sellkit', false, dirname( plugin_basename( __FILE__ ) ) . '/languages/' );
370 }
371
372 /**
373 * Enqueue editor scripts.
374 *
375 * @since 1.1.0
376 * @return void
377 */
378 public function enqueue_editor_script() {
379 wp_enqueue_script(
380 'sellkit-editor',
381 sellkit()->plugin_url() . 'assets/dist/js/editor.min.js',
382 [ 'jquery' ],
383 self::$version,
384 true
385 );
386 }
387
388 /**
389 * Enqueue admin scripts.
390 *
391 * @since 1.1.0
392 */
393 public function enqueue_admin_scripts() {
394 $page = ! empty( $_GET['page'] ) ? $_GET['page'] : ''; // phpcs:ignore
395
396 if ( ! in_array( $page, $this->sellkit_menus, true ) ) {
397 return false;
398 }
399
400 wp_enqueue_editor();
401
402 wp_enqueue_script(
403 'sellkit',
404 sellkit()->plugin_url() . 'assets/dist/admin/sellkit.js',
405 [ 'lodash', 'wp-element', 'wp-i18n', 'wp-util' ],
406 sellkit()->version(),
407 true
408 );
409
410 wp_localize_script(
411 'sellkit',
412 'sellkit',
413 $this->get_localize_data()
414 );
415
416 wp_enqueue_style(
417 'sellkit',
418 sellkit()->plugin_url() . 'assets/dist/admin/sellkit.css',
419 [],
420 sellkit()->version()
421 );
422
423 wp_set_script_translations( 'sellkit', 'sellkit', sellkit()->plugin_dir() . 'languages' );
424 }
425
426 /**
427 * Register admin menu.
428 *
429 * @since 1.1.0
430 * @SuppressWarnings(PHPMD.NPathComplexity)
431 */
432 public function register_admin_menu() {
433 $menu_name = esc_html__( 'Sellkit', 'sellkit' );
434 $initial_page = 'sellkit-dashboard';
435 $submenu = [
436 'sellkit-dashboard' => esc_html__( 'Dashboard', 'sellkit' ),
437 'sellkit-funnel' => esc_html__( 'Funnels', 'sellkit' ),
438 'sellkit-checkout' => esc_html__( 'Global Checkout', 'sellkit' ),
439 ];
440
441 $submenu = apply_filters( 'sellkit_sub_menu', $submenu );
442
443 $svg_file = wp_remote_get( self::plugin_url() . 'assets/img/icons/sellkit-dashboard.svg' );
444
445 add_menu_page(
446 $menu_name,
447 $menu_name,
448 'manage_options',
449 $initial_page,
450 [ $this, 'register_admin_menu_callback' ],
451 'data:image/svg+xml;base64,' . base64_encode( wp_remote_retrieve_body( $svg_file ) ),
452 '58.1'
453 );
454
455 foreach ( $submenu as $slug => $title ) {
456 add_submenu_page(
457 $initial_page,
458 "{$menu_name} {$title}",
459 $title,
460 'edit_theme_options',
461 $slug,
462 [ $this, 'register_admin_menu_callback' ]
463 );
464 }
465 }
466
467 /**
468 * Adds settings menu.
469 *
470 * @since 1.1.0
471 */
472 public function register_admin_settings_menu() {
473 add_submenu_page(
474 'sellkit-dashboard',
475 esc_html__( 'Sellkit', 'sellkit' ) . ' ' . esc_html__( 'Settings', 'sellkit' ),
476 esc_html__( 'Settings', 'sellkit' ),
477 'edit_theme_options',
478 'sellkit-settings',
479 [ $this, 'register_admin_menu_callback' ]
480 );
481 }
482
483 /**
484 * Register admin menu callback.
485 *
486 * @since 1.1.0
487 */
488 public function register_admin_menu_callback() {
489 ?>
490 <div id="wrap" class="wrap">
491 <!-- It's required for notices, otherwise WP adds the notices wherever it finds the first heading element. -->
492 <h1></h1>
493 <div id="sellkit-root"></div>
494 </div>
495 <?php
496 }
497
498 /**
499 * Check if in SellKit pages.
500 *
501 * @since 1.1.0
502 *
503 * @return boolean SellKit screen.
504 */
505 private function is_sellkit_screen() {
506 $page = sellkit_htmlspecialchars( INPUT_GET, 'page' );
507
508 return (
509 is_admin() &&
510 isset( $page ) &&
511 strpos( $page, 'sellkit' ) !== false
512 );
513 }
514
515 /**
516 * Get localize data.
517 *
518 * @since 1.1.0
519 *
520 * @return array
521 */
522 public function get_localize_data() {
523 return [
524 'nonce' => wp_create_nonce( 'sellkit' ),
525 'assetsUrl' => self::$plugin_assets_url,
526 'dynamicKeywords' => Sellkit_Dynamic_Keywords::$keywords['contact_segmentation'],
527 'defaultFunnelSteps' => Sellkit_Admin_Steps::get_default_funnel_steps(),
528 'woocommerceSettings' => $this->get_woocommerce_settings_data(),
529 'contactSegmentation' => [
530 'conditionsOperators' => Operators::$condition_operator_names,
531 'operators' => Operators::$names,
532 'conditionsData' => Conditions::$data,
533 'browserLanguages' => Conditions\Browser_Language::browser_languages_array(),
534 ],
535 'adminUrl' => admin_url(),
536 'url' => site_url(),
537 'timezones' => timezone_identifiers_list(),
538 'defaultSettings' => [
539 'defaultTimezone' => get_option( 'timezone_string' ),
540 ],
541 'elementorActivation' => class_exists( 'Elementor\Plugin' ) ? true : false,
542 'funnelsTemplateSource' => Funnel::SELLKIT_FUNNELS_TEMPLATE_SOURCE,
543 'removedContentBoxes' => Sellkit_Admin_Settings::get_removed_content_box(),
544 'sellkitProIsActive' => $this->has_pro,
545 'wcIsActivated' => $this->has_valid_dependencies(),
546 'activeTheme' => wp_get_theme()->get( 'Name' ),
547 'pageBuilder' => $this->page_builder(),
548 ];
549 }
550
551 /**
552 * Get page builder.
553 *
554 * @since 2.3.0
555 * @return string
556 */
557 public function page_builder() {
558 $default = 'gutenberg';
559
560 if ( class_exists( 'Elementor\Plugin' ) ) {
561 $default = 'elementor';
562 }
563
564 $page_builder = sellkit_get_option( 'page_builder', '' );
565
566 if ( empty( $page_builder ) ) {
567 sellkit_update_option( 'page_builder', $default );
568
569 return $default;
570 }
571
572 return $page_builder;
573 }
574
575 /**
576 * Get woocommerce settings data.
577 *
578 * @since 1.1.0
579 *
580 * @return array|boolean
581 */
582 public function get_woocommerce_settings_data() {
583 if ( ! class_exists( 'WooCommerce' ) ) {
584 return false;
585 }
586
587 return [
588 'currencyFormatNumDecimals' => wc_get_price_decimals(),
589 'currencySymbol' => html_entity_decode( get_woocommerce_currency_symbol() ),
590 'currencyFormatDecimalSep' => wc_get_price_decimal_separator(),
591 'currencyFormatThousandSep' => wc_get_price_thousand_separator(),
592 'currencyPosition' => get_option( 'woocommerce_currency_pos' ),
593 'productDefaultThumbnail' => wc_placeholder_img_src(),
594 ];
595 }
596
597 /**
598 * Remove notices.
599 *
600 * @since 1.1.0
601 */
602 public function remove_notice_for_sellkit_pages() {
603 remove_all_actions( 'admin_notices' );
604 }
605
606 /**
607 * Sellkit dependencies.
608 *
609 * @since 1.1.0
610 */
611 public function has_valid_dependencies() {
612 if ( ! class_exists( 'woocommerce' ) ) {
613 return false;
614 }
615
616 return true;
617 }
618
619 /**
620 * Loads specified PHP files from the plugin includes directory.
621 *
622 * @since 1.1.0
623 *
624 * @param array $file_names The names of the files to be loaded in the includes directory.
625 */
626 public function load_files( $file_names = array() ) {
627
628 foreach ( $file_names as $file_name ) {
629 $path = self::plugin_dir() . 'includes/' . $file_name . '.php';
630
631 if ( file_exists( $path ) ) {
632 require_once $path;
633 }
634 }
635 }
636
637 /**
638 * Returns the version number of the plugin.
639 *
640 * @since 1.1.0
641 *
642 * @return string
643 */
644 public function version() {
645 return self::$version;
646 }
647
648 /**
649 * Returns the plugin basename.
650 *
651 * @since 1.1.0
652 *
653 * @return string
654 */
655 public function plugin_basename() {
656 return self::$plugin_basename;
657 }
658
659 /**
660 * Returns the plugin name.
661 *
662 * @since 1.1.0
663 *
664 * @return string
665 */
666 public function plugin_name() {
667 return self::$plugin_name;
668 }
669
670 /**
671 * Returns the plugin directory.
672 *
673 * @since 1.1.0
674 *
675 * @return string
676 */
677 public function plugin_dir() {
678 return self::$plugin_dir;
679 }
680
681 /**
682 * Returns the plugin URL.
683 *
684 * @since 1.1.0
685 *
686 * @return string
687 */
688 public function plugin_url() {
689 return self::$plugin_url;
690 }
691
692 /**
693 * Returns the plugin assets URL.
694 *
695 * @since 1.1.0
696 *
697 * @return string
698 */
699 public function plugin_assets_url() {
700 return self::$plugin_assets_url;
701 }
702 }
703 }
704
705 if ( ! function_exists( 'sellkit' ) ) {
706 /**
707 * Initialize the Sellkit.
708 *
709 * @since 1.1.0
710 */
711 function sellkit() {
712 return Sellkit::get_instance();
713 }
714 }
715
716 /**
717 * Initialize the Sellkit application.
718 *
719 * @since 1.1.0
720 */
721 sellkit();
722