PluginProbe
Ultimate Store Kit – Store Builder Addons for Elementor, WooCommerce Store Builder, EDD Store Builder / 3.0.4
Ultimate Store Kit – Store Builder Addons for Elementor, WooCommerce Store Builder, EDD Store Builder v3.0.4
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.4, at includes/Admin/Biggopties.php

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