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

549 lines 16.2 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 // Prepare background styles
208 $background_style = '';
209 $wrapper_classes = 'bdt-biggopti-wrapper';
210
211 if (isset($biggopti->background_color) && !empty($biggopti->background_color)) {
212 $background_style .= 'background-color: ' . $biggopti->background_color . ';';
213 }
214
215 if (isset($biggopti->image) && !empty($biggopti->image)) {
216 $background_style .= 'background-image: url(' . esc_url_raw($biggopti->image) . ');';
217 $wrapper_classes .= ' has-background-image';
218 }
219
220 ?>
221 <div class="<?php echo esc_attr($wrapper_classes); ?>" <?php echo $background_style ? 'style="' . esc_attr($background_style) . '"' : ''; ?>>
222
223
224 <?php $title = (isset($biggopti->title) && !empty($biggopti->title)) ? $biggopti->title : ''; ?>
225
226 <div class="bdt-api-biggopti-content">
227 <div class="bdt-plugin-logo-wrapper">
228 <img height="auto" width="40" src="<?php echo esc_url(BDTUPK_ASSETS_URL); ?>images/logo.svg" alt="Ultimate Post Kit Logo">
229 </div>
230
231 <div class="bdt-biggopti-content">
232 <div class="bdt-biggopti-content-inner">
233 <?php if (isset($biggopti->logo) && !empty($biggopti->logo)) : ?>
234 <div class="bdt-biggopti-logo-wrapper">
235 <img width="100" src="<?php echo esc_url($biggopti->logo); ?>" alt="Logo">
236 </div>
237 <?php endif; ?>
238 <div class="bdt-biggopti-title-description">
239 <?php if (isset($title) && !empty($title)) : ?>
240 <h2 class="bdt-biggopti-title"><?php echo wp_kses_post($title); ?></h2>
241 <?php endif; ?>
242
243 <?php if (isset($biggopti->content) && !empty($biggopti->content)) : ?>
244 <div class="bdt-biggopti-html-content">
245 <?php echo wp_kses_post($biggopti->content); ?>
246 </div>
247 <?php endif; ?>
248 </div>
249 </div>
250
251 <div class="bdt-biggopti-content-right">
252 <?php
253 // Only show countdown if it's enabled, has an end date, and the end date is in the future
254 $show_countdown = isset($biggopti->show_countdown) && $biggopti->show_countdown && isset($biggopti->end_date);
255 if ($show_countdown) {
256 $end_timestamp = strtotime($biggopti->end_date);
257 $current_timestamp = current_time('timestamp');
258 $show_countdown = $end_timestamp > $current_timestamp;
259 }
260 ?>
261 <?php if ($show_countdown) : ?>
262 <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'); ?>">
263 <div class="countdown-timer">Loading...</div>
264 </div>
265 <?php endif; ?>
266
267 <?php if (isset($biggopti->link) && !empty($biggopti->link)) : ?>
268 <div class="bdt-biggopti-btn">
269 <a href="<?php echo esc_url($biggopti->link); ?>" target="_blank">
270 <div class="nm-biggopti-btn">
271 <?php echo isset($biggopti->button_text) ? esc_html($biggopti->button_text) : 'Read More'; ?>
272 <span class="dashicons dashicons-arrow-right-alt"></span>
273 </div>
274 </a>
275 </div>
276 <?php endif; ?>
277 </div>
278 </div>
279 </div>
280 </div>
281 <?php
282 return ob_get_clean();
283 }
284
285 public static function add_biggopti($args = []) {
286 if (is_array($args)) {
287 self::$biggopties[] = $args;
288 }
289 }
290
291 /**
292 * AJAX: Build and return API biggopties HTML for dynamic injection
293 */
294 public function ajax_fetch_api_biggopties() {
295 $nonce = isset($_POST['_wpnonce']) ? sanitize_text_field(wp_unslash($_POST['_wpnonce'])) : '';
296 if (!wp_verify_nonce($nonce, 'ultimate-post-kit')) {
297 wp_send_json_error([ 'message' => 'invalid_nonce' ]);
298 }
299
300 if (!current_user_can('manage_options')) {
301 wp_send_json_error([ 'message' => 'forbidden' ]);
302 }
303
304 // Don't show biggopties on plugin/theme install and upload pages
305 $current_url = isset($_POST['current_url']) ? sanitize_text_field(wp_unslash($_POST['current_url'])) : '';
306
307 if (!empty($current_url)) {
308 $excluded_patterns = [
309 'plugin-install.php',
310 'theme-install.php',
311 'action=upload-plugin',
312 'action=upload-theme'
313 ];
314
315 foreach ($excluded_patterns as $pattern) {
316 if (strpos($current_url, $pattern) !== false) {
317 wp_send_json_success([ 'html' => '' ]);
318 }
319 }
320 }
321
322 $biggopties = $this->get_api_biggopties_data();
323 $grouped_biggopties = [];
324
325 if (is_array($biggopties)) {
326 foreach ($biggopties as $index => $biggopti) {
327 if ($this->should_show_biggopti($biggopti)) {
328 $display_id = isset($biggopti->display_id) ? $biggopti->display_id : 'default-' . $index;
329 if (!isset($grouped_biggopties[$display_id])) {
330 $grouped_biggopties[$display_id] = $biggopti;
331 }
332 }
333 }
334 }
335
336 // Build biggopties using the same pipeline as synchronous rendering
337 foreach ($grouped_biggopties as $display_id => $biggopti) {
338 $biggopti_id = isset($biggopti->id) ? $display_id : $biggopti->id;
339
340 self::add_biggopti([
341 'id' => 'api-biggopti-' . $biggopti_id,
342 'type' => isset($biggopti->type) ? $biggopti->type : 'info',
343 'category' => isset($biggopti->category) ? $biggopti->category : 'regular',
344 'dismissible' => true,
345 'html_message' => $this->render_api_biggopti($biggopti),
346 'dismissible-meta' => 'transient',
347 'dismissible-time' => isset($biggopti->end_date) ? max((new \DateTime($biggopti->end_date, new \DateTimeZone('UTC')))->getTimestamp() - time(), 0) : WEEK_IN_SECONDS,
348 ]);
349 }
350
351 ob_start();
352 $this->show_biggopties();
353 $markup = ob_get_clean();
354
355 wp_send_json_success([ 'html' => $markup ]);
356 }
357
358 /**
359 * Dismiss Biggopti.
360 */
361 public function dismiss() {
362 $nonce = (isset($_POST['_wpnonce'])) ? sanitize_text_field(wp_unslash($_POST['_wpnonce'])) : '';
363 $id = isset($_POST['id']) ? sanitize_text_field(wp_unslash($_POST['id'])) : '';
364 $time = isset($_POST['time']) ? absint(wp_unslash($_POST['time'])) : 0;
365 $meta = isset($_POST['meta']) ? sanitize_text_field(wp_unslash($_POST['meta'])) : '';
366
367 if ( ! wp_verify_nonce($nonce, 'ultimate-post-kit') ) {
368 wp_send_json_error();
369 }
370
371 if ( ! current_user_can('manage_options') ) {
372 wp_send_json_error();
373 }
374
375 /**
376 * Valid inputs?
377 */
378 if (!empty($id)) {
379 // Handle regular biggopties
380 if ('user' === $meta) {
381 update_user_meta(get_current_user_id(), $id, true);
382 } else {
383 set_transient($id, true, $time);
384
385 // Also store in options table for persistence
386 $dismissals_option = get_option('bdtupk_biggopti_dismissals', []);
387 $dismissals_option[$id] = [
388 'dismissed_at' => time(),
389 'expires_at' => time() + intval($time),
390 ];
391 update_option('bdtupk_biggopti_dismissals', $dismissals_option, false);
392 }
393
394 wp_send_json_success();
395 }
396
397 wp_send_json_error();
398 }
399
400 /**
401 * Biggopti Types
402 */
403 public function show_biggopties() {
404
405 $defaults = [
406 'id' => '',
407 'type' => 'info',
408 'category' => 'regular',
409 'show_if' => true,
410 'title' => '',
411 'message' => '',
412 'class' => 'ultimate-post-kit-biggopti',
413 'dismissible' => false,
414 'dismissible-meta' => 'transient',
415 'dismissible-time' => WEEK_IN_SECONDS,
416 'data' => '',
417 'action_link' => '',
418 ];
419
420 foreach (self::$biggopties as $key => $biggopti) {
421
422 $biggopti = wp_parse_args($biggopti, $defaults);
423
424 // Check if biggopti is for White Label
425 if (defined('BDTUPK_WL') && $biggopti['category'] === 'regular') {
426 continue;
427 }
428
429 $classes = ['biggopti'];
430
431 $classes[] = $biggopti['class'];
432 if (isset($biggopti['type'])) {
433 $classes[] = 'biggopti-' . $biggopti['type'];
434 }
435
436 // Is biggopti dismissible?
437 if (true === $biggopti['dismissible']) {
438 $classes[] = 'is-dismissible';
439
440 // Dismissable time.
441 $biggopti['data'] = ' dismissible-time=' . esc_attr($biggopti['dismissible-time']) . ' ';
442 }
443
444 // Biggopti ID.
445 $biggopti_id = 'bdt-admin-biggopti-' . $biggopti['id'];
446 $biggopti['id'] = $biggopti_id;
447 if (!isset($biggopti['id'])) {
448 $biggopti_id = 'bdt-admin-biggopti-' . $biggopti['id'];
449 $biggopti['id'] = $biggopti_id;
450 } else {
451 $biggopti_id = $biggopti['id'];
452 }
453
454 $biggopti['classes'] = implode(' ', $classes);
455
456 // User meta.
457 $biggopti['data'] .= ' dismissible-meta=' . esc_attr($biggopti['dismissible-meta']) . ' ';
458 if ('user' === $biggopti['dismissible-meta']) {
459 $expired = get_user_meta(get_current_user_id(), $biggopti_id, true);
460 } elseif ('transient' === $biggopti['dismissible-meta']) {
461 $expired = get_transient($biggopti_id);
462
463 // If transient not found, check options table for persistent dismissal
464 if (false === $expired || empty($expired)) {
465 $dismissals_option = get_option('bdtupk_biggopti_dismissals', []);
466 if (isset($dismissals_option[$biggopti_id])) {
467 $dismissal = $dismissals_option[$biggopti_id];
468 // Check if dismissal is still valid (not expired)
469 if (isset($dismissal['expires_at']) && time() < $dismissal['expires_at']) {
470 $expired = true;
471 } else {
472 // Clean up expired dismissal from options
473 unset($dismissals_option[$biggopti_id]);
474 update_option('bdtupk_biggopti_dismissals', $dismissals_option, false);
475 }
476 }
477 }
478 }
479
480 // Biggopties visible after transient expire.
481 if (isset($biggopti['show_if'])) {
482
483 if (true === $biggopti['show_if']) {
484
485 // Is transient expired?
486 if (false === $expired || empty($expired)) {
487 self::biggopti_layout($biggopti);
488 }
489 }
490 } else {
491
492 // No transient biggopties.
493 self::biggopti_layout($biggopti);
494 }
495 }
496 }
497
498 /**
499 * New Biggopti Layout
500 * @param array $biggopti Biggopti biggopti_layout.
501 * @return void
502 * @since 6.11.3
503 */
504
505 public static function biggopti_layout($biggopti = []) {
506
507 if( isset($biggopti['html_message']) && ! empty($biggopti['html_message']) ) {
508 self::new_biggopti_layout($biggopti);
509 return;
510 }
511
512 ?>
513 <div id="<?php echo esc_attr($biggopti['id']); ?>" class="<?php echo esc_attr($biggopti['classes']); ?>" <?php echo esc_attr($biggopti['data']); ?>>
514 <div class="bdt-biggopti-wrapper">
515 <div class="bdt-biggopti-icon-wrapper">
516 <img height="25" width="25" src="<?php echo esc_url (BDTUPK_ASSETS_URL ); ?>images/logo.svg">
517 </div>
518
519 <div class="bdt-biggopti-content">
520 <?php if (isset($biggopti['title']) && !empty($biggopti['title'])) : ?>
521 <h2 class="bdt-biggopti-title"><?php echo wp_kses_post($biggopti['title']); ?></h2>
522 <?php endif; ?>
523
524 <p class="bdt-biggopti-text"><?php echo wp_kses_post($biggopti['message']); ?></p>
525
526 <?php if (isset($biggopti['action_link']) && !empty($biggopti['action_link'])) : ?>
527 <div class="bdt-biggopti-btn">
528 <a href="#">Renew Now</a>
529 </div>
530 <?php endif; ?>
531 </div>
532 </div>
533 </div>
534 <?php
535 }
536
537 public static function new_biggopti_layout( $biggopti = [] ) {
538 ?>
539 <div id="<?php echo esc_attr( $biggopti['id'] ); ?>" class="<?php echo esc_attr( $biggopti['classes'] ); ?>" <?php echo esc_attr( $biggopti['data'] ); ?>>
540 <?php
541 echo wp_kses_post( $biggopti['html_message'] );
542 ?>
543 </div>
544
545 <?php
546 }
547 }
548
549 Biggopties::get_instance();