PluginProbe
SellKit – Funnel builder and checkout optimizer for WooCommerce to sell more, faster / 2.8.0
SellKit – Funnel builder and checkout optimizer for WooCommerce to sell more, faster v2.8.0
2.8.0 2.7.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 All 44 releases
← All changes | sellkit.php +118 -37 1.1.4 → 2.8.0 View file →
@@ -1,14 +1,14 @@
1 1 <?php
2 2 /**
3 - * Plugin Name: Sellkit
3 + * Plugin Name: SellKit - Funnel builder and checkout optimizer for WooCommerce to sell more, faster
4 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.1.4
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.8.0
7 7 * Author: Artbees
8 8 * Author URI: https://artbees.net
9 9 * Text Domain: sellkit
10 - * License: GPL2
10 + * License: GPLv2 or later
11 11 *
12 12 * @package Sellkit
13 13 */
14 14
@@ -122,8 +122,9 @@
122 122 public $sellkit_menus = [
123 123 'sellkit-dashboard',
124 124 'sellkit-funnel',
125 125 'sellkit-settings',
126 + 'sellkit-checkout',
126 127 ];
127 128
128 129 /**
129 130 * Has pro plugin or not.
@@ -156,15 +157,26 @@
156 157 public function __construct() {
157 158 $this->define_constants();
158 159
159 160 $this->load_files( [
161 + 'db',
160 162 'functions',
163 + 'funnel/redirect',
164 + 'funnel/homepage',
161 165 'funnel/analytics/data-updater',
166 + 'global-checkout/class',
162 167 'funnel/class',
168 + 'funnel/contacts/base-contacts',
163 169 'funnel/steps',
164 - 'db',
165 170 ] );
166 171
172 + if ( class_exists( 'SitePress' ) ) {
173 + $this->load_files([
174 + 'compatibility/wpml/module',
175 + 'compatibility/module',
176 + ] );
177 + }
178 +
167 179 $this->db = new Database();
168 180
169 181 add_action( 'plugins_loaded', [ $this, 'check_if_has_sellkit_pro' ], 11 );
170 182 add_action( 'plugins_loaded', [ $this, 'plugins_loaded' ] );
@@ -175,8 +187,10 @@
175 187
176 188 // Editor script.
177 189 add_action( 'elementor/editor/before_enqueue_scripts', [ $this, 'enqueue_editor_script' ] );
178 190
191 + add_action( 'requests-curl.before_request', [ $this, 'actions_before_curl_requests' ], 9999 );
192 +
179 193 // Register activation hook.
180 194 register_activation_hook( __FILE__, array( $this, 'activation' ) );
181 195
182 196 if ( ! $this->is_sellkit_screen() ) {
@@ -188,15 +202,27 @@
188 202 add_filter( 'admin_body_class', [ $this, 'sellkit_admin_body_class' ] );
189 203 }
190 204
191 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 + /**
192 216 * Has sellKit pro.
193 217 *
194 218 * @since 1.1.0
195 219 */
196 220 public function check_if_has_sellkit_pro() {
197 - if ( class_exists( 'Sellkit_Pro' ) ) {
198 - $this->has_pro = true;
221 + if ( class_exists( 'Sellkit_Pro' ) && function_exists( 'sellkit_pro' ) ) {
222 + if ( sellkit_pro()->is_active_sellkit_pro ) {
223 + $this->has_pro = true;
224 + }
199 225 }
200 226 }
201 227
202 228 /**
@@ -220,15 +246,25 @@
220 246 *
221 247 * @since 1.1.0
222 248 */
223 249 public function plugins_loaded() {
224 - if ( ! $this->has_valid_dependencies() ) {
225 - return false;
250 + if ( 'elementor' === $this->page_builder() ) {
251 + $this->load_files( [
252 + 'elementor/class',
253 + ] );
226 254 }
227 255
228 256 $this->load_files( [
229 - 'elementor/class',
257 + 'admin/class-promote-sellkit-pro',
258 + 'admin/class-promotion-banner',
230 259 ] );
260 +
261 + if ( class_exists( 'WooCommerce' ) && 'gutenberg' === $this->page_builder() ) {
262 + $this->load_files( [
263 + 'block-editor/helper',
264 + 'block-editor/class',
265 + ] );
266 + }
231 267 }
232 268
233 269 /**
234 270 * Do some stuff on plugin activation.
@@ -244,23 +280,37 @@
244 280 ] );
245 281
246 282 Install::check_database_tables();
247 283
248 - sellkit_update_option( 'current_db_version', '1.0.0' );
284 + if ( empty( sellkit_get_option( 'current_db_version' ) ) ) {
285 + sellkit_update_option( 'current_db_version', '1.2.7' ); // @since 1.5.0
286 + }
249 287
250 288 if ( ! wp_next_scheduled( 'sellkit_update_rfm_score' ) ) {
251 289 wp_schedule_event( time(), 'twicedaily', 'sellkit_update_rfm_score' );
252 290 }
291 +
292 + $this->sellkit_installed_time();
253 293 }
254 294
255 295 /**
256 - * Adding sellkit class to body.
296 + * Saves sellkit installation time.
257 297 *
258 - * @param string $classes Sellkit the sellkit class.
298 + * @since 1.5.9
299 + */
300 + private function sellkit_installed_time() {
301 + update_option( 'sellkit-installed-time', time() );
302 + }
303 +
304 + /**
305 + * Adds `sellkit` on the admin body so `.sellkit …` Bootstrap/Reboot selectors apply.
306 + * wp-admin sidebar chrome is toned down in `src/style.scss` where Reboot bleeds through.
307 + *
308 + * @param string $classes Existing body classes.
259 309 * @return string
260 310 */
261 311 public function sellkit_admin_body_class( $classes ) {
262 - return "{$classes} sellkit";
312 + return "{$classes} sellkit sellkit-admin-screen";
263 313 }
264 314
265 315 /**
266 316 * Initialize admin.
@@ -269,14 +319,11 @@
269 319 */
270 320 public function admin_init() {
271 321 $this->load_files( [
272 322 'admin/class-notices',
323 + 'admin/class',
273 324 ] );
274 325
275 - if ( ! $this->has_valid_dependencies() ) {
276 - return false;
277 - }
278 -
279 326 $this->load_files( [
280 327 'admin/utilities',
281 328 'admin/class-components',
282 329 'admin/components/class-list-table',
@@ -285,8 +332,9 @@
285 332 'admin/class-posts',
286 333 'admin/settings/class-settings',
287 334 'admin/class-custom-tables',
288 335 'admin/funnel/class',
336 + 'admin/class-global-checkout',
289 337 'core/install',
290 338 ] );
291 339 }
292 340
@@ -295,12 +343,8 @@
295 343 *
296 344 * @since 1.1.0
297 345 */
298 346 public function init() {
299 - if ( ! $this->has_valid_dependencies() ) {
300 - return false;
301 - }
302 -
303 347 $this->load_files( [
304 348 'admin/class-steps',
305 349 'utilities/functions',
306 350 'contact-segmentation/class',
@@ -322,8 +366,10 @@
322 366 register_post_type( $post_type, [
323 367 'public' => false,
324 368 ] );
325 369 }
370 +
371 + // Translations load automatically (WP 4.6+) from wp-content/languages/plugins/ and this plugin's languages directory.
326 372 }
327 373
328 374 /**
329 375 * Enqueue editor scripts.
@@ -346,12 +392,8 @@
346 392 *
347 393 * @since 1.1.0
348 394 */
349 395 public function enqueue_admin_scripts() {
350 - if ( ! $this->has_valid_dependencies() ) {
351 - return false;
352 - }
353 -
354 396 $page = ! empty( $_GET['page'] ) ? $_GET['page'] : ''; // phpcs:ignore
355 397
356 398 if ( ! in_array( $page, $this->sellkit_menus, true ) ) {
357 399 return false;
@@ -380,10 +422,8 @@
380 422 sellkit()->version()
381 423 );
382 424
383 425 wp_set_script_translations( 'sellkit', 'sellkit', sellkit()->plugin_dir() . 'languages' );
384 -
385 - $page = filter_input( INPUT_GET, 'page', FILTER_SANITIZE_STRING );
386 426 }
387 427
388 428 /**
389 429 * Register admin menu.
@@ -391,21 +431,30 @@
391 431 * @since 1.1.0
392 432 * @SuppressWarnings(PHPMD.NPathComplexity)
393 433 */
394 434 public function register_admin_menu() {
395 - if ( ! $this->has_valid_dependencies() ) {
396 - return false;
397 - }
398 -
399 435 $menu_name = esc_html__( 'Sellkit', 'sellkit' );
400 436 $initial_page = 'sellkit-dashboard';
401 437 $submenu = [
402 438 'sellkit-dashboard' => esc_html__( 'Dashboard', 'sellkit' ),
403 439 'sellkit-funnel' => esc_html__( 'Funnels', 'sellkit' ),
440 + 'sellkit-checkout' => esc_html__( 'Global Checkout', 'sellkit' ),
404 441 ];
405 442
406 - $svg_file = wp_remote_get( self::plugin_url() . 'assets/img/icons/sellkit-dashboard.svg' );
443 + $submenu = apply_filters( 'sellkit_sub_menu', $submenu );
407 444
445 + // Load SVG from disk. wp_remote_get() to the plugin URL often fails on local/SSL sites and yields an empty icon.
446 + $icon_path = sellkit()->plugin_dir() . 'assets/img/icons/sellkit-dashboard.svg';
447 + $menu_icon = 'dashicons-cart';
448 +
449 + if ( is_readable( $icon_path ) ) {
450 + // phpcs:ignore WordPress.WP.AlternativeFunctions.file_get_contents_file_get_contents -- Reading a bundled asset from the filesystem.
451 + $svg_contents = file_get_contents( $icon_path );
452 + if ( false !== $svg_contents && '' !== $svg_contents ) {
453 + $menu_icon = 'data:image/svg+xml;base64,' . base64_encode( $svg_contents );
454 + }
455 + }
456 +
408 457 add_menu_page(
409 458 $menu_name,
410 459 $menu_name,
411 460 'manage_options',
@@ -410,9 +459,9 @@
410 459 $menu_name,
411 460 'manage_options',
412 461 $initial_page,
413 462 [ $this, 'register_admin_menu_callback' ],
414 - 'data:image/svg+xml;base64,' . base64_encode( wp_remote_retrieve_body( $svg_file ) ),
463 + $menu_icon,
415 464 '58.1'
416 465 );
417 466
418 467 foreach ( $submenu as $slug => $title ) {
@@ -421,9 +470,9 @@
421 470 "{$menu_name} {$title}",
422 471 $title,
423 472 'edit_theme_options',
424 473 $slug,
425 - [ $this, 'register_admin_menu_callback' ],
474 + [ $this, 'register_admin_menu_callback' ]
426 475 );
427 476 }
428 477 }
429 478
@@ -438,9 +487,9 @@
438 487 esc_html__( 'Sellkit', 'sellkit' ) . ' ' . esc_html__( 'Settings', 'sellkit' ),
439 488 esc_html__( 'Settings', 'sellkit' ),
440 489 'edit_theme_options',
441 490 'sellkit-settings',
442 - [ $this, 'register_admin_menu_callback' ],
491 + [ $this, 'register_admin_menu_callback' ]
443 492 );
444 493 }
445 494
446 495 /**
@@ -465,9 +514,9 @@
465 514 *
466 515 * @return boolean SellKit screen.
467 516 */
468 517 private function is_sellkit_screen() {
469 - $page = filter_input( INPUT_GET, 'page', FILTER_SANITIZE_STRING );
518 + $page = sellkit_htmlspecialchars( INPUT_GET, 'page' );
470 519
471 520 return (
472 521 is_admin() &&
473 522 isset( $page ) &&
@@ -492,8 +541,9 @@
492 541 'contactSegmentation' => [
493 542 'conditionsOperators' => Operators::$condition_operator_names,
494 543 'operators' => Operators::$names,
495 544 'conditionsData' => Conditions::$data,
545 + 'browserLanguages' => Conditions\Browser_Language::browser_languages_array(),
496 546 ],
497 547 'adminUrl' => admin_url(),
498 548 'url' => site_url(),
499 549 'timezones' => timezone_identifiers_list(),
@@ -503,9 +553,40 @@
503 553 'elementorActivation' => class_exists( 'Elementor\Plugin' ) ? true : false,
504 554 'funnelsTemplateSource' => Funnel::SELLKIT_FUNNELS_TEMPLATE_SOURCE,
505 555 'removedContentBoxes' => Sellkit_Admin_Settings::get_removed_content_box(),
506 556 'sellkitProIsActive' => $this->has_pro,
557 + 'sellkitProPluginInstalled' => class_exists( 'Sellkit_Pro' ) && function_exists( 'sellkit_pro' ),
558 + 'sellkitLicensePageUrl' => ( class_exists( 'Sellkit_Pro' ) && function_exists( 'sellkit_pro' ) )
559 + ? ( is_multisite() ? network_admin_url( 'admin.php?page=sellkit-license' ) : admin_url( 'admin.php?page=sellkit-license' ) )
560 + : '',
561 + 'wcIsActivated' => $this->has_valid_dependencies(),
562 + 'activeTheme' => wp_get_theme()->get( 'Name' ),
563 + 'pageBuilder' => $this->page_builder(),
507 564 ];
565 + }
566 +
567 + /**
568 + * Get page builder.
569 + *
570 + * @since 2.3.0
571 + * @return string
572 + */
573 + public function page_builder() {
574 + $default = 'gutenberg';
575 +
576 + if ( class_exists( 'Elementor\Plugin' ) ) {
577 + $default = 'elementor';
578 + }
579 +
580 + $page_builder = sellkit_get_option( 'page_builder', '' );
581 +
582 + if ( empty( $page_builder ) ) {
583 + sellkit_update_option( 'page_builder', $default );
584 +
585 + return $default;
586 + }
587 +
588 + return $page_builder;
508 589 }
509 590
510 591 /**
511 592 * Get woocommerce settings data.