PluginProbe
Ultimate Post Kit – Elementor Post Grid, Post Carousel, Post Slider & Blog Layout Widgets / 4.1.14
Ultimate Post Kit – Elementor Post Grid, Post Carousel, Post Slider & Blog Layout Widgets v4.1.14
4.5.4 4.2.1 4.2.2 4.2.3 4.5.0 4.5.2 4.5.3 4.2.0 4.1.18 4.1.17 4.1.16 4.1.15 4.1.14 4.1.13 4.1.12 4.1.11 4.1.10 4.1.9 4.1.8 4.0.9 4.1.0 4.1.1 4.1.2 4.1.3 4.1.4 All 146 releases
ultimate-post-kit / admin / admin-biggopti.php

admin-biggopti.php in Ultimate Post Kit – Elementor Post Grid, Post Carousel, Post Slider & Blog Layout Widgets 4.1.14, at admin/admin-biggopti.php

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