PluginProbe
SellKit – Funnel builder and checkout optimizer for WooCommerce to sell more, faster / 2.3.0
SellKit – Funnel builder and checkout optimizer for WooCommerce to sell more, faster v2.3.0
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.0, at sellkit.php

713 lines 15.4 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.0
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 $this->db = new Database();
173
174 add_action( 'plugins_loaded', [ $this, 'check_if_has_sellkit_pro' ], 11 );
175 add_action( 'plugins_loaded', [ $this, 'plugins_loaded' ] );
176 add_action( 'init', [ $this, 'init' ] );
177 add_action( 'admin_init', [ $this, 'admin_init' ] );
178 add_action( 'admin_menu', [ $this, 'register_admin_menu' ] );
179 add_action( 'admin_menu', [ $this, 'register_admin_settings_menu' ], 12 );
180
181 // Editor script.
182 add_action( 'elementor/editor/before_enqueue_scripts', [ $this, 'enqueue_editor_script' ] );
183
184 add_action( 'requests-curl.before_request', [ $this, 'actions_before_curl_requests' ], 9999 );
185
186 // Register activation hook.
187 register_activation_hook( __FILE__, array( $this, 'activation' ) );
188
189 if ( ! $this->is_sellkit_screen() ) {
190 return;
191 }
192
193 add_action( 'admin_enqueue_scripts', [ $this, 'enqueue_admin_scripts' ] );
194 add_action( 'admin_head', [ $this, 'remove_notice_for_sellkit_pages' ] );
195 add_filter( 'admin_body_class', [ $this, 'sellkit_admin_body_class' ] );
196 }
197
198 /**
199 * Actions before all curl requests.
200 *
201 * @since 1.5.4
202 * @return void
203 */
204 public function actions_before_curl_requests() {
205 session_write_close();
206 }
207
208 /**
209 * Has sellKit pro.
210 *
211 * @since 1.1.0
212 */
213 public function check_if_has_sellkit_pro() {
214 if ( class_exists( 'Sellkit_Pro' ) ) {
215 $this->has_pro = true;
216 }
217 }
218
219 /**
220 * Defines constants used by the plugin.
221 *
222 * @since 1.1.0
223 */
224 protected function define_constants() {
225 $plugin_data = get_file_data( __FILE__, array( 'Plugin Name', 'Version' ), 'sellkit' );
226
227 self::$plugin_basename = plugin_basename( __FILE__ );
228 self::$plugin_name = array_shift( $plugin_data );
229 self::$version = array_shift( $plugin_data );
230 self::$plugin_dir = trailingslashit( plugin_dir_path( __FILE__ ) );
231 self::$plugin_url = trailingslashit( plugin_dir_url( __FILE__ ) );
232 self::$plugin_assets_url = trailingslashit( self::$plugin_url . 'assets' );
233 }
234
235 /**
236 * Plugins loaded.
237 *
238 * @since 1.1.0
239 */
240 public function plugins_loaded() {
241 if ( 'elementor' === $this->page_builder() ) {
242 $this->load_files( [
243 'elementor/class',
244 ] );
245 }
246
247 $this->load_files( [
248 'admin/class-promote-sellkit-pro',
249 ] );
250
251 if ( class_exists( 'WooCommerce' ) && 'gutenberg' === $this->page_builder() ) {
252 $this->load_files( [
253 'block-editor/helper',
254 'block-editor/class',
255 ] );
256 }
257 }
258
259 /**
260 * Do some stuff on plugin activation.
261 *
262 * @since NEXT
263 * @return void
264 */
265 public function activation() {
266 $this->load_files( [
267 'core/libraries/wp-async-request',
268 'core/libraries/wp-background-process',
269 'core/install',
270 ] );
271
272 Install::check_database_tables();
273
274 if ( empty( sellkit_get_option( 'current_db_version' ) ) ) {
275 sellkit_update_option( 'current_db_version', '1.2.7' ); // @since 1.5.0
276 }
277
278 if ( ! wp_next_scheduled( 'sellkit_update_rfm_score' ) ) {
279 wp_schedule_event( time(), 'twicedaily', 'sellkit_update_rfm_score' );
280 }
281
282 $this->sellkit_installed_time();
283 }
284
285 /**
286 * Saves sellkit installation time.
287 *
288 * @since 1.5.9
289 */
290 private function sellkit_installed_time() {
291 update_option( 'sellkit-installed-time', time() );
292 }
293
294 /**
295 * Adding sellkit class to body.
296 *
297 * @param string $classes Sellkit the sellkit class.
298 * @return string
299 */
300 public function sellkit_admin_body_class( $classes ) {
301 return "{$classes} sellkit";
302 }
303
304 /**
305 * Initialize admin.
306 *
307 * @since 1.1.0
308 */
309 public function admin_init() {
310 $this->load_files( [
311 'admin/class-notices',
312 'admin/class',
313 ] );
314
315 $this->load_files( [
316 'admin/utilities',
317 'admin/class-components',
318 'admin/components/class-list-table',
319 'admin/components/class-filters',
320 'admin/components/class-analytics',
321 'admin/class-posts',
322 'admin/settings/class-settings',
323 'admin/class-custom-tables',
324 'admin/funnel/class',
325 'admin/class-global-checkout',
326 'core/install',
327 ] );
328 }
329
330 /**
331 * Initialize.
332 *
333 * @since 1.1.0
334 */
335 public function init() {
336 $this->load_files( [
337 'admin/class-steps',
338 'utilities/functions',
339 'contact-segmentation/class',
340 'dynamic-keywords/class',
341 'core/libraries/wp-async-request',
342 'core/libraries/wp-background-process',
343 'settings/class',
344 'contact-segmentation/rfm/class',
345 'admin/settings/integration/class',
346 ] );
347
348 // Register post types.
349 $post_types = [
350 // 'sellkit-analytics',
351 'sellkit-funnels',
352 ];
353
354 foreach ( $post_types as $post_type ) {
355 register_post_type( $post_type, [
356 'public' => false,
357 ] );
358 }
359
360 load_plugin_textdomain( 'sellkit', false, dirname( plugin_basename( __FILE__ ) ) . '/languages/' );
361 }
362
363 /**
364 * Enqueue editor scripts.
365 *
366 * @since 1.1.0
367 * @return void
368 */
369 public function enqueue_editor_script() {
370 wp_enqueue_script(
371 'sellkit-editor',
372 sellkit()->plugin_url() . 'assets/dist/js/editor.min.js',
373 [ 'jquery' ],
374 self::$version,
375 true
376 );
377 }
378
379 /**
380 * Enqueue admin scripts.
381 *
382 * @since 1.1.0
383 */
384 public function enqueue_admin_scripts() {
385 $page = ! empty( $_GET['page'] ) ? $_GET['page'] : ''; // phpcs:ignore
386
387 if ( ! in_array( $page, $this->sellkit_menus, true ) ) {
388 return false;
389 }
390
391 wp_enqueue_editor();
392
393 wp_enqueue_script(
394 'sellkit',
395 sellkit()->plugin_url() . 'assets/dist/admin/sellkit.js',
396 [ 'lodash', 'wp-element', 'wp-i18n', 'wp-util' ],
397 sellkit()->version(),
398 true
399 );
400
401 wp_localize_script(
402 'sellkit',
403 'sellkit',
404 $this->get_localize_data()
405 );
406
407 wp_enqueue_style(
408 'sellkit',
409 sellkit()->plugin_url() . 'assets/dist/admin/sellkit.css',
410 [],
411 sellkit()->version()
412 );
413
414 wp_set_script_translations( 'sellkit', 'sellkit', sellkit()->plugin_dir() . 'languages' );
415 }
416
417 /**
418 * Register admin menu.
419 *
420 * @since 1.1.0
421 * @SuppressWarnings(PHPMD.NPathComplexity)
422 */
423 public function register_admin_menu() {
424 $menu_name = esc_html__( 'Sellkit', 'sellkit' );
425 $initial_page = 'sellkit-dashboard';
426 $submenu = [
427 'sellkit-dashboard' => esc_html__( 'Dashboard', 'sellkit' ),
428 'sellkit-funnel' => esc_html__( 'Funnels', 'sellkit' ),
429 'sellkit-checkout' => esc_html__( 'Global Checkout', 'sellkit' ),
430 ];
431
432 $submenu = apply_filters( 'sellkit_sub_menu', $submenu );
433
434 $svg_file = wp_remote_get( self::plugin_url() . 'assets/img/icons/sellkit-dashboard.svg' );
435
436 add_menu_page(
437 $menu_name,
438 $menu_name,
439 'manage_options',
440 $initial_page,
441 [ $this, 'register_admin_menu_callback' ],
442 'data:image/svg+xml;base64,' . base64_encode( wp_remote_retrieve_body( $svg_file ) ),
443 '58.1'
444 );
445
446 foreach ( $submenu as $slug => $title ) {
447 add_submenu_page(
448 $initial_page,
449 "{$menu_name} {$title}",
450 $title,
451 'edit_theme_options',
452 $slug,
453 [ $this, 'register_admin_menu_callback' ]
454 );
455 }
456 }
457
458 /**
459 * Adds settings menu.
460 *
461 * @since 1.1.0
462 */
463 public function register_admin_settings_menu() {
464 add_submenu_page(
465 'sellkit-dashboard',
466 esc_html__( 'Sellkit', 'sellkit' ) . ' ' . esc_html__( 'Settings', 'sellkit' ),
467 esc_html__( 'Settings', 'sellkit' ),
468 'edit_theme_options',
469 'sellkit-settings',
470 [ $this, 'register_admin_menu_callback' ]
471 );
472 }
473
474 /**
475 * Register admin menu callback.
476 *
477 * @since 1.1.0
478 */
479 public function register_admin_menu_callback() {
480 ?>
481 <div id="wrap" class="wrap">
482 <!-- It's required for notices, otherwise WP adds the notices wherever it finds the first heading element. -->
483 <h1></h1>
484 <div id="sellkit-root"></div>
485 </div>
486 <?php
487 }
488
489 /**
490 * Check if in SellKit pages.
491 *
492 * @since 1.1.0
493 *
494 * @return boolean SellKit screen.
495 */
496 private function is_sellkit_screen() {
497 $page = sellkit_htmlspecialchars( INPUT_GET, 'page' );
498
499 return (
500 is_admin() &&
501 isset( $page ) &&
502 strpos( $page, 'sellkit' ) !== false
503 );
504 }
505
506 /**
507 * Get localize data.
508 *
509 * @since 1.1.0
510 *
511 * @return array
512 */
513 public function get_localize_data() {
514 return [
515 'nonce' => wp_create_nonce( 'sellkit' ),
516 'assetsUrl' => self::$plugin_assets_url,
517 'dynamicKeywords' => Sellkit_Dynamic_Keywords::$keywords['contact_segmentation'],
518 'defaultFunnelSteps' => Sellkit_Admin_Steps::get_default_funnel_steps(),
519 'woocommerceSettings' => $this->get_woocommerce_settings_data(),
520 'contactSegmentation' => [
521 'conditionsOperators' => Operators::$condition_operator_names,
522 'operators' => Operators::$names,
523 'conditionsData' => Conditions::$data,
524 'browserLanguages' => Conditions\Browser_Language::browser_languages_array(),
525 ],
526 'adminUrl' => admin_url(),
527 'url' => site_url(),
528 'timezones' => timezone_identifiers_list(),
529 'defaultSettings' => [
530 'defaultTimezone' => get_option( 'timezone_string' ),
531 ],
532 'elementorActivation' => class_exists( 'Elementor\Plugin' ) ? true : false,
533 'funnelsTemplateSource' => Funnel::SELLKIT_FUNNELS_TEMPLATE_SOURCE,
534 'removedContentBoxes' => Sellkit_Admin_Settings::get_removed_content_box(),
535 'sellkitProIsActive' => $this->has_pro,
536 'wcIsActivated' => $this->has_valid_dependencies(),
537 'activeTheme' => wp_get_theme()->get( 'Name' ),
538 'pageBuilder' => $this->page_builder(),
539 ];
540 }
541
542 /**
543 * Get page builder.
544 *
545 * @since 2.3.0
546 * @return string
547 */
548 public function page_builder() {
549 $default = 'gutenberg';
550
551 if ( class_exists( 'Elementor\Plugin' ) ) {
552 $default = 'elementor';
553 }
554
555 $page_builder = sellkit_get_option( 'page_builder', '' );
556
557 if ( empty( $page_builder ) ) {
558 sellkit_update_option( 'page_builder', $default );
559
560 return $default;
561 }
562
563 return $page_builder;
564 }
565
566 /**
567 * Get woocommerce settings data.
568 *
569 * @since 1.1.0
570 *
571 * @return array|boolean
572 */
573 public function get_woocommerce_settings_data() {
574 if ( ! class_exists( 'WooCommerce' ) ) {
575 return false;
576 }
577
578 return [
579 'currencyFormatNumDecimals' => wc_get_price_decimals(),
580 'currencySymbol' => html_entity_decode( get_woocommerce_currency_symbol() ),
581 'currencyFormatDecimalSep' => wc_get_price_decimal_separator(),
582 'currencyFormatThousandSep' => wc_get_price_thousand_separator(),
583 'currencyPosition' => get_option( 'woocommerce_currency_pos' ),
584 'productDefaultThumbnail' => wc_placeholder_img_src(),
585 ];
586 }
587
588 /**
589 * Remove notices.
590 *
591 * @since 1.1.0
592 */
593 public function remove_notice_for_sellkit_pages() {
594 remove_all_actions( 'admin_notices' );
595 }
596
597 /**
598 * Sellkit dependencies.
599 *
600 * @since 1.1.0
601 */
602 public function has_valid_dependencies() {
603 if ( ! class_exists( 'woocommerce' ) ) {
604 return false;
605 }
606
607 return true;
608 }
609
610 /**
611 * Loads specified PHP files from the plugin includes directory.
612 *
613 * @since 1.1.0
614 *
615 * @param array $file_names The names of the files to be loaded in the includes directory.
616 */
617 public function load_files( $file_names = array() ) {
618
619 foreach ( $file_names as $file_name ) {
620 $path = self::plugin_dir() . 'includes/' . $file_name . '.php';
621
622 if ( file_exists( $path ) ) {
623 require_once $path;
624 }
625 }
626 }
627
628 /**
629 * Returns the version number of the plugin.
630 *
631 * @since 1.1.0
632 *
633 * @return string
634 */
635 public function version() {
636 return self::$version;
637 }
638
639 /**
640 * Returns the plugin basename.
641 *
642 * @since 1.1.0
643 *
644 * @return string
645 */
646 public function plugin_basename() {
647 return self::$plugin_basename;
648 }
649
650 /**
651 * Returns the plugin name.
652 *
653 * @since 1.1.0
654 *
655 * @return string
656 */
657 public function plugin_name() {
658 return self::$plugin_name;
659 }
660
661 /**
662 * Returns the plugin directory.
663 *
664 * @since 1.1.0
665 *
666 * @return string
667 */
668 public function plugin_dir() {
669 return self::$plugin_dir;
670 }
671
672 /**
673 * Returns the plugin URL.
674 *
675 * @since 1.1.0
676 *
677 * @return string
678 */
679 public function plugin_url() {
680 return self::$plugin_url;
681 }
682
683 /**
684 * Returns the plugin assets URL.
685 *
686 * @since 1.1.0
687 *
688 * @return string
689 */
690 public function plugin_assets_url() {
691 return self::$plugin_assets_url;
692 }
693 }
694 }
695
696 if ( ! function_exists( 'sellkit' ) ) {
697 /**
698 * Initialize the Sellkit.
699 *
700 * @since 1.1.0
701 */
702 function sellkit() {
703 return Sellkit::get_instance();
704 }
705 }
706
707 /**
708 * Initialize the Sellkit application.
709 *
710 * @since 1.1.0
711 */
712 sellkit();
713