PluginProbe
Ultimate Store Kit – Store Builder Addons for Elementor, WooCommerce Store Builder, EDD Store Builder / 3.0.2
Ultimate Store Kit – Store Builder Addons for Elementor, WooCommerce Store Builder, EDD Store Builder v3.0.2
3.1.4 3.0.8 3.0.9 3.1.0 3.1.2 3.1.3 3.0.7 3.0.5 3.0.4 3.0.3 3.0.2 trunk 1.5.0 1.5.1 1.5.2 1.6.1 1.6.2 1.6.3 1.6.4 2.0.0 2.0.1 2.0.2 2.0.3 2.0.4 2.0.5 All 93 releases
ultimate-store-kit / includes / Admin / Biggopties.php

Biggopties.php in Ultimate Store Kit – Store Builder Addons for Elementor, WooCommerce Store Builder, EDD Store Builder 3.0.2, at includes/Admin/Biggopties.php

633 lines 19.6 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace UltimateStoreKit\Admin;
4
5 use UltimateStoreKit\Base\Singleton;
6
7 /**
8 * Biggopties class
9 */
10 class Biggopties {
11 use Singleton;
12
13 private static $biggopties = [];
14
15 public function __construct() {
16
17 // add_action('admin_notices', [$this, 'show_biggopties']);
18 add_action('wp_ajax_ultimate-store-kit-biggopties', [$this, 'dismiss']);
19
20 // AJAX endpoint to fetch API biggopties on demand (after page load)
21 add_action('wp_ajax_usk_fetch_api_biggopties', [$this, 'ajax_fetch_api_biggopties']);
22 add_action('wp_ajax_usk_admin_api_biggopti_dismiss', [$this, 'usk_admin_api_biggopti_dismiss']);
23 add_action('admin_enqueue_scripts', [$this, 'enqueue_admin_scripts']);
24 }
25
26 /**
27 * Dismiss Admin API Biggopti.
28 */
29 public function usk_admin_api_biggopti_dismiss() {
30 $nonce = (isset($_POST['_wpnonce'])) ? sanitize_text_field($_POST['_wpnonce']) : '';
31 $display_id = (isset($_POST['display_id'])) ? sanitize_text_field($_POST['display_id']) : '';
32 $id = (isset($_POST['id'])) ? esc_attr($_POST['id']) : '';
33 $meta = (isset($_POST['meta'])) ? esc_attr($_POST['meta']) : '';
34
35 if (! wp_verify_nonce($nonce, 'ultimate-store-kit')) {
36 wp_send_json_error();
37 }
38
39 if (! current_user_can('manage_options')) {
40 wp_send_json_error();
41 }
42
43 // Prefer display_id; fallback: extract from id (bdt-admin-api-biggopti-{display_id})
44 if (empty($display_id) && !empty($id)) {
45 $prefix = 'bdt-admin-api-biggopti-';
46 if (strpos($id, $prefix) === 0) {
47 $display_id = substr($id, strlen($prefix));
48 } else {
49 $display_id = $id;
50 }
51 }
52
53 /**
54 * Valid inputs?
55 */
56 if (!empty($display_id)) {
57 if ('user' === $meta) {
58 $user_key = 'bdt-admin-api-biggopti-' . $display_id;
59 update_user_meta(get_current_user_id(), $user_key, true);
60 } else {
61 // Save to options table only - display_id based, no end-time expiration
62 $dismissals_option = get_option('bdt_biggopti_dismissals', []);
63 $dismissals_option[$display_id] = ['dismissed_at' => time()];
64 update_option('bdt_biggopti_dismissals', $dismissals_option, false);
65 }
66
67 wp_send_json_success();
68 }
69
70 wp_send_json_error();
71 }
72
73 /**
74 * Enqueue admin scripts
75 */
76 public function enqueue_admin_scripts() {
77 wp_enqueue_style('usk-admin-biggopti', BDTUSK_ASSETS_URL . 'admin/others/css/admin-biggopti.css', [], BDTUSK_VER);
78 wp_enqueue_style('bdt-admin-api-biggopti', BDTUSK_ASSETS_URL . 'admin/others/css/admin-api-biggopti.css', [], BDTUSK_VER);
79 wp_enqueue_style('bdt-product-feed', BDTUSK_ASSETS_URL . 'admin/others/css/product-feed.css', [], BDTUSK_VER);
80 wp_enqueue_script('usk-biggopti', BDTUSK_ASSETS_URL . 'admin/others/js/biggopti.js', ['jquery'], BDTUSK_VER, true);
81 wp_enqueue_script('usk-admin-api-biggopti', BDTUSK_ASSETS_URL . 'admin/others/js/admin-api-biggopti.js', ['jquery', 'wp-i18n'], BDTUSK_VER, true);
82 wp_set_script_translations('usk-admin-api-biggopti', 'ultimate-store-kit');
83
84 $dismissals = get_option('bdt_biggopti_dismissals', []);
85 $dismissed_display_ids = [];
86 $prefix = 'bdt-admin-biggopti-api-biggopti-';
87 foreach (array_keys($dismissals) as $key) {
88 if (strpos($key, $prefix) === 0) {
89 $dismissed_display_ids[] = substr($key, strlen($prefix));
90 } else {
91 $dismissed_display_ids[] = $key;
92 }
93 }
94
95 $current_sector = '';
96 if (isset($_GET['page']) && $_GET['page'] === 'ultimate_store_kit_options') {
97 $current_sector = 'plugin_dashboard';
98 }
99
100 $script_config = [
101 'ajaxurl' => admin_url('admin-ajax.php'),
102 'nonce' => wp_create_nonce('ultimate-store-kit'),
103 'isPro' => function_exists('usk_license_validation') && usk_license_validation(),
104 'assetsUrl' => defined('BDTUSK_ASSETS_URL') ? BDTUSK_ASSETS_URL : '',
105 'dismissedDisplayIds' => $dismissed_display_ids,
106 'currentSector' => $current_sector,
107 ];
108
109 wp_localize_script('usk-biggopti', 'UltimateStoreKitBiggoptiConfig', $script_config);
110 wp_localize_script('usk-admin-api-biggopti', 'UltimateStoreKitAdminApiBiggoptiConfig', $script_config);
111 }
112
113 /**
114 * Get Remote Biggopties Data from API
115 *
116 * @return array|mixed
117 */
118 private function get_api_biggopties_data() {
119 // API endpoint for biggopties - you can change this to your actual endpoint
120 $api_url = 'https://api.sigmative.io/prod/store/api/biggopti/api-data-records';
121
122 $response = wp_remote_get($api_url, [
123 'timeout' => 30,
124 'headers' => [
125 'Accept' => 'application/json',
126 ],
127 ]);
128
129 if (is_wp_error($response)) {
130 return [];
131 }
132
133 $response_code = wp_remote_retrieve_response_code($response);
134
135 $response_body = wp_remote_retrieve_body($response);
136
137 $biggopties = json_decode($response_body);
138
139 if (isset($biggopties) && isset($biggopties->{'ultimate-store-kit'})) {
140 $data = $biggopties->{'ultimate-store-kit'};
141 if (is_array($data)) {
142 return $data;
143 }
144 }
145
146 return [];
147 }
148
149 /**
150 * Check if a biggopti should be shown based on its enabled status and date range.
151 *
152 * @param object $biggopti The biggopti data from the API.
153 * @return bool True if the biggopti should be shown, false otherwise.
154 */
155 private function should_show_biggopti($biggopti) {
156 // Development override - set to true to bypass date checks for testing
157 $development_mode = false; // Set to true to bypass date checks
158
159 if ($development_mode) {
160 return true;
161 }
162
163 // Check if the biggopti is enabled
164 if (!isset($biggopti->is_enabled) || !$biggopti->is_enabled) {
165 return false;
166 }
167
168 // Check plugin compatibility
169 if (!$this->is_biggopti_compatible_with_plugin($biggopti)) {
170 return false;
171 }
172
173 // Check if the biggopti has a start date and end date
174 if (!isset($biggopti->start_date) || !isset($biggopti->end_date)) {
175 return false;
176 }
177
178 // Get timezone from biggopti or default to UTC
179 $timezone = isset($biggopti->timezone) ? $biggopti->timezone : 'UTC';
180
181 // Create DateTime objects with proper timezone (using global namespace)
182 $start_date = new \DateTime($biggopti->start_date, new \DateTimeZone($timezone));
183 $end_date = new \DateTime($biggopti->end_date, new \DateTimeZone($timezone));
184 $current_date = new \DateTime('now', new \DateTimeZone($timezone));
185
186 // Convert to timestamps for comparison
187 $start_timestamp = $start_date->getTimestamp();
188 $end_timestamp = $end_date->getTimestamp();
189 $current_timestamp = $current_date->getTimestamp();
190
191 // Check if the current date is within the start and end dates
192 if ($current_timestamp < $start_timestamp || $current_timestamp > $end_timestamp) {
193 return false;
194 }
195
196 // Check if biggopti should be visible after a certain time
197 if (isset($biggopti->visible_after) && $biggopti->visible_after > 0) {
198 $visible_after_timestamp = $start_timestamp + $biggopti->visible_after;
199 if ($current_timestamp < $visible_after_timestamp) {
200 return false;
201 }
202 }
203
204 return true;
205 }
206
207 /**
208 * Check if a biggopti is compatible with the current plugin installation
209 *
210 * @param object $biggopti The biggopti data from the API.
211 * @return bool True if the biggopti should be shown, false otherwise.
212 */
213 private function is_biggopti_compatible_with_plugin($biggopti) {
214 // Get current plugin info
215 $current_plugin_slug = $this->get_current_plugin_slug();
216 $is_pro_active = function_exists('_is_usk_pro_activated') ? _is_usk_pro_activated() : false;
217 $is_lite_active = $current_plugin_slug === 'ultimate-store-kit';
218 $is_pro_plugin = $current_plugin_slug === 'ultimate-store-kit-pro';
219
220 // Get client targets, default to ['both'] if not set or not an array
221 $client_targets = (isset($biggopti->client_targets) && is_array($biggopti->client_targets))
222 ? $biggopti->client_targets
223 : ['both'];
224
225 // Determine if this is targeted at Pro users
226 $pro_targeted = in_array('pro_targeted', $client_targets, true);
227
228 // Ensure client_targets is always an array
229 if (!is_array($client_targets)) {
230 $client_targets = [$client_targets];
231 }
232
233 // Handle pro_targeted parameter (only for free version)
234 if ($pro_targeted && $is_lite_active) {
235 // If pro_targeted is true, only show if pro is NOT active
236 $should_show = !$is_pro_active;
237 return $should_show;
238 }
239
240 // Check if any of the client targets match current plugin status
241 foreach ($client_targets as $target) {
242 $target = trim($target); // Clean up any whitespace
243
244 switch ($target) {
245 case 'pro':
246 // Pro-only biggopties: show only if pro is active
247 if ($is_pro_active) {
248 return true;
249 }
250 break;
251
252 case 'free':
253 if ($is_lite_active) {
254 return true;
255 }
256 break;
257 }
258 }
259
260 return false;
261 }
262
263 /**
264 * Get current plugin slug
265 *
266 * @return string
267 */
268 private function get_current_plugin_slug() {
269 // Get plugin basename from current file
270 $plugin_file = plugin_basename(BDTUSK__FILE__);
271
272 // Extract plugin slug from basename
273 $plugin_slug = dirname($plugin_file);
274
275 return $plugin_slug;
276 }
277
278 /**
279 * Render API biggopti HTML
280 *
281 * @param object $biggopti
282 * @return string
283 */
284 private function render_api_biggopti($biggopti) {
285 ob_start();
286
287 // Add custom CSS if provided
288 if (isset($biggopti->custom_css) && !empty($biggopti->custom_css)) {
289 echo '<style>' . wp_kses_post($biggopti->custom_css) . '</style>';
290 }
291
292 // Prepare background styles
293 $background_style = '';
294 $wrapper_classes = 'bdt-biggopti-wrapper';
295
296 if (isset($biggopti->background_color) && !empty($biggopti->background_color)) {
297 $background_style .= 'background-color: ' . esc_attr($biggopti->background_color) . ';';
298 }
299
300 if (isset($biggopti->image) && !empty($biggopti->image)) {
301 $background_style .= 'background-image: url(' . esc_url($biggopti->image) . ');';
302 $wrapper_classes .= ' has-background-image';
303 }
304
305 ?>
306 <div class="<?php echo esc_attr($wrapper_classes); ?>" <?php echo $background_style ? 'style="' . $background_style . '"' : ''; ?>>
307
308
309 <?php $title = (isset($biggopti->title) && !empty($biggopti->title)) ? $biggopti->title : ''; ?>
310
311 <div class="bdt-api-biggopti-content">
312 <div class="bdt-plugin-logo-wrapper">
313 <img height="auto" width="40" src="<?php echo esc_url(BDTUSK_ASSETS_URL); ?>images/logo.svg" alt="Ultimate Store Kit Logo">
314 </div>
315
316 <div class="bdt-biggopti-content">
317 <div class="bdt-biggopti-content-inner">
318 <?php if (isset($biggopti->logo) && !empty($biggopti->logo)) : ?>
319 <div class="bdt-biggopti-logo-wrapper">
320 <img width="100" src="<?php echo esc_url($biggopti->logo); ?>" alt="Logo">
321 </div>
322 <?php endif; ?>
323 <div class="bdt-biggopti-title-description">
324 <?php if (isset($title) && !empty($title)) : ?>
325 <h2 class="bdt-biggopti-title"><?php echo wp_kses_post($title); ?></h2>
326 <?php endif; ?>
327
328 <?php if (isset($biggopti->content) && !empty($biggopti->content)) : ?>
329 <div class="bdt-biggopti-html-content">
330 <?php echo wp_kses_post($biggopti->content); ?>
331 </div>
332 <?php endif; ?>
333 </div>
334 </div>
335
336 <div class="bdt-biggopti-content-right">
337 <?php
338 // Only show countdown if it's enabled, has an end date, and the end date is in the future
339 $show_countdown = isset($biggopti->show_countdown) && $biggopti->show_countdown && isset($biggopti->end_date);
340 if ($show_countdown) {
341 $end_timestamp = strtotime($biggopti->end_date);
342 $current_timestamp = current_time('timestamp');
343 $show_countdown = $end_timestamp > $current_timestamp;
344 }
345 ?>
346 <?php if ($show_countdown) : ?>
347 <div class="bdt-biggopti-countdown" data-end-date="<?php echo esc_attr($biggopti->end_date); ?>" data-timezone="<?php echo esc_attr($biggopti->timezone ? $biggopti->timezone : 'UTC'); ?>">
348 <div class="countdown-timer">Loading...</div>
349 </div>
350 <?php endif; ?>
351
352 <?php if (isset($biggopti->link) && !empty($biggopti->link)) : ?>
353 <div class="bdt-biggopti-btn">
354 <a href="<?php echo esc_url($biggopti->link); ?>" target="_blank">
355 <div class="nm-biggopti-btn">
356 <?php echo isset($biggopti->button_text) ? esc_html($biggopti->button_text) : 'Read More'; ?>
357 <span class="dashicons dashicons-arrow-right-alt"></span>
358 </div>
359 </a>
360 </div>
361 <?php endif; ?>
362 </div>
363 </div>
364 </div>
365 </div>
366 <?php
367 return ob_get_clean();
368 }
369
370 public static function add_biggopti($args = []) {
371 if (is_array($args)) {
372 self::$biggopties[] = $args;
373 }
374 }
375
376 /**
377 * AJAX: Build and return API biggopties HTML for dynamic injection
378 */
379 public function ajax_fetch_api_biggopties() {
380 $nonce = isset($_POST['_wpnonce']) ? sanitize_text_field($_POST['_wpnonce']) : '';
381 if (!wp_verify_nonce($nonce, 'ultimate-store-kit')) {
382 wp_send_json_error(['message' => 'invalid_nonce']);
383 }
384
385 if (!current_user_can('manage_options')) {
386 wp_send_json_error(['message' => 'forbidden']);
387 }
388
389 // Don't show biggopties on plugin/theme install and upload pages
390 $current_url = isset($_POST['current_url']) ? sanitize_text_field($_POST['current_url']) : '';
391
392 if (!empty($current_url)) {
393 $excluded_patterns = [
394 'plugin-install.php',
395 'theme-install.php',
396 'action=upload-plugin',
397 'action=upload-theme'
398 ];
399
400 foreach ($excluded_patterns as $pattern) {
401 if (strpos($current_url, $pattern) !== false) {
402 wp_send_json_success(['html' => '']);
403 }
404 }
405 }
406
407 $biggopties = $this->get_api_biggopties_data();
408 $grouped_biggopties = [];
409
410 if (is_array($biggopties)) {
411 foreach ($biggopties as $index => $biggopti) {
412 if ($this->should_show_biggopti($biggopti)) {
413 $display_id = isset($biggopti->display_id) ? $biggopti->display_id : 'default-' . $index;
414 if (!isset($grouped_biggopties[$display_id])) {
415 $grouped_biggopties[$display_id] = $biggopti;
416 }
417 }
418 }
419 }
420
421 // Build biggopties using the same pipeline as synchronous rendering
422 foreach ($grouped_biggopties as $display_id => $biggopti) {
423 $biggopti_id = isset($biggopti->id) ? $display_id : $biggopti->id;
424
425 self::add_biggopti([
426 'id' => 'api-biggopti-' . $biggopti_id,
427 'type' => isset($biggopti->type) ? $biggopti->type : 'info',
428 'category' => isset($biggopti->category) ? $biggopti->category : 'regular',
429 'dismissible' => true,
430 'html_message' => $this->render_api_biggopti($biggopti),
431 'dismissible-meta' => 'transient',
432 'dismissible-time' => isset($biggopti->end_date) ? max((new \DateTime($biggopti->end_date, new \DateTimeZone('UTC')))->getTimestamp() - time(), 0) : WEEK_IN_SECONDS,
433 ]);
434 }
435
436 ob_start();
437 $this->show_biggopties();
438 $markup = ob_get_clean();
439
440 wp_send_json_success(['html' => $markup]);
441 }
442
443 /**
444 * Dismiss Biggopti.
445 */
446 public function dismiss() {
447 $nonce = (isset($_POST['_wpnonce'])) ? sanitize_text_field($_POST['_wpnonce']) : '';
448 $id = (isset($_POST['id'])) ? esc_attr($_POST['id']) : '';
449 $time = (isset($_POST['time'])) ? esc_attr($_POST['time']) : '';
450 $meta = (isset($_POST['meta'])) ? esc_attr($_POST['meta']) : '';
451
452 if (! wp_verify_nonce($nonce, 'ultimate-store-kit')) {
453 wp_send_json_error();
454 }
455
456 if (! current_user_can('manage_options')) {
457 wp_send_json_error();
458 }
459
460 /**
461 * Valid inputs?
462 */
463 if (!empty($id)) {
464 // Handle regular biggopties
465 if ('user' === $meta) {
466 update_user_meta(get_current_user_id(), $id, true);
467 } else {
468 set_transient($id, true, $time);
469
470 // Also store in options table for persistence
471 $dismissals_option = get_option('bdt_biggopti_dismissals', []);
472 $dismissals_option[$id] = [
473 'dismissed_at' => time(),
474 'expires_at' => time() + intval($time),
475 ];
476 update_option('bdt_biggopti_dismissals', $dismissals_option, false);
477 }
478
479 wp_send_json_success();
480 }
481
482 wp_send_json_error();
483 }
484
485 /**
486 * Biggopti Types
487 */
488 public function show_biggopties() {
489
490 $defaults = [
491 'id' => '',
492 'type' => 'info',
493 'category' => 'regular',
494 'show_if' => true,
495 'title' => '',
496 'message' => '',
497 'class' => 'ultimate-store-kit-biggopti',
498 'dismissible' => false,
499 'dismissible-meta' => 'transient',
500 'dismissible-time' => WEEK_IN_SECONDS,
501 'data' => '',
502 'action_link' => '',
503 ];
504
505 foreach (self::$biggopties as $key => $biggopti) {
506
507 $biggopti = wp_parse_args($biggopti, $defaults);
508
509 // Check if biggopti is for White Label
510 if (defined('BDTUSK_WL') && $biggopti['category'] === 'regular') {
511 continue;
512 }
513
514 $classes = ['biggopti'];
515
516 $classes[] = $biggopti['class'];
517 if (isset($biggopti['type'])) {
518 $classes[] = 'biggopti-' . $biggopti['type'];
519 }
520
521 // Is biggopti dismissible?
522 if (true === $biggopti['dismissible']) {
523 $classes[] = 'is-dismissible';
524
525 // Dismissable time.
526 $biggopti['data'] = ' dismissible-time=' . esc_attr($biggopti['dismissible-time']) . ' ';
527 }
528
529 // Biggopti ID.
530 $biggopti_id = 'bdt-admin-biggopti-' . $biggopti['id'];
531 $biggopti['id'] = $biggopti_id;
532 if (!isset($biggopti['id'])) {
533 $biggopti_id = 'bdt-admin-biggopti-' . $biggopti['id'];
534 $biggopti['id'] = $biggopti_id;
535 } else {
536 $biggopti_id = $biggopti['id'];
537 }
538
539 $biggopti['classes'] = implode(' ', $classes);
540
541 // User meta.
542 $biggopti['data'] .= ' dismissible-meta=' . esc_attr($biggopti['dismissible-meta']) . ' ';
543 if ('user' === $biggopti['dismissible-meta']) {
544 $expired = get_user_meta(get_current_user_id(), $biggopti_id, true);
545 } elseif ('transient' === $biggopti['dismissible-meta']) {
546 $expired = get_transient($biggopti_id);
547
548 // If transient not found, check options table for persistent dismissal
549 if (false === $expired || empty($expired)) {
550 $dismissals_option = get_option('bdt_biggopti_dismissals', []);
551 if (isset($dismissals_option[$biggopti_id])) {
552 $dismissal = $dismissals_option[$biggopti_id];
553 // Check if dismissal is still valid (not expired)
554 if (isset($dismissal['expires_at']) && time() < $dismissal['expires_at']) {
555 $expired = true;
556 } else {
557 // Clean up expired dismissal from options
558 unset($dismissals_option[$biggopti_id]);
559 update_option('bdt_biggopti_dismissals', $dismissals_option, false);
560 }
561 }
562 }
563 }
564
565 // Biggopties visible after transient expire.
566 if (isset($biggopti['show_if'])) {
567
568 if (true === $biggopti['show_if']) {
569
570 // Is transient expired?
571 if (false === $expired || empty($expired)) {
572 self::biggopti_layout($biggopti);
573 }
574 }
575 } else {
576
577 // No transient biggopties.
578 self::biggopti_layout($biggopti);
579 }
580 }
581 }
582
583 /**
584 * New Biggopti Layout
585 * @param array $biggopti Biggopti biggopti_layout.
586 * @return void
587 * @since 6.11.3
588 */
589
590 public static function biggopti_layout($biggopti = []) {
591
592 if (isset($biggopti['html_message']) && ! empty($biggopti['html_message'])) {
593 self::new_biggopti_layout($biggopti);
594 return;
595 }
596
597 ?>
598 <div id="<?php echo esc_attr($biggopti['id']); ?>" class="<?php echo esc_attr($biggopti['classes']); ?>" <?php echo esc_attr($biggopti['data']); ?>>
599 <div class="bdt-biggopti-wrapper">
600 <div class="bdt-biggopti-icon-wrapper">
601 <img height="25" width="25" src="<?php echo esc_url(BDTUSK_ASSETS_URL); ?>images/logo.svg">
602 </div>
603
604 <div class="bdt-biggopti-content">
605 <?php if (isset($biggopti['title']) && !empty($biggopti['title'])) : ?>
606 <h2 class="bdt-biggopti-title"><?php echo wp_kses_post($biggopti['title']); ?></h2>
607 <?php endif; ?>
608
609 <p class="bdt-biggopti-text"><?php echo wp_kses_post($biggopti['message']); ?></p>
610
611 <?php if (isset($biggopti['action_link']) && !empty($biggopti['action_link'])) : ?>
612 <div class="bdt-biggopti-btn">
613 <a href="#">Renew Now</a>
614 </div>
615 <?php endif; ?>
616 </div>
617 </div>
618 </div>
619 <?php
620 }
621
622 public static function new_biggopti_layout($biggopti = []) {
623 ?>
624 <div id="<?php echo esc_attr($biggopti['id']); ?>" class="<?php echo esc_attr($biggopti['classes']); ?>" <?php echo esc_attr($biggopti['data']); ?>>
625 <?php
626 echo wp_kses_post($biggopti['html_message']);
627 ?>
628 </div>
629
630 <?php
631 }
632 }
633