PluginProbe
Ultimate Store Kit / 3.0.9
Ultimate Store Kit v3.0.9
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 2.0.6 All 92 releases
ultimate-store-kit / includes / Admin / Biggopties.php

Biggopties.php in Ultimate Store Kit 3.0.9, at includes/Admin/Biggopties.php

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