PluginProbe
Ultimate Post Kit – Elementor Post Grid, Post Carousel, Post Slider & Blog Layout Widgets / 4.2.3
Ultimate Post Kit – Elementor Post Grid, Post Carousel, Post Slider & Blog Layout Widgets v4.2.3
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.2.3, at admin/admin-biggopti.php

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