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

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