PluginProbe
Visualizer – Tables & Charts Manager with Built-in AI Generator / 3.11.10
Visualizer – Tables & Charts Manager with Built-in AI Generator v3.11.10
4.0.8 4.0.7 4.0.6 4.0.5 4.0.4 4.0.3 3.0.5 3.0.6 3.0.7 3.0.8 3.0.9 3.1.0 3.1.1 3.1.2 3.1.3 3.10.0 3.10.1 3.10.10 3.10.11 3.10.12 3.10.13 3.10.14 3.10.15 3.10.2 3.10.3 All 149 releases
← All changes | vendor/codeinwp/themeisle-sdk/src/Modules/Promotions.php +521 -118 3.10.23.11.10 View file →
@@ -13,8 +13,9 @@
13 13
14 14 namespace ThemeisleSDK\Modules;
15 15
16 16 use ThemeisleSDK\Common\Abstract_Module;
17 +use ThemeisleSDK\Loader;
17 18 use ThemeisleSDK\Product;
18 19
19 20 // Exit if accessed directly.
20 21 if ( ! defined( 'ABSPATH' ) ) {
@@ -30,11 +31,19 @@
30 31 * Holds the promotions.
31 32 *
32 33 * @var array
33 34 */
34 - private $promotions = array();
35 + public $promotions = array();
35 36
36 37 /**
38 + * Holds the values of the promotions that are not allowed to be shown.
39 + * Can be filtered by each product.
40 + *
41 + * @var array
42 + */
43 + private $dissallowed_promotions = array();
44 +
45 + /**
37 46 * Option key for promos.
38 47 *
39 48 * @var string
40 49 */
@@ -61,15 +70,43 @@
61 70 */
62 71 private $option_rop = 'themeisle_sdk_promotions_rop_installed';
63 72
64 73 /**
65 - * Option key for Neve FSE promos.
74 + * Option key for Neve promo.
66 75 *
67 76 * @var string
68 77 */
69 - private $option_neve_fse = 'themeisle_sdk_promotions_neve_fse_installed';
78 + private $option_neve = 'themeisle_sdk_promotions_neve_installed';
70 79
71 80 /**
81 + * Option key for Redirection for CF7.
82 + *
83 + * @var string
84 + */
85 + private $option_redirection_cf7 = 'themeisle_sdk_promotions_redirection_cf7_installed';
86 +
87 + /**
88 + * Option key for Hyve.
89 + *
90 + * @var string
91 + */
92 + private $option_hyve = 'themeisle_sdk_promotions_hyve_installed';
93 +
94 + /**
95 + * Option key for WP Full Pay.
96 + *
97 + * @var string
98 + */
99 + private $option_wp_full_pay = 'themeisle_sdk_promotions_wp_full_pay_installed';
100 +
101 + /**
102 + * Option key for Feedzy.
103 + *
104 + * @var string
105 + */
106 + private $option_feedzy = 'themeisle_sdk_promotions_feedzy_installed';
107 +
108 + /**
72 109 * Loaded promotion.
73 110 *
74 111 * @var string
75 112 */
@@ -103,23 +140,34 @@
103 140 if ( $this->is_from_partner( $product ) ) {
104 141 return false;
105 142 }
106 143
107 - $this->debug = apply_filters( 'themeisle_sdk_promo_debug', $this->debug );
108 - $promotions_to_load = apply_filters( $product->get_key() . '_load_promotions', array() );
144 + $this->debug = apply_filters( 'themeisle_sdk_promo_debug', $this->debug );
145 + $promotions_to_load = apply_filters( $product->get_key() . '_load_promotions', array() );
146 +
109 147 $promotions_to_load[] = 'optimole';
110 148 $promotions_to_load[] = 'rop';
111 149 $promotions_to_load[] = 'woo_plugins';
112 - $promotions_to_load[] = 'neve-fse';
150 + $promotions_to_load[] = 'neve';
151 + $promotions_to_load[] = 'redirection-cf7';
152 + $promotions_to_load[] = 'hyve';
153 + $promotions_to_load[] = 'wp_full_pay';
154 + $promotions_to_load[] = 'feedzy_import';
113 155
156 + if ( defined( 'NEVE_VERSION' ) || defined( 'WPMM_PATH' ) || defined( 'OTTER_BLOCKS_VERSION' ) || defined( 'OBFX_URL' ) ) {
157 + $promotions_to_load[] = 'feedzy_embed';
158 + }
159 + $promotions_to_load = array_unique( $promotions_to_load );
160 +
114 161 $this->promotions = $this->get_promotions();
115 162
163 + $this->dissallowed_promotions = apply_filters( $product->get_key() . '_dissallowed_promotions', array() );
164 +
116 165 foreach ( $this->promotions as $slug => $data ) {
117 166 if ( ! in_array( $slug, $promotions_to_load, true ) ) {
118 167 unset( $this->promotions[ $slug ] );
119 168 }
120 169 }
121 -
122 170 add_action( 'init', array( $this, 'register_settings' ), 99 );
123 171 add_action( 'admin_init', array( $this, 'register_reference' ), 99 );
124 172
125 173 return ! empty( $this->promotions );
@@ -134,16 +182,16 @@
134 182 if ( ! $this->is_writeable() || ! current_user_can( 'install_plugins' ) ) {
135 183 return;
136 184 }
137 185
138 - $this->product = $product;
186 + $last_dismiss_time = $this->get_last_dismiss_time();
139 187
140 - $last_dismiss = $this->get_last_dismiss_time();
141 -
142 - if ( ! $this->debug && $last_dismiss && ( time() - $last_dismiss ) < 7 * DAY_IN_SECONDS ) {
188 + if ( ! $this->debug && is_int( $last_dismiss_time ) && ( time() - $last_dismiss_time ) < ( 3 * WEEK_IN_SECONDS ) ) {
143 189 return;
144 190 }
145 191
192 + $this->product = $product;
193 +
146 194 add_filter( 'attachment_fields_to_edit', array( $this, 'add_attachment_field' ), 10, 2 );
147 195 add_action( 'current_screen', [ $this, 'load_available' ] );
148 196 add_action( 'elementor/editor/after_enqueue_scripts', array( $this, 'enqueue' ) );
149 197 add_action( 'wp_ajax_tisdk_update_option', array( $this, 'dismiss_promotion' ) );
@@ -148,9 +196,9 @@
148 196 add_action( 'elementor/editor/after_enqueue_scripts', array( $this, 'enqueue' ) );
149 197 add_action( 'wp_ajax_tisdk_update_option', array( $this, 'dismiss_promotion' ) );
150 198 add_filter( 'themeisle_sdk_ran_promos', '__return_true' );
151 199
152 - if ( get_option( $this->option_neve_fse, false ) !== true ) {
200 + if ( get_option( $this->option_neve, false ) !== true ) {
153 201 add_action( 'wp_ajax_themeisle_sdk_dismiss_notice', 'ThemeisleSDK\Modules\Notification::regular_dismiss' );
154 202 }
155 203 }
156 204
@@ -158,9 +206,8 @@
158 206 * Load available promotions.
159 207 */
160 208 public function load_available() {
161 209 $this->promotions = $this->filter_by_screen_and_merge();
162 -
163 210 if ( empty( $this->promotions ) ) {
164 211 return;
165 212 }
166 213
@@ -173,8 +220,21 @@
173 220 *
174 221 * @return void
175 222 */
176 223 public function register_reference() {
224 + if ( ! current_user_can( 'activate_plugins' ) ) {
225 + return;
226 + }
227 +
228 + if ( ! isset( $_GET['plugin'] ) || ! isset( $_GET['_wpnonce'] ) ) {
229 + return;
230 + }
231 +
232 + $plugin = rawurldecode( $_GET['plugin'] ); // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
233 + if ( wp_verify_nonce( $_GET['_wpnonce'], 'activate-plugin_' . $plugin ) === false ) { // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
234 + return;
235 + }
236 +
177 237 if ( isset( $_GET['reference_key'] ) ) {
178 238 update_option( 'otter_reference_key', sanitize_key( $_GET['reference_key'] ) );
179 239 }
180 240
@@ -185,11 +245,23 @@
185 245 if ( isset( $_GET['rop_reference_key'] ) ) {
186 246 update_option( 'rop_reference_key', sanitize_key( $_GET['rop_reference_key'] ) );
187 247 }
188 248
189 - if ( isset( $_GET['neve_fse_reference_key'] ) ) {
190 - update_option( 'neve_fse_reference_key', sanitize_key( $_GET['neve_fse_reference_key'] ) );
249 + if ( isset( $_GET['neve_reference_key'] ) ) {
250 + update_option( 'neve_reference_key', sanitize_key( $_GET['neve_reference_key'] ) );
191 251 }
252 +
253 + if ( isset( $_GET['hyve_reference_key'] ) ) {
254 + update_option( 'hyve_reference_key', sanitize_key( $_GET['hyve_reference_key'] ) );
255 + }
256 +
257 + if ( isset( $_GET['wp_full_pay_reference_key'] ) ) {
258 + update_option( 'wp_full_pay_reference_key', sanitize_key( $_GET['wp_full_pay_reference_key'] ) );
259 + }
260 + if ( isset( $_GET['feedzy_reference_key'] ) || ( isset( $_GET['from'], $_GET['plugin'] ) && $_GET['from'] === 'import' && str_starts_with( sanitize_key( $_GET['plugin'] ), 'feedzy' ) ) ) {
261 + update_option( 'feedzy_reference_key', sanitize_key( $_GET['feedzy_reference_key'] ?? 'i-' . $this->product->get_key() ) );
262 + update_option( $this->option_feedzy, 1 );
263 + }
192 264 }
193 265
194 266 /**
195 267 * Register Settings
@@ -239,9 +311,9 @@
239 311 )
240 312 );
241 313 register_setting(
242 314 'themeisle_sdk_settings',
243 - $this->option_neve_fse,
315 + $this->option_neve,
244 316 array(
245 317 'type' => 'boolean',
246 318 'sanitize_callback' => 'rest_sanitize_boolean',
247 319 'show_in_rest' => true,
@@ -247,8 +319,38 @@
247 319 'show_in_rest' => true,
248 320 'default' => false,
249 321 )
250 322 );
323 + register_setting(
324 + 'themeisle_sdk_settings',
325 + $this->option_redirection_cf7,
326 + array(
327 + 'type' => 'boolean',
328 + 'sanitize_callback' => 'rest_sanitize_boolean',
329 + 'show_in_rest' => true,
330 + 'default' => false,
331 + )
332 + );
333 + register_setting(
334 + 'themeisle_sdk_settings',
335 + $this->option_hyve,
336 + array(
337 + 'type' => 'boolean',
338 + 'sanitize_callback' => 'rest_sanitize_boolean',
339 + 'show_in_rest' => true,
340 + 'default' => false,
341 + )
342 + );
343 + register_setting(
344 + 'themeisle_sdk_settings',
345 + $this->option_wp_full_pay,
346 + array(
347 + 'type' => 'boolean',
348 + 'sanitize_callback' => 'rest_sanitize_boolean',
349 + 'show_in_rest' => true,
350 + 'default' => false,
351 + )
352 + );
251 353 }
252 354
253 355 /**
254 356 * Check if the path is writable.
@@ -268,36 +370,68 @@
268 370 return false;
269 371 }
270 372
271 373 /**
374 + * Third-party compatibility.
375 + *
376 + * @return boolean
377 + */
378 + private function has_conflicts() {
379 + global $pagenow;
380 +
381 + // Editor notices aren't compatible with Enfold theme.
382 + if ( defined( 'AV_FRAMEWORK_VERSION' ) && in_array( $pagenow, array( 'post.php', 'post-new.php' ) ) ) {
383 + return true;
384 + }
385 +
386 + return false;
387 + }
388 +
389 + /**
272 390 * Get promotions.
273 391 *
274 392 * @return array
275 393 */
276 394 private function get_promotions() {
277 - $has_otter = defined( 'OTTER_BLOCKS_VERSION' ) || $this->is_plugin_installed( 'otter-blocks' );
278 - $had_otter_from_promo = get_option( $this->option_otter, false );
279 - $has_optimole = defined( 'OPTIMOLE_VERSION' ) || $this->is_plugin_installed( 'optimole-wp' );
280 - $had_optimole_from_promo = get_option( $this->option_optimole, false );
281 - $has_rop = defined( 'ROP_LITE_VERSION' ) || $this->is_plugin_installed( 'tweet-old-post' );
282 - $had_rop_from_promo = get_option( $this->option_rop, false );
283 - $has_woocommerce = class_exists( 'WooCommerce' );
284 - $has_sparks = defined( 'SPARKS_WC_VERSION' ) || $this->is_plugin_installed( 'sparks-for-woocommerce' );
285 - $has_ppom = defined( 'PPOM_VERSION' ) || $this->is_plugin_installed( 'woocommerce-product-addon' );
286 - $is_min_req_v = version_compare( get_bloginfo( 'version' ), '5.8', '>=' );
287 - $is_min_fse_v = version_compare( get_bloginfo( 'version' ), '6.2', '>=' );
288 - $has_enough_attachments = $this->has_min_media_attachments();
289 - $has_enough_old_posts = $this->has_old_posts();
395 + $has_otter = defined( 'OTTER_BLOCKS_VERSION' ) || $this->is_plugin_installed( 'otter-blocks' );
396 + $had_otter_from_promo = get_option( $this->option_otter, false );
397 + $has_optimole = defined( 'OPTIMOLE_VERSION' ) || $this->is_plugin_installed( 'optimole-wp' );
398 + $had_optimole_from_promo = get_option( $this->option_optimole, false );
399 + $has_rop = defined( 'ROP_LITE_VERSION' ) || $this->is_plugin_installed( 'tweet-old-post' );
400 + $had_rop_from_promo = get_option( $this->option_rop, false );
401 + $has_woocommerce = class_exists( 'WooCommerce' );
402 + $has_sparks = defined( 'SPARKS_WC_VERSION' ) || $this->is_plugin_installed( 'sparks-for-woocommerce' );
403 + $has_ppom = defined( 'PPOM_VERSION' ) || $this->is_plugin_installed( 'woocommerce-product-addon' );
404 + $has_redirection_cf7 = defined( 'WPCF7_PRO_REDIRECT_PLUGIN_VERSION' ) || $this->is_plugin_installed( 'wpcf7-redirect' );
405 + $had_redirection_cf7_promo = get_option( $this->option_redirection_cf7, false );
406 + $has_hyve = defined( 'HYVE_LITE_VERSION' ) || $this->is_plugin_installed( 'hyve' ) || $this->is_plugin_installed( 'hyve-lite' );
407 + $had_hyve_from_promo = get_option( $this->option_hyve, false );
408 + $has_hyve_conditions = version_compare( get_bloginfo( 'version' ), '6.2', '>=' ) && $this->has_support_page();
409 + $has_wfp_full_pay = defined( 'WP_FULL_STRIPE_BASENAME' ) || $this->is_plugin_installed( 'wp-full-stripe-free' );
410 + $had_wfp_from_promo = get_option( $this->option_wp_full_pay, false );
411 + $has_wfp_conditions = $this->has_donate_page();
412 + $is_min_req_v = version_compare( get_bloginfo( 'version' ), '5.8', '>=' );
413 + $current_theme = wp_get_theme();
414 + $has_neve = $current_theme->template === 'neve' || $current_theme->parent() === 'neve';
415 + $has_neve_from_promo = get_option( $this->option_neve, false );
416 + $has_enough_attachments = $this->has_min_media_attachments();
417 + $has_enough_old_posts = $this->has_old_posts();
418 + $is_min_php_8_1 = version_compare( PHP_VERSION, '8.1', '>=' );
290 419
420 + $has_feedzy = defined( 'FEEDZY_BASEFILE' ) || $this->is_plugin_installed( 'feedzy-rss-feedss' );
421 + $had_feedzy_from_promo = get_option( $this->option_feedzy, false );
422 +
291 423 $all = [
292 - 'optimole' => [
424 + 'optimole' => [
293 425 'om-editor' => [
294 - 'env' => ! $has_optimole && $is_min_req_v && ! $had_optimole_from_promo,
295 - 'screen' => 'editor',
426 + 'env' => ! $has_optimole && $is_min_req_v && ! $had_optimole_from_promo,
427 + 'screen' => 'editor',
428 + 'delayed' => true,
296 429 ],
297 430 'om-image-block' => [
298 - 'env' => ! $has_optimole && $is_min_req_v && ! $had_optimole_from_promo,
299 - 'screen' => 'editor',
431 + 'env' => ! $has_optimole && $is_min_req_v && ! $had_optimole_from_promo,
432 + 'screen' => 'editor',
433 + 'delayed' => true,
300 434 ],
301 435 'om-attachment' => [
302 436 'env' => ! $has_optimole && ! $had_optimole_from_promo,
303 437 'screen' => 'media-editor',
@@ -306,33 +440,51 @@
306 440 'env' => ! $has_optimole && ! $had_optimole_from_promo && $has_enough_attachments,
307 441 'screen' => 'media',
308 442 ],
309 443 'om-elementor' => [
310 - 'env' => ! $has_optimole && ! $had_optimole_from_promo && defined( 'ELEMENTOR_VERSION' ),
311 - 'screen' => 'elementor',
444 + 'env' => ! $has_optimole && ! $had_optimole_from_promo && defined( 'ELEMENTOR_VERSION' ),
445 + 'screen' => 'elementor',
446 + 'delayed' => true,
312 447 ],
313 448 ],
314 - 'otter' => [
449 + 'feedzy_import' => [
450 + 'feedzy-import' => [
451 + 'env' => true,
452 + 'screen' => 'import',
453 + 'always' => true,
454 + ],
455 + ],
456 + 'feedzy_embed' => [
457 + 'feedzy-editor' => [
458 + 'env' => ! $has_feedzy && is_main_site() && ! $had_feedzy_from_promo,
459 + 'screen' => 'editor',
460 + ],
461 + ],
462 + 'otter' => [
315 463 'blocks-css' => [
316 - 'env' => ! $has_otter && $is_min_req_v && ! $had_otter_from_promo,
317 - 'screen' => 'editor',
464 + 'env' => ! $has_otter && $is_min_req_v && ! $had_otter_from_promo,
465 + 'screen' => 'editor',
466 + 'delayed' => true,
318 467 ],
319 468 'blocks-animation' => [
320 - 'env' => ! $has_otter && $is_min_req_v && ! $had_otter_from_promo,
321 - 'screen' => 'editor',
469 + 'env' => ! $has_otter && $is_min_req_v && ! $had_otter_from_promo,
470 + 'screen' => 'editor',
471 + 'delayed' => true,
322 472 ],
323 473 'blocks-conditions' => [
324 - 'env' => ! $has_otter && $is_min_req_v && ! $had_otter_from_promo,
325 - 'screen' => 'editor',
474 + 'env' => ! $has_otter && $is_min_req_v && ! $had_otter_from_promo,
475 + 'screen' => 'editor',
476 + 'delayed' => true,
326 477 ],
327 478 ],
328 - 'rop' => [
479 + 'rop' => [
329 480 'rop-posts' => [
330 - 'env' => ! $has_rop && ! $had_rop_from_promo && $has_enough_old_posts,
331 - 'screen' => 'edit-post',
481 + 'env' => ! $has_rop && ! $had_rop_from_promo && $has_enough_old_posts,
482 + 'screen' => 'edit-post',
483 + 'delayed' => true,
332 484 ],
333 485 ],
334 - 'woo_plugins' => [
486 + 'woo_plugins' => [
335 487 'ppom' => [
336 488 'env' => ! $has_ppom && $has_woocommerce,
337 489 'screen' => 'edit-product',
338 490 ],
@@ -348,19 +500,38 @@
348 500 'env' => ! $has_sparks && $has_woocommerce,
349 501 'screen' => 'edit-product',
350 502 ],
351 503 ],
352 - 'neve-fse' => [
353 - 'neve-fse-themes-popular' => [
354 - 'env' => $is_min_fse_v,
504 + 'neve' => [
505 + 'neve-themes-popular' => [
506 + 'env' => ! $has_neve && ! $has_neve_from_promo,
355 507 'screen' => 'themes-install-popular',
356 508 ],
357 509 ],
510 + 'redirection-cf7' => [
511 + 'wpcf7' => [
512 + 'env' => ! $has_redirection_cf7 && ! $had_redirection_cf7_promo,
513 + 'screen' => 'wpcf7',
514 + 'delayed' => true,
515 + ],
516 + ],
517 + 'hyve' => [
518 + 'hyve-plugins-install' => [
519 + 'env' => $is_min_php_8_1 && ! $has_hyve && ! $had_hyve_from_promo && $has_hyve_conditions,
520 + 'screen' => 'plugin-install',
521 + ],
522 + ],
523 + 'wp_full_pay' => [
524 + 'wp-full-pay-plugins-install' => [
525 + 'env' => ! $has_wfp_full_pay && ! $had_wfp_from_promo && $has_wfp_conditions,
526 + 'screen' => 'plugin-install',
527 + ],
528 + ],
358 529 ];
359 530
360 531 foreach ( $all as $slug => $data ) {
361 532 foreach ( $data as $key => $conditions ) {
362 - if ( ! $conditions['env'] ) {
533 + if ( ! $conditions['env'] || $this->has_conflicts() ) {
363 534 unset( $all[ $slug ][ $key ] );
364 535
365 536 continue;
366 537 }
@@ -373,9 +544,8 @@
373 544 if ( empty( $all[ $slug ] ) ) {
374 545 unset( $all[ $slug ] );
375 546 }
376 547 }
377 -
378 548 return $all;
379 549 }
380 550
381 551 /**
@@ -400,20 +570,14 @@
400 570
401 571 /**
402 572 * Get the last dismiss time of a promotion.
403 573 *
404 - * @return int The timestamp of last dismiss, or install time - 4 days.
574 + * @return int | false The timestamp of last dismiss or false.
405 575 */
406 576 private function get_last_dismiss_time() {
407 577 $dismissed = $this->get_upsells_dismiss_time();
408 578
409 - if ( empty( $dismissed ) ) {
410 - // we return the product install time - 4 days because we want to show the upsell after 3 days,
411 - // and we move the product install time 4 days in the past.
412 - return $this->product->get_install_time() - 4 * DAY_IN_SECONDS;
413 - }
414 -
415 - return max( array_values( $dismissed ) );
579 + return empty( $dismissed ) ? false : max( array_values( $dismissed ) );
416 580 }
417 581
418 582 /**
419 583 * Filter by screen & merge into single array of keys.
@@ -422,19 +586,45 @@
422 586 */
423 587 private function filter_by_screen_and_merge() {
424 588 $current_screen = get_current_screen();
425 589
426 - $is_elementor = isset( $_GET['action'] ) && $_GET['action'] === 'elementor';
427 - $is_media = isset( $current_screen->id ) && $current_screen->id === 'upload';
428 - $is_posts = isset( $current_screen->id ) && $current_screen->id === 'edit-post';
429 - $is_editor = method_exists( $current_screen, 'is_block_editor' ) && $current_screen->is_block_editor();
430 - $is_theme_install = isset( $current_screen->id ) && ( $current_screen->id === 'theme-install' || $current_screen->id === 'themes' );
431 - $is_product = isset( $current_screen->id ) && $current_screen->id === 'product';
590 + $is_elementor = isset( $_GET['action'] ) && $_GET['action'] === 'elementor';
591 + $is_media = isset( $current_screen->id ) && $current_screen->id === 'upload';
592 + $is_posts = isset( $current_screen->id ) && $current_screen->id === 'edit-post';
593 + $is_editor = method_exists( $current_screen, 'is_block_editor' ) && $current_screen->is_block_editor();
594 + $is_theme_install = isset( $current_screen->id ) && ( $current_screen->id === 'theme-install' );
595 + $is_plugin_install = isset( $current_screen->id ) && ( $current_screen->id === 'plugin-install' );
596 + $is_product = isset( $current_screen->id ) && $current_screen->id === 'product';
597 + $is_import = isset( $current_screen->id ) && $current_screen->id === 'import';
598 + $is_cf7_install = isset( $current_screen->id ) && function_exists( 'str_contains' ) ? str_contains( $current_screen->id, 'page_wpcf7' ) : false;
432 599
433 - $return = [];
434 -
600 + $return = [];
601 + $product_install_time = (int) $this->product->get_install_time();
602 + $is_older = time() > ( $product_install_time + ( 3 * DAY_IN_SECONDS ) );
603 + $is_newer = time() < ( $product_install_time + ( 6 * HOUR_IN_SECONDS ) );
435 604 foreach ( $this->promotions as $slug => $promos ) {
436 605 foreach ( $promos as $key => $data ) {
606 +
607 + $data = wp_parse_args(
608 + $data,
609 + [
610 + 'delayed' => false,
611 + 'always' => false,
612 + ]
613 + );
614 +
615 + if (
616 + ! $this->debug &&
617 + (
618 + ( $data['delayed'] === true && ! $is_older ) || // Skip promotions that are delayed for 3 days.
619 + $is_newer // Skip promotions for the first 6 hours after install.
620 + )
621 + && ! $data['always']
622 + ) {
623 + unset( $this->promotions[ $slug ][ $key ] );
624 +
625 + continue;
626 + }
437 627 switch ( $data['screen'] ) {
438 628 case 'media-editor':
439 629 if ( ! $is_media && ! $is_editor ) {
440 630 unset( $this->promotions[ $slug ][ $key ] );
@@ -449,8 +639,13 @@
449 639 if ( ! $is_editor || $is_elementor ) {
450 640 unset( $this->promotions[ $slug ][ $key ] );
451 641 }
452 642 break;
643 + case 'import':
644 + if ( ! $is_import ) {
645 + unset( $this->promotions[ $slug ][ $key ] );
646 + }
647 + break;
453 648 case 'elementor':
454 649 if ( ! $is_elementor ) {
455 650 unset( $this->promotions[ $slug ][ $key ] );
456 651 }
@@ -469,8 +664,18 @@
469 664 if ( ! $is_theme_install ) {
470 665 unset( $this->promotions[ $slug ][ $key ] );
471 666 }
472 667 break;
668 + case 'wpcf7':
669 + if ( ! $is_cf7_install ) {
670 + unset( $this->promotions[ $slug ][ $key ] );
671 + }
672 + break;
673 + case 'plugin-install':
674 + if ( ! $is_plugin_install ) {
675 + unset( $this->promotions[ $slug ][ $key ] );
676 + }
677 + break;
473 678 }
474 679 }
475 680
476 681 $return = array_merge( $return, $this->promotions[ $slug ] );
@@ -475,8 +680,16 @@
475 680
476 681 $return = array_merge( $return, $this->promotions[ $slug ] );
477 682 }
478 683
684 + $return = array_filter(
685 + $return,
686 + function ( $value, $key ) {
687 + return ! in_array( $key, $this->dissallowed_promotions, true );
688 + },
689 + ARRAY_FILTER_USE_BOTH
690 + );
691 +
479 692 return array_keys( $return );
480 693 }
481 694
482 695 /**
@@ -495,16 +708,27 @@
495 708 }
496 709 if ( $this->get_upsells_dismiss_time( 'rop-posts' ) === false ) {
497 710 add_action( 'admin_notices', [ $this, 'render_rop_dash_notice' ] );
498 711 }
499 - if ( $this->get_upsells_dismiss_time( 'neve-fse-themes-popular' ) === false ) {
500 - add_action( 'admin_notices', [ $this, 'render_neve_fse_themes_notice' ] );
712 + if ( $this->get_upsells_dismiss_time( 'neve-themes-popular' ) === false ) {
713 + add_action( 'admin_notices', [ $this, 'render_neve_themes_notice' ] );
501 714 }
715 + if ( $this->get_upsells_dismiss_time( 'redirection-cf7' ) === false ) {
716 + add_action( 'admin_notices', [ $this, 'render_redirection_cf7_notice' ] );
717 + }
718 + if ( $this->get_upsells_dismiss_time( 'hyve-plugins-install' ) === false ) {
719 + add_action( 'admin_notices', [ $this, 'render_hyve_notice' ] );
720 + }
502 721
722 + if ( $this->get_upsells_dismiss_time( 'wp-full-pay-plugins-install' ) === false ) {
723 + add_action( 'admin_notices', [ $this, 'render_wp_full_pay_notice' ] );
724 + }
725 +
726 + add_action( 'load-import.php', [ $this, 'add_import' ] );
503 727 $this->load_woo_promos();
728 +
504 729 return;
505 730 }
506 -
507 731 switch ( $slug ) {
508 732 case 'om-editor':
509 733 case 'om-image-block':
510 734 case 'blocks-css':
@@ -522,8 +746,15 @@
522 746 case 'rop-posts':
523 747 add_action( 'admin_enqueue_scripts', [ $this, 'enqueue' ] );
524 748 add_action( 'admin_notices', [ $this, 'render_rop_dash_notice' ] );
525 749 break;
750 + case 'feedzy-import':
751 + add_action( 'load-import.php', [ $this, 'add_import' ] );
752 +
753 + break;
754 + case 'feedzy-editor':
755 + add_action( 'enqueue_block_editor_assets', [ $this, 'enqueue' ] );
756 + break;
526 757 case 'ppom':
527 758 case 'sparks-wishlist':
528 759 case 'sparks-announcement':
529 760 case 'sparks-product-reviews':
@@ -528,16 +759,59 @@
528 759 case 'sparks-announcement':
529 760 case 'sparks-product-reviews':
530 761 $this->load_woo_promos();
531 762 break;
532 - case 'neve-fse-themes-popular':
763 + case 'neve-themes-popular':
764 + // Remove any other notifications if Neve promotion is showing
765 + remove_action( 'admin_notices', array( 'ThemeisleSDK\Modules\Notification', 'show_notification' ) );
766 + remove_action(
767 + 'wp_ajax_themeisle_sdk_dismiss_notice',
768 + array(
769 + 'ThemeisleSDK\Modules\Notification',
770 + 'dismiss',
771 + )
772 + );
773 + remove_action( 'admin_head', array( 'ThemeisleSDK\Modules\Notification', 'dismiss_get' ) );
774 + remove_action( 'admin_head', array( 'ThemeisleSDK\Modules\Notification', 'setup_notifications' ) );
775 + // Add required actions to display this notification
533 776 add_action( 'admin_enqueue_scripts', [ $this, 'enqueue' ] );
534 - add_action( 'admin_notices', [ $this, 'render_neve_fse_themes_notice' ] );
777 + add_action( 'admin_notices', [ $this, 'render_neve_themes_notice' ] );
535 778 break;
779 + case 'wpcf7':
780 + add_action( 'admin_enqueue_scripts', [ $this, 'enqueue' ] );
781 + add_action( 'admin_notices', [ $this, 'render_redirection_cf7_notice' ] );
782 + break;
783 + case 'hyve-plugins-install':
784 + add_action( 'admin_enqueue_scripts', [ $this, 'enqueue' ] );
785 + add_action( 'admin_notices', [ $this, 'render_hyve_notice' ] );
786 + break;
787 + case 'wp-full-pay-plugins-install':
788 + add_action( 'admin_enqueue_scripts', [ $this, 'enqueue' ] );
789 + add_action( 'admin_notices', [ $this, 'render_wp_full_pay_notice' ] );
790 + break;
536 791 }
537 792 }
538 793
539 794 /**
795 + * Add import row.
796 + *
797 + * @return void
798 + */
799 + public function add_import() {
800 + global $wp_importers;
801 + if ( isset( $wp_importers['feedzy-rss-feeds'] ) ) {
802 + return;
803 + }
804 + $wp_importers['feedzy-rss-feeds'] = array( // phpcs:ignore WordPress.WP.GlobalVariablesOverride.Prohibited
805 + 'Feedzy',
806 + sprintf( Loader::$labels['promotions']['feedzy']['import_desc'], '<span style="float: left; font-style: italic;margin-top:0.4em;">', $this->product->get_friendly_name(), '</span>' ),
807 + 'install' => 'feedzy-rss-feeds',
808 + );
809 + if ( defined( 'FEEDZY_BASEFILE' ) ) {
810 + unset( $wp_importers['feedzy-rss-feeds']['install'] );
811 + }
812 + }
813 + /**
540 814 * Render dashboard notice.
541 815 */
542 816 public function render_optimole_dash_notice() {
543 817 $screen = get_current_screen();
@@ -560,30 +834,66 @@
560 834 $user = wp_get_current_user();
561 835 $asset_file = require $themeisle_sdk_max_path . '/assets/js/build/promos/index.asset.php';
562 836 $deps = array_merge( $asset_file['dependencies'], [ 'updates' ] );
563 837
838 + $themes = wp_get_themes();
839 + $neve_action = isset( $themes['neve'] ) ? 'activate' : 'install';
840 + $labels = Loader::$labels['promotions'];
841 + $labels['feedzy']['editor_recommends'] = sprintf(
842 + $labels['feedzy']['editor_recommends'],
843 + $this->product->get_friendly_name(),
844 + '<a target="_blank" href="' . add_query_arg(
845 + array(
846 + 'tab' => 'plugin-information',
847 + 'plugin' => 'feedzy-rss-feeds',
848 + '_wpnonce' => wp_create_nonce( 'activate-plugin_feedzy-rss-feeds' ),
849 + 'feedzy_reference_key' => 'e-' . $this->product->get_key(),
850 + ),
851 + network_admin_url( 'plugin-install.php' )
852 + ) . '">',
853 + '</a>'
854 + );
564 855 wp_register_script( $handle, $themeisle_sdk_src . 'assets/js/build/promos/index.js', $deps, $asset_file['version'], true );
565 856 wp_localize_script(
566 857 $handle,
567 858 'themeisleSDKPromotions',
568 859 [
569 - 'debug' => $this->debug,
570 - 'email' => $user->user_email,
571 - 'showPromotion' => $this->loaded_promo,
572 - 'optionKey' => $this->option_main,
573 - 'product' => $this->product->get_name(),
574 - 'option' => empty( $saved ) ? new \stdClass() : $saved,
575 - 'nonce' => wp_create_nonce( 'wp_rest' ),
576 - 'assets' => $themeisle_sdk_src . 'assets/images/',
577 - 'optimoleApi' => esc_url( rest_url( 'optml/v1/register_service' ) ),
578 - 'optimoleActivationUrl' => $this->get_plugin_activation_link( 'optimole-wp' ),
579 - 'otterActivationUrl' => $this->get_plugin_activation_link( 'otter-blocks' ),
580 - 'ropActivationUrl' => $this->get_plugin_activation_link( 'tweet-old-post' ),
581 - 'optimoleDash' => esc_url( add_query_arg( [ 'page' => 'optimole' ], admin_url( 'upload.php' ) ) ),
582 - 'ropDash' => esc_url( add_query_arg( [ 'page' => 'TweetOldPost' ], admin_url( 'admin.php' ) ) ),
583 - 'neveFSEMoreUrl' => tsdk_utmify( 'https://themeisle.com/themes/neve-fse/', 'neve-fse-themes-popular', 'theme-install' ),
860 + 'debug' => $this->debug,
861 + 'labels' => $labels,
862 + 'email' => $user->user_email,
863 + 'showPromotion' => $this->loaded_promo,
864 + 'optionKey' => $this->option_main,
865 + 'product' => $this->product->get_name(),
866 + 'option' => empty( $saved ) ? new \stdClass() : $saved,
867 + 'nonce' => wp_create_nonce( 'wp_rest' ),
868 + 'assets' => $themeisle_sdk_src . 'assets/images/',
869 + 'optimoleApi' => esc_url( rest_url( 'optml/v1/register_service' ) ),
870 + 'optimoleActivationUrl' => $this->get_plugin_activation_link( 'optimole-wp' ),
871 + 'otterActivationUrl' => $this->get_plugin_activation_link( 'otter-blocks' ),
872 + 'ropActivationUrl' => $this->get_plugin_activation_link( 'tweet-old-post' ),
873 + 'optimoleDash' => esc_url( add_query_arg( [ 'page' => 'optimole' ], admin_url( 'upload.php' ) ) ),
874 + 'ropDash' => esc_url( add_query_arg( [ 'page' => 'TweetOldPost' ], admin_url( 'admin.php' ) ) ),
584 875 // translators: %s is the product name.
585 - 'title' => esc_html( sprintf( __( 'Recommended by %s', 'textdomain' ), $this->product->get_name() ) ),
876 + 'title' => esc_html( sprintf( Loader::$labels['promotions']['recommended'], $this->product->get_name() ) ),
877 + 'redirectionCF7MoreUrl' => tsdk_utmify( 'https://docs.themeisle.com/collection/2014-redirection-for-contact-form-7', 'redirection-for-contact-form-7', 'plugin-install' ),
878 + 'rfCF7ActivationUrl' => $this->get_plugin_activation_link( 'wpcf7-redirect' ),
879 + 'cf7Dash' => esc_url( add_query_arg( [ 'page' => 'wpcf7-new' ], admin_url( 'admin.php' ) ) ),
880 + 'hyveActivationUrl' => $this->get_plugin_activation_link( 'hyve-lite' ),
881 + 'hyveDash' => esc_url( add_query_arg( [ 'page' => 'wpfs-settings-stripe' ], admin_url( 'admin.php' ) ) ),
882 + 'wpFullPayActivationUrl' => $this->get_plugin_activation_link( 'wp-full-stripe-free' ),
883 + 'wpFullPayDash' => esc_url( add_query_arg( [ 'page' => 'wpfs-settings-stripe' ], admin_url( 'admin.php' ) ) ),
884 + 'nevePreviewURL' => esc_url( add_query_arg( [ 'theme' => 'neve' ], admin_url( 'theme-install.php' ) ) ),
885 + 'neveAction' => $neve_action,
886 + 'activateNeveURL' => esc_url(
887 + add_query_arg(
888 + [
889 + 'action' => 'activate',
890 + 'stylesheet' => 'neve',
891 + '_wpnonce' => wp_create_nonce( 'switch-theme_neve' ),
892 + ],
893 + admin_url( 'themes.php' )
894 + )
895 + ),
586 896 ]
587 897 );
588 898 wp_enqueue_script( $handle );
589 899 wp_enqueue_style( $handle, $themeisle_sdk_src . 'assets/js/build/promos/style-index.css', [ 'wp-components' ], $asset_file['version'] );
@@ -602,15 +912,36 @@
602 912 echo '<div id="ti-rop-notice" class="notice notice-info ti-sdk-rop-notice"></div>';
603 913 }
604 914
605 915 /**
606 - * Render Neve FSE Themes notice.
916 + * Render Neve Themes notice.
607 917 */
608 - public function render_neve_fse_themes_notice() {
609 - echo '<div id="ti-neve-fse-notice" class="notice notice-info ti-sdk-neve-fse-notice"></div>';
918 + public function render_neve_themes_notice() {
919 + echo '<div id="ti-neve-notice" class="notice notice-info ti-sdk-om-notice"></div>';
610 920 }
611 921
612 922 /**
923 + * Render Hyve notice.
924 + */
925 + public function render_hyve_notice() {
926 + echo '<div id="ti-hyve-notice" class="notice notice-info ti-sdk-om-notice"></div>';
927 + }
928 +
929 + /**
930 + * Render WP Full Pay notice.
931 + */
932 + public function render_wp_full_pay_notice() {
933 + echo '<div id="ti-wp-full-pay-notice" class="notice notice-info ti-sdk-om-notice"></div>';
934 + }
935 +
936 + /**
937 + * Render Redirection for CF7 notice.
938 + */
939 + public function render_redirection_cf7_notice() {
940 + echo '<div id="ti-redirection-cf7-notice" class="notice notice-info ti-sdk-om-notice"></div>';
941 + }
942 +
943 + /**
613 944 * Add promo to attachment modal.
614 945 *
615 946 * @param array $fields Fields array.
616 947 * @param \WP_Post $post Post object.
@@ -627,9 +958,9 @@
627 958 }
628 959
629 960 $meta = wp_get_attachment_metadata( $post->ID );
630 961
631 - if ( isset( $meta['filesize'] ) && $meta['filesize'] < 200000 ) {
962 + if ( isset( $meta['filesize'] ) && $meta['filesize'] < 100000 ) {
632 963 return $fields;
633 964 }
634 965
635 966 $fields['optimole'] = array(
@@ -669,8 +1000,9 @@
669 1000
670 1001
671 1002 set_transient( 'tsk_attachment_count', $attachment_count, DAY_IN_SECONDS );
672 1003 }
1004 +
673 1005 return $attachment_count > 50;
674 1006 }
675 1007
676 1008 /**
@@ -730,10 +1062,10 @@
730 1062 */
731 1063 private function load_woo_promos() {
732 1064 $this->woo_promos = array(
733 1065 'ppom' => array(
734 - 'title' => 'Product Add-Ons',
735 - 'description' => 'Add extra custom fields & add-ons on your product pages, like sizes, colors & more.',
1066 + 'title' => Loader::$labels['promotions']['woo']['ppom_title'],
1067 + 'description' => Loader::$labels['promotions']['woo']['ppom_desc'],
736 1068 'icon' => '<svg width="25" height="25" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1800 1800"><path d="M241.023,324.818c0.252,0,0.505,0.035,0.758,0.035h465.68c17.266,0,31.256-13.99,31.256-31.252 c0-17.262-13.99-31.247-31.256-31.247H351.021h-109.24c-17.258,0-31.252,13.985-31.252,31.247 C210.529,310.605,224.121,324.412,241.023,324.818z"/><path d="M210.529,450.306c0,17.257,13.994,31.252,31.252,31.252h769.451c17.262,0,31.256-13.995,31.256-31.252 c0-17.266-13.994-31.252-31.256-31.252H241.781C224.523,419.054,210.529,433.04,210.529,450.306z"/><path d="M1011.232,575.751H241.781c-8.149,0-15.549,3.147-21.116,8.261c-6.213,5.712-10.136,13.879-10.136,22.987 c0,17.262,13.994,31.26,31.252,31.26h769.451c17.262,0,31.256-13.999,31.256-31.26c0-9.108-3.923-17.275-10.141-22.987 C1026.781,578.898,1019.386,575.751,1011.232,575.751z"/><path d="M1011.232,732.461H241.781c-17.258,0-31.252,13.99-31.252,31.247c0,17.262,13.994,31.257,31.252,31.257 h769.451c17.262,0,31.256-13.995,31.256-31.257C1042.488,746.451,1028.494,732.461,1011.232,732.461z"/><path d="M1011.232,889.157H241.781c-8.149,0-15.549,3.147-21.116,8.261c-6.213,5.713-10.136,13.879-10.136,22.987 c0,17.257,13.994,31.261,31.252,31.261h769.451c17.262,0,31.256-14.004,31.256-31.261c0-9.108-3.923-17.274-10.141-22.987 C1026.781,892.305,1019.386,889.157,1011.232,889.157z"/><path d="M1011.232,1045.867H241.781c-17.258,0-31.252,13.99-31.252,31.243c0,17.271,13.994,31.265,31.252,31.265 h769.451c17.262,0,31.256-13.994,31.256-31.265C1042.488,1059.857,1028.494,1045.867,1011.232,1045.867z"/><path d="M1011.232,1202.576H241.781c-17.258,0-31.252,13.995-31.252,31.252c0,17.258,13.994,31.252,31.252,31.252 h769.451c17.262,0,31.256-13.994,31.256-31.252C1042.488,1216.571,1028.494,1202.576,1011.232,1202.576z"/><path d="M1011.232,1359.273H241.781c-8.149,0-15.549,3.151-21.116,8.265c-6.213,5.713-10.136,13.875-10.136,22.987 c0,17.258,13.994,31.261,31.252,31.261h769.451c17.262,0,31.256-14.003,31.256-31.261c0-9.112-3.923-17.274-10.141-22.987 C1026.781,1362.425,1019.386,1359.273,1011.232,1359.273z"/><path d="M1233.542,251.228l-49.851-45.109L1052.136,87.076l-59.185-53.554c-5.293-4.792-11.947-7.421-18.786-7.836 h-3.49H83.676c-45.688,0-82.858,37.375-82.858,83.316v1583.612c0,45.94,37.17,83.316,82.858,83.316h1078.562 c45.68,0,82.845-37.376,82.845-83.316V277.08v-3.182C1244.646,264.73,1240.261,256.589,1233.542,251.228z M1003.117,125.864 l131.119,118.657h-131.119V125.864z M1183.691,1692.613c0,12.094-9.622,21.926-21.454,21.926H83.676 c-11.836,0-21.467-9.832-21.467-21.926V109.001c0-12.089,9.631-21.925,21.467-21.925h857.857V275.38 c0,17.052,13.785,30.862,30.786,30.862h211.372V1692.613z"/><path d="M1798.578,180.737c-7.049-88.305-81.114-158.02-171.205-158.02c-0.004,0-0.004,0-0.004,0 c-45.889,0-89.033,17.874-121.479,50.32c-29.18,29.175-46.519,67.005-49.73,107.699h-0.586v13.609c0,0.06-0.005,0.115-0.005,0.175 c0,0.026,0.005,0.056,0.005,0.082l-0.005,1369.26h0.197c0.557,5.404,2.522,10.731,6.047,15.373l141.135,185.91 c5.803,7.648,14.851,12.136,24.447,12.136c9.601-0.004,18.646-4.496,24.447-12.14l141.093-185.897 c3.528-4.65,5.494-9.982,6.051-15.391h0.197V180.737H1798.578z M1549.299,116.448c20.854-20.855,48.578-32.339,78.07-32.339h0.004 c50.24,0,92.746,33.723,106.076,79.718h-212.19C1526.358,146.098,1535.896,129.852,1549.299,116.448z M1595.372,1502.468 l-78.413,0.005l0.005-1260.345h220.828v1260.336h-81.103l0.009-1016.486l-61.335,0.004L1595.372,1502.468z M1627.382,1695.821 l-100.171-131.963l200.338-0.004L1627.382,1695.821z"/></svg>',
737 1069 'has_install' => true,
738 1070 'link' => wp_nonce_url(
739 1071 add_query_arg(
@@ -746,22 +1078,22 @@
746 1078 'install-plugin_woocommerce-product-addon'
747 1079 ),
748 1080 ),
749 1081 'sparks-wishlist' => array(
750 - 'title' => 'Wishlist',
751 - 'description' => 'Loyalize your customers by allowing them to save their favorite products.',
1082 + 'title' => Loader::$labels['promotions']['woo']['spark_title1'],
1083 + 'description' => Loader::$labels['promotions']['woo']['spark_desc1'],
752 1084 'icon' => '<svg width="25" height="25" viewBox="0 0 60 60" fill="none" xmlns="http://www.w3.org/2000/SVG" aria-hidden="true"><path d="M60 21.25H57.5V40.125H60V21.25Z"></path><path d="M2.5 40H0V8.75C0 6.625 1.625 5 3.75 5H25V7.5H3.75C3 7.5 2.5 8 2.5 8.75V40Z"></path><path d="M56.25 51.25H3.75C1.625 51.25 0 49.625 0 47.5V42.5H25V45H2.5V47.5C2.5 48.25 3 48.75 3.75 48.75H56.25C57 48.75 57.5 48.25 57.5 47.5V43.75H60V47.5C60 49.625 58.375 51.25 56.25 51.25Z"></path><path d="M23.75 58.75H21.25V57.25L22.5 51.125V50H25V51.5L23.75 57.625V58.75Z"></path><path d="M38.75 58.75H36.25V57.625L35 51.25V50H37.5V51.125L38.75 57.5V58.75Z"></path><path d="M41.25 57.5H18.75V60H41.25V57.5Z"></path><path d="M56.25 32.5H43.75C41.625 32.5 40 30.875 40 28.75V3.75C40 1.625 41.625 0 43.75 0H56.25C58.375 0 60 1.625 60 3.75V28.75C60 30.875 58.375 32.5 56.25 32.5ZM43.75 2.5C43 2.5 42.5 3 42.5 3.75V28.75C42.5 29.5 43 30 43.75 30H56.25C57 30 57.5 29.5 57.5 28.75V3.75C57.5 3 57 2.5 56.25 2.5H43.75Z"></path><path d="M50 27.5C50.6904 27.5 51.25 26.9404 51.25 26.25C51.25 25.5596 50.6904 25 50 25C49.3096 25 48.75 25.5596 48.75 26.25C48.75 26.9404 49.3096 27.5 50 27.5Z"></path><path d="M51.25 45H31.25C29.125 45 27.5 43.375 27.5 41.25V8.75C27.5 6.625 29.125 5 31.25 5H37.5V7.5H31.25C30.5 7.5 30 8 30 8.75V41.25C30 42 30.5 42.5 31.25 42.5H51.25C52 42.5 52.5 42 52.5 41.25V35H55V41.25C55 43.375 53.375 45 51.25 45Z"></path><path d="M41.25 40C41.9404 40 42.5 39.4404 42.5 38.75C42.5 38.0596 41.9404 37.5 41.25 37.5C40.5596 37.5 40 38.0596 40 38.75C40 39.4404 40.5596 40 41.25 40Z"></path><path d="M21.75 40H18.25L13.25 35H11.75L6.75 40H0V37.5H5.75L10.75 32.5H14.25L19.25 37.5H20.75L52.875 5.375L54.625 7.125L21.75 40Z"></path><path d="M55 11.25H52.5V7.5H48.75V5H55V11.25Z"></path><defs><clip-path id="clip0"><rect width="60" height="60" fill="white"></rect></clip-path></defs></svg>',
753 1085 'link' => tsdk_utmify( 'https://themeisle.com/plugins/sparks-for-woocommerce/', 'promo', 'products-tabs' ),
754 1086 ),
755 1087 'sparks-announcement' => array(
756 - 'title' => 'Multi-Announcement Bars',
757 - 'description' => 'Add a top notification bar on your website to highlight the latest products, offers, or upcoming events.',
1088 + 'title' => Loader::$labels['promotions']['woo']['spark_title2'],
1089 + 'description' => Loader::$labels['promotions']['woo']['spark_desc2'],
758 1090 'icon' => '<svg width="25" height="25" viewBox="0 0 60 61" fill="none" xmlns="http://www.w3.org/2000/SVG" aria-hidden="true"><path d="M30 8.89282C29.6685 8.89282 29.3505 8.76113 29.1161 8.52671C28.8817 8.29228 28.75 7.97434 28.75 7.64282V1.39282C28.75 1.0613 28.8817 0.743359 29.1161 0.508939C29.3505 0.274518 29.6685 0.142822 30 0.142822C30.3315 0.142822 30.6495 0.274518 30.8839 0.508939C31.1183 0.743359 31.25 1.0613 31.25 1.39282V7.64282C31.25 7.97434 31.1183 8.29228 30.8839 8.52671C30.6495 8.76113 30.3315 8.89282 30 8.89282Z"></path><path d="M30 21.9105L26.25 18.1605V7.82598L26.9409 7.47992C27.8914 7.00723 28.9385 6.76123 30 6.76123C31.0615 6.76123 32.1086 7.00723 33.0591 7.47992L33.75 7.82598V18.1605L30 21.9105ZM28.75 17.1253L30 18.3753L31.25 17.1253V9.44219C30.4344 9.19928 29.5656 9.19928 28.75 9.44219V17.1253Z"></path><path d="M60 60.1428H0V22.6428H17.5C17.8315 22.6428 18.1495 22.7745 18.3839 23.0089C18.6183 23.2434 18.75 23.5613 18.75 23.8928C18.75 24.2243 18.6183 24.5423 18.3839 24.7767C18.1495 25.0111 17.8315 25.1428 17.5 25.1428H2.5V57.6428H57.5V25.1428H42.5C42.1685 25.1428 41.8505 25.0111 41.6161 24.7767C41.3817 24.5423 41.25 24.2243 41.25 23.8928C41.25 23.5613 41.3817 23.2434 41.6161 23.0089C41.8505 22.7745 42.1685 22.6428 42.5 22.6428H60V60.1428Z"></path><path d="M11.2493 53.8933C11.0421 53.8929 10.8383 53.841 10.6561 53.7424C10.474 53.6438 10.3191 53.5015 10.2055 53.3283C10.0919 53.1551 10.0231 52.9564 10.0052 52.75C9.98727 52.5436 10.0209 52.336 10.103 52.1458L26.353 14.6459C26.4182 14.4953 26.5125 14.359 26.6304 14.2448C26.7483 14.1306 26.8876 14.0408 27.0402 13.9804C27.1928 13.9201 27.3559 13.8903 27.52 13.893C27.6841 13.8956 27.8461 13.9306 27.9967 13.9958C28.1473 14.0611 28.2836 14.1553 28.3978 14.2732C28.5119 14.3912 28.6018 14.5304 28.6621 14.683C28.7225 14.8357 28.7522 14.9987 28.7496 15.1628C28.7469 15.3269 28.712 15.4889 28.6467 15.6395L12.3967 53.1395C12.2999 53.3634 12.1397 53.5541 11.9358 53.6881C11.7319 53.822 11.4932 53.8934 11.2493 53.8933Z"></path><path d="M48.7505 53.8935C48.5065 53.8935 48.2679 53.8222 48.064 53.6883C47.8601 53.5543 47.6999 53.3637 47.603 53.1398L31.353 15.6398C31.2212 15.3356 31.2157 14.9915 31.3376 14.6833C31.4595 14.375 31.6989 14.1278 32.003 13.9961C32.3072 13.8643 32.6513 13.8588 32.9595 13.9807C33.2678 14.1026 33.515 14.3419 33.6467 14.6461L49.8967 52.1461C49.9789 52.3363 50.0125 52.5439 49.9946 52.7503C49.9767 52.9566 49.9078 53.1553 49.7942 53.3285C49.6806 53.5018 49.5258 53.6441 49.3436 53.7427C49.1614 53.8413 48.9576 53.8932 48.7505 53.8936V53.8935Z"></path><path d="M30 33.8928C29.6685 33.8928 29.3505 33.7611 29.1161 33.5267C28.8817 33.2923 28.75 32.9743 28.75 32.6428V25.1428C28.75 24.8113 28.8817 24.4934 29.1161 24.2589C29.3505 24.0245 29.6685 23.8928 30 23.8928C30.3315 23.8928 30.6495 24.0245 30.8839 24.2589C31.1183 24.4934 31.25 24.8113 31.25 25.1428V32.6428C31.25 32.9743 31.1183 33.2923 30.8839 33.5267C30.6495 33.7611 30.3315 33.8928 30 33.8928Z"></path><path d="M45 30.1428H15C14.6685 30.1428 14.3505 30.0111 14.1161 29.7767C13.8817 29.5423 13.75 29.2243 13.75 28.8928C13.75 28.5613 13.8817 28.2434 14.1161 28.0089C14.3505 27.7745 14.6685 27.6428 15 27.6428H45C45.3315 27.6428 45.6495 27.7745 45.8839 28.0089C46.1183 28.2434 46.25 28.5613 46.25 28.8928C46.25 29.2243 46.1183 29.5423 45.8839 29.7767C45.6495 30.0111 45.3315 30.1428 45 30.1428Z"></path><defs><clip-path id="clip0"><rect width="60" height="60" fill="white" transform="translate(0 0.142822)"></rect></clip-path></defs></svg>',
759 1091 'link' => tsdk_utmify( 'https://themeisle.com/plugins/sparks-for-woocommerce/', 'promo', 'products-tabs' ),
760 1092 ),
761 1093 'sparks-product-review' => array(
762 - 'title' => 'Advanced Product Review',
763 - 'description' => 'Enable an advanced review section, enlarging the basic review options with lots of capabilities.',
1094 + 'title' => Loader::$labels['promotions']['woo']['spark_title3'],
1095 + 'description' => Loader::$labels['promotions']['woo']['spark_desc3'],
764 1096 'icon' => '<svg width="25" height="25" viewBox="0 0 60 61" fill="none" xmlns="http://www.w3.org/2000/SVG" aria-hidden="true"><path d="M58.75 54.1797H1.25C1.08584 54.1797 0.923271 54.1474 0.771595 54.0846C0.619919 54.0218 0.482103 53.9297 0.366021 53.8137C0.24994 53.6976 0.157867 53.5598 0.0950637 53.4081C0.0322604 53.2564 -4.26571e-05 53.0939 4.22759e-08 52.9297V6.67969C-4.26571e-05 6.51552 0.0322604 6.35296 0.0950637 6.20128C0.157867 6.04961 0.24994 5.91179 0.366021 5.79571C0.482103 5.67963 0.619919 5.58755 0.771595 5.52475C0.923271 5.46195 1.08584 5.42964 1.25 5.42969H58.75C58.9142 5.42964 59.0767 5.46195 59.2284 5.52475C59.3801 5.58755 59.5179 5.67963 59.634 5.79571C59.7501 5.91179 59.8421 6.04961 59.9049 6.20128C59.9677 6.35296 60 6.51552 60 6.67969V52.9297C60 53.0939 59.9677 53.2564 59.9049 53.4081C59.8421 53.5598 59.7501 53.6976 59.634 53.8137C59.5179 53.9297 59.3801 54.0218 59.2284 54.0846C59.0767 54.1474 58.9142 54.1797 58.75 54.1797ZM2.5 51.6797H57.5V7.92969H2.5V51.6797Z"></path><path d="M6.25 15.4297C6.94036 15.4297 7.5 14.87 7.5 14.1797C7.5 13.4893 6.94036 12.9297 6.25 12.9297C5.55964 12.9297 5 13.4893 5 14.1797C5 14.87 5.55964 15.4297 6.25 15.4297Z"></path><path d="M10 15.4297C10.6904 15.4297 11.25 14.87 11.25 14.1797C11.25 13.4893 10.6904 12.9297 10 12.9297C9.30964 12.9297 8.75 13.4893 8.75 14.1797C8.75 14.87 9.30964 15.4297 10 15.4297Z"></path><path d="M13.75 15.4297C14.4404 15.4297 15 14.87 15 14.1797C15 13.4893 14.4404 12.9297 13.75 12.9297C13.0596 12.9297 12.5 13.4893 12.5 14.1797C12.5 14.87 13.0596 15.4297 13.75 15.4297Z"></path><path d="M58.75 15.4297H18.75C18.4185 15.4297 18.1005 15.298 17.8661 15.0636C17.6317 14.8292 17.5 14.5112 17.5 14.1797C17.5 13.8482 17.6317 13.5302 17.8661 13.2958C18.1005 13.0614 18.4185 12.9297 18.75 12.9297H58.75C59.0815 12.9297 59.3995 13.0614 59.6339 13.2958C59.8683 13.5302 60 13.8482 60 14.1797C60 14.5112 59.8683 14.8292 59.6339 15.0636C59.3995 15.298 59.0815 15.4297 58.75 15.4297Z"></path><path d="M28.7502 37.9297C28.4187 37.9295 28.1009 37.7978 27.8664 37.5634L24.4289 34.1259C24.198 33.8908 24.0693 33.574 24.0708 33.2445C24.0723 32.915 24.2039 32.5994 24.4369 32.3664C24.6699 32.1334 24.9855 32.0018 25.315 32.0003C25.6445 31.9988 25.9613 32.1275 26.1964 32.3584L28.6977 34.8597L38.8588 23.4522C38.968 23.3296 39.1002 23.2298 39.2479 23.1583C39.3957 23.0869 39.5561 23.0452 39.7199 23.0358C39.8838 23.0263 40.0479 23.0492 40.2029 23.1032C40.3579 23.1571 40.5008 23.2411 40.6233 23.3503C40.7459 23.4594 40.8457 23.5917 40.9172 23.7394C40.9886 23.8872 41.0303 24.0476 41.0397 24.2114C41.0492 24.3753 41.0263 24.5394 40.9723 24.6944C40.9184 24.8494 40.8344 24.9922 40.7253 25.1148L29.6834 37.511C29.5702 37.6382 29.4322 37.7409 29.2779 37.8129C29.1237 37.8849 28.9563 37.9247 28.7862 37.9298L28.7502 37.9297Z"></path><path d="M29.977 44.1812C28.3217 44.1775 26.6876 43.8085 25.1912 43.1007C23.6948 42.3928 22.3731 41.3635 21.3203 40.0861C20.2675 38.8087 19.5095 37.3148 19.1004 35.7108C18.6913 34.1068 18.6413 32.4322 18.9537 30.8067C19.2662 29.1811 19.9335 27.6445 20.9081 26.3065C21.8827 24.9684 23.1406 23.862 24.592 23.0659C26.0433 22.2699 27.6525 21.804 29.3046 21.7013C30.9568 21.5987 32.6113 21.8619 34.15 22.4722C34.4579 22.5949 34.7044 22.8349 34.8354 23.1393C34.9663 23.4438 34.9709 23.7878 34.8482 24.0957C34.7255 24.4036 34.4856 24.6501 34.1811 24.7811C33.8766 24.912 33.5326 24.9166 33.2247 24.7939C31.44 24.0862 29.472 23.985 27.6241 24.5059C25.7762 25.0269 24.1508 26.141 22.9985 27.6767C21.8462 29.2124 21.2308 31.0844 21.2473 33.0043C21.2637 34.9242 21.9111 36.7854 23.0895 38.3011C24.268 39.8168 25.9122 40.903 27.7688 41.3922C29.6254 41.8813 31.5913 41.7464 33.3637 41.0082C35.136 40.27 36.6164 38.9694 37.5768 37.3069C38.5372 35.6444 38.9242 33.7122 38.6782 31.8081C38.6568 31.6451 38.6678 31.4795 38.7104 31.3208C38.7531 31.1621 38.8267 31.0133 38.927 30.8831C39.0272 30.7528 39.1522 30.6436 39.2947 30.5617C39.4373 30.4798 39.5945 30.4268 39.7575 30.4058C39.9206 30.3848 40.0861 30.3961 40.2448 30.4391C40.4034 30.4822 40.552 30.5561 40.682 30.6566C40.8121 30.7572 40.921 30.8824 41.0026 31.0251C41.0842 31.1678 41.1368 31.3252 41.1574 31.4883C41.3469 32.9535 41.2459 34.4417 40.8602 35.8679C40.4745 37.294 39.8116 38.6303 38.9094 39.8002C38.0072 40.9702 36.8834 41.9509 35.6021 42.6865C34.3208 43.4221 32.9071 43.898 31.4419 44.0872C30.9561 44.1494 30.4668 44.1807 29.977 44.1812Z"></path><defs><clip-path id="clip0"><rect width="60" height="60" fill="white" transform="translate(0 0.429688)"></rect></clip-path></defs></svg>',
765 1097 'link' => tsdk_utmify( 'https://themeisle.com/plugins/sparks-for-woocommerce/', 'promo', 'products-tabs' ),
766 1098 ),
767 1099 );
@@ -774,11 +1106,11 @@
774 1106 }
775 1107
776 1108 add_action(
777 1109 'woocommerce_product_data_tabs',
778 - function( $tabs ) {
1110 + function ( $tabs ) {
779 1111 $tabs['tisdk-suggestions'] = array(
780 - 'label' => 'More extensions from Themeisle',
1112 + 'label' => Loader::$labels['promotions']['woo']['title'],
781 1113 'target' => 'tisdk_suggestions',
782 1114 'class' => array(),
783 1115 'priority' => 1000,
784 1116 );
@@ -783,9 +1115,9 @@
783 1115 'priority' => 1000,
784 1116 );
785 1117
786 1118 return $tabs;
787 - }
1119 + }
788 1120 );
789 1121
790 1122 add_action( 'woocommerce_product_data_panels', array( $this, 'woocommerce_tab_content' ) );
791 1123 }
@@ -796,12 +1128,12 @@
796 1128 public function woocommerce_tab_content() {
797 1129 // Filter content based on if the key exists in $this->promotions array.
798 1130 $content = array_filter(
799 1131 $this->woo_promos,
800 - function( $key ) {
1132 + function ( $key ) {
801 1133 return in_array( $key, $this->promotions, true );
802 1134 },
803 - ARRAY_FILTER_USE_KEY
1135 + ARRAY_FILTER_USE_KEY
804 1136 );
805 1137
806 1138 // Display CSS
807 1139 self::render_woo_tabs_css();
@@ -810,9 +1142,9 @@
810 1142 ?>
811 1143
812 1144 <div id="tisdk_suggestions" class="panel woocommerce_options_panel hidden">
813 1145 <div class="tisdk-suggestions-header">
814 - <h4>Recommended extensions</h4>
1146 + <h4><?php echo esc_html( Loader::$labels['promotions']['woo']['title2'] ); ?></h4>
815 1147 </div>
816 1148 <div class="tisdk-suggestions-content">
817 1149 <?php foreach ( $content as $key => $item ) : ?>
818 1150 <div class="tisdk-suggestion" id="<?php echo esc_attr( $key ); ?>">
@@ -826,11 +1158,13 @@
826 1158 <p><?php echo esc_html( $item['description'] ); ?></p>
827 1159 </div>
828 1160 <div class="tisdk-suggestion-cta">
829 1161 <a href="<?php echo esc_url( $item['link'] ); ?>" target="blank" class="button">
830 - <?php echo ( ( isset( $item['has_install'] ) && $item['has_install'] ) ? 'Install' : 'Learn More' ); ?>
1162 + <?php echo( ( isset( $item['has_install'] ) && $item['has_install'] ) ? esc_html( Loader::$labels['promotions']['woo']['cta_install'] ) : esc_html( Loader::$labels['promotions']['woo']['learn_more'] ) ); ?>
831 1163 </a>
832 - <a class="suggestion-dismiss" title="Dismiss this suggestion" href="#"></a>
1164 + <a class="suggestion-dismiss"
1165 + title="<?php echo esc_attr( Loader::$labels['promotions']['woo']['dismiss'] ); ?>"
1166 + href="#"></a>
833 1167 </div>
834 1168 </div>
835 1169 <?php endforeach; ?>
836 1170 </div>
@@ -849,25 +1183,29 @@
849 1183 .tisdk-suggestions_options a {
850 1184 display: flex !important;
851 1185 align-items: center;
852 1186 }
1187 +
853 1188 .tisdk-suggestions_options a::before {
854 1189 content: url("data:image/svg+xml,%3Csvg fill='%23135e96' xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512'%3E%3Cpath d='<?php echo esc_attr( $icon ); ?>'/%3E%3C/svg%3E") !important;
855 1190 min-width: 13px;
856 1191 max-width: 13px;
857 - margin: auto;
858 1192 }
1193 +
859 1194 .tisdk-suggestions_options.active a::before {
860 1195 content: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512'%3E%3Cpath d='<?php echo esc_attr( $icon ); ?>'/%3E%3C/svg%3E") !important;
861 1196 }
1197 +
862 1198 .tisdk-suggestions-header {
863 1199 padding: 1em 1.5em;
864 1200 border-bottom: 1px solid #eee;
865 1201 }
1202 +
866 1203 .tisdk-suggestions-header h4 {
867 1204 font-size: 1.1em;
868 1205 margin: 0;
869 1206 }
1207 +
870 1208 .tisdk-suggestion {
871 1209 display: flex;
872 1210 align-items: center;
873 1211 flex-direction: row;
@@ -872,8 +1210,9 @@
872 1210 align-items: center;
873 1211 flex-direction: row;
874 1212 padding: 1em 1.5em;
875 1213 }
1214 +
876 1215 .tisdk-suggestion-icon {
877 1216 height: 40px;
878 1217 margin: 0;
879 1218 margin-right: 0px;
@@ -885,17 +1224,21 @@
885 1224 border-radius: 100%;
886 1225 align-items: center;
887 1226 padding: 5px;
888 1227 }
1228 +
889 1229 .tisdk-suggestion-icon svg {
890 1230 fill: #fff;
891 1231 }
1232 +
892 1233 .tisdk-suggestion-content {
893 1234 flex: 1 1 60%;
894 1235 }
1236 +
895 1237 .tisdk-suggestion-content h4 {
896 1238 margin: 0;
897 1239 }
1240 +
898 1241 .tisdk-suggestion-content p {
899 1242 margin: 0;
900 1243 margin-top: 4px;
901 1244 padding: 0;
@@ -900,13 +1243,15 @@
900 1243 margin-top: 4px;
901 1244 padding: 0;
902 1245 line-height: 1.5;
903 1246 }
1247 +
904 1248 .tisdk-suggestion-cta {
905 1249 flex: 1 1 30%;
906 1250 min-width: 160px;
907 1251 text-align: right;
908 1252 }
1253 +
909 1254 .tisdk-suggestion-cta .button {
910 1255 display: inline-block;
911 1256 min-width: 120px;
912 1257 text-align: center;
@@ -911,8 +1256,9 @@
911 1256 min-width: 120px;
912 1257 text-align: center;
913 1258 margin: 0;
914 1259 }
1260 +
915 1261 .tisdk-suggestion-cta .suggestion-dismiss {
916 1262 position: relative;
917 1263 top: 5px;
918 1264 right: auto;
@@ -928,13 +1274,13 @@
928 1274 */
929 1275 public static function render_notice_dismiss_ajax() {
930 1276 ?>
931 1277 <script>
932 - jQuery(document).ready(function($) {
1278 + jQuery(document).ready(function ($) {
933 1279 // AJAX request to update the option value
934 - $( '.tisdk-suggestion .suggestion-dismiss' ).click(function(e) {
1280 + $('.tisdk-suggestion .suggestion-dismiss').click(function (e) {
935 1281 e.preventDefault();
936 - var suggestion = $(this).closest( '.tisdk-suggestion' );
1282 + var suggestion = $(this).closest('.tisdk-suggestion');
937 1283 var value = suggestion.attr('id');
938 1284
939 1285 var nonce = '<?php echo esc_attr( wp_create_nonce( 'tisdk_update_option' ) ); ?>';
940 1286
@@ -949,13 +1295,13 @@
949 1295 complete() {
950 1296 suggestion.remove();
951 1297
952 1298 // If element with .tisdk-suggestions-content has no children, hide the whole panel. Skip if the selector doesn't exist.
953 - if ( $( '.tisdk-suggestions-content' ).length && ! $( '.tisdk-suggestions-content' ).children().length ) {
954 - $( '.tisdk-suggestions_options' ).remove();
955 - $( '#tisdk_suggestions' ).remove();
956 - $( '.general_options' ).addClass( 'active' );
957 - $( '#general_product_data' ).css( 'display', 'block' );
1299 + if ($('.tisdk-suggestions-content').length && !$('.tisdk-suggestions-content').children().length) {
1300 + $('.tisdk-suggestions_options').remove();
1301 + $('#tisdk_suggestions').remove();
1302 + $('.general_options').addClass('active');
1303 + $('#general_product_data').css('display', 'block');
958 1304 }
959 1305 }
960 1306 });
961 1307 });
@@ -1001,6 +1347,63 @@
1001 1347 );
1002 1348
1003 1349 wp_send_json( $response );
1004 1350 wp_die();
1351 + }
1352 +
1353 + /**
1354 + * Check if the user has a support page.
1355 + */
1356 + public function has_support_page() {
1357 + $transient_name = 'tisdk_has_support_page';
1358 + $has_support = get_transient( $transient_name );
1359 +
1360 + if ( false === $has_support ) {
1361 + global $wpdb;
1362 +
1363 + // We use %i escape identifier that was added in WP 6.2.0, hence need to ignore PHPCS warning.
1364 + // We only show this notice to users on higher version as that is the minimum for Hyve as well.
1365 + $query = $wpdb->get_var( //phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
1366 + $wpdb->prepare( // phpcs:ignore WordPress.DB.PreparedSQLPlaceholders.ReplacementsWrongNumber
1367 + 'SELECT ID FROM %i WHERE post_type = %s AND post_status = %s AND post_title LIKE %s LIMIT 1', // phpcs:ignore WordPress.DB.PreparedSQLPlaceholders.UnsupportedPlaceholder
1368 + $wpdb->posts,
1369 + 'page',
1370 + 'publish',
1371 + '%support%'
1372 + )
1373 + );
1374 +
1375 + $has_support = $query ? 'yes' : 'no';
1376 +
1377 + set_transient( $transient_name, $has_support, 7 * DAY_IN_SECONDS );
1378 + }
1379 +
1380 + return 'yes' === $has_support;
1381 + }
1382 +
1383 + /**
1384 + * Check if the user has a donate page.
1385 + */
1386 + public function has_donate_page() {
1387 + $transient_name = 'tisdk_has_donate_page';
1388 + $has_donate = get_transient( $transient_name );
1389 +
1390 + if ( false === $has_donate ) {
1391 + global $wpdb;
1392 +
1393 + $query = $wpdb->get_var( //phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
1394 + $wpdb->prepare(
1395 + 'SELECT ID FROM ' . $wpdb->posts . ' WHERE post_type = %s AND post_status = %s AND post_title LIKE %s LIMIT 1',
1396 + 'page',
1397 + 'publish',
1398 + '%donate%'
1399 + )
1400 + );
1401 +
1402 + $has_donate = $query ? 'yes' : 'no';
1403 +
1404 + set_transient( $transient_name, $has_donate, 7 * DAY_IN_SECONDS );
1405 + }
1406 +
1407 + return 'yes' === $has_donate;
1005 1408 }
1006 1409 }