| @@ -1,8 +1,12 @@ | ||
| 1 | 1 | <?php |
| 2 | 2 | |
| 3 | 3 | namespace UltimatePostKit; |
| 4 | 4 | |
| 5 | +if (!defined('ABSPATH')) { | |
| 6 | + exit; // Exit if accessed directly. | |
| 7 | +} | |
| 8 | + | |
| 5 | 9 | /** |
| 6 | 10 | * Biggopties class |
| 7 | 11 | */ |
| 8 | 12 | class Biggopties { |
| @@ -33,24 +37,15 @@ | ||
| 33 | 37 | * |
| 34 | 38 | * @return array|mixed |
| 35 | 39 | */ |
| 36 | 40 | private function get_api_biggopties_data() { |
| 37 | - | |
| 38 | - // 6-hour transient cache for API response | |
| 39 | - $transient_key = 'bdt_api_biggopties'; | |
| 40 | - $cached = get_transient($transient_key); | |
| 41 | - if ($cached !== false && is_array($cached)) { | |
| 42 | - return $cached; | |
| 43 | - } | |
| 44 | - | |
| 45 | 41 | // API endpoint for biggopties - you can change this to your actual endpoint |
| 46 | - $api_url = 'https://store.bdthemes.com/api/notices/api-data-records'; | |
| 42 | + $api_url = ''; | |
| 47 | 43 | |
| 48 | 44 | $response = wp_remote_get($api_url, [ |
| 49 | 45 | 'timeout' => 30, |
| 50 | 46 | 'headers' => [ |
| 51 | 47 | 'Accept' => 'application/json', |
| 52 | - 'X-ALLOW-KEY' => 'bdthemes', | |
| 53 | 48 | ], |
| 54 | 49 | ]); |
| 55 | 50 | |
| 56 | 51 | if (is_wp_error($response)) { |
| @@ -56,19 +51,15 @@ | ||
| 56 | 51 | if (is_wp_error($response)) { |
| 57 | 52 | return []; |
| 58 | 53 | } |
| 59 | 54 | |
| 60 | - $response_code = wp_remote_retrieve_response_code($response); | |
| 61 | - | |
| 62 | 55 | $response_body = wp_remote_retrieve_body($response); |
| 63 | 56 | |
| 64 | 57 | $biggopties = json_decode($response_body); |
| 65 | 58 | |
| 66 | - if( isset($biggopties->api) && isset($biggopties->api->{'ultimate-post-kit'}) ) { | |
| 67 | - $data = $biggopties->api->{'ultimate-post-kit'}; | |
| 59 | + if( isset($biggopties) && isset($biggopties->{'ultimate-post-kit'}) ) { | |
| 60 | + $data = $biggopties->{'ultimate-post-kit'}; | |
| 68 | 61 | if (is_array($data)) { |
| 69 | - $ttl = apply_filters('bdt_api_biggopties_cache_ttl', 6 * HOUR_IN_SECONDS); | |
| 70 | - set_transient($transient_key, $data, $ttl); | |
| 71 | 62 | return $data; |
| 72 | 63 | } |
| 73 | 64 | } |
| 74 | 65 | |
| @@ -151,9 +142,9 @@ | ||
| 151 | 142 | ? $biggopti->client_targets |
| 152 | 143 | : ['both']; |
| 153 | 144 | |
| 154 | 145 | // Determine if this is targeted at Pro users |
| 155 | - $pro_targeted = in_array('pro', $client_targets, true); | |
| 146 | + $pro_targeted = in_array('pro_targeted', $client_targets, true); | |
| 156 | 147 | |
| 157 | 148 | // Ensure client_targets is always an array |
| 158 | 149 | if (!is_array($client_targets)) { |
| 159 | 150 | $client_targets = [$client_targets]; |
| @@ -212,28 +203,23 @@ | ||
| 212 | 203 | */ |
| 213 | 204 | private function render_api_biggopti($biggopti) { |
| 214 | 205 | ob_start(); |
| 215 | 206 | |
| 216 | - // Add custom CSS if provided | |
| 217 | - if (isset($biggopti->custom_css) && !empty($biggopti->custom_css)) { | |
| 218 | - echo '<style>' . wp_kses_post($biggopti->custom_css) . '</style>'; | |
| 219 | - } | |
| 220 | - | |
| 221 | 207 | // Prepare background styles |
| 222 | 208 | $background_style = ''; |
| 223 | 209 | $wrapper_classes = 'bdt-biggopti-wrapper'; |
| 224 | 210 | |
| 225 | 211 | if (isset($biggopti->background_color) && !empty($biggopti->background_color)) { |
| 226 | - $background_style .= 'background-color: ' . esc_attr($biggopti->background_color) . ';'; | |
| 212 | + $background_style .= 'background-color: ' . $biggopti->background_color . ';'; | |
| 227 | 213 | } |
| 228 | - | |
| 214 | + | |
| 229 | 215 | if (isset($biggopti->image) && !empty($biggopti->image)) { |
| 230 | - $background_style .= 'background-image: url(' . esc_url($biggopti->image) . ');'; | |
| 216 | + $background_style .= 'background-image: url(' . esc_url_raw($biggopti->image) . ');'; | |
| 231 | 217 | $wrapper_classes .= ' has-background-image'; |
| 232 | 218 | } |
| 233 | - | |
| 219 | + | |
| 234 | 220 | ?> |
| 235 | - <div class="<?php echo esc_attr($wrapper_classes); ?>" <?php echo $background_style ? 'style="' . $background_style . '"' : ''; ?>> | |
| 221 | + <div class="<?php echo esc_attr($wrapper_classes); ?>" <?php echo $background_style ? 'style="' . esc_attr($background_style) . '"' : ''; ?>> | |
| 236 | 222 | |
| 237 | 223 | |
| 238 | 224 | <?php $title = (isset($biggopti->title) && !empty($biggopti->title)) ? $biggopti->title : ''; ?> |
| 239 | 225 | |
| @@ -305,9 +291,9 @@ | ||
| 305 | 291 | /** |
| 306 | 292 | * AJAX: Build and return API biggopties HTML for dynamic injection |
| 307 | 293 | */ |
| 308 | 294 | public function ajax_fetch_api_biggopties() { |
| 309 | - $nonce = isset($_POST['_wpnonce']) ? sanitize_text_field($_POST['_wpnonce']) : ''; | |
| 295 | + $nonce = isset($_POST['_wpnonce']) ? sanitize_text_field(wp_unslash($_POST['_wpnonce'])) : ''; | |
| 310 | 296 | if (!wp_verify_nonce($nonce, 'ultimate-post-kit')) { |
| 311 | 297 | wp_send_json_error([ 'message' => 'invalid_nonce' ]); |
| 312 | 298 | } |
| 313 | 299 | |
| @@ -314,8 +300,26 @@ | ||
| 314 | 300 | if (!current_user_can('manage_options')) { |
| 315 | 301 | wp_send_json_error([ 'message' => 'forbidden' ]); |
| 316 | 302 | } |
| 317 | 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 | + | |
| 318 | 322 | $biggopties = $this->get_api_biggopties_data(); |
| 319 | 323 | $grouped_biggopties = []; |
| 320 | 324 | |
| 321 | 325 | if (is_array($biggopties)) { |
| @@ -320,11 +324,11 @@ | ||
| 320 | 324 | |
| 321 | 325 | if (is_array($biggopties)) { |
| 322 | 326 | foreach ($biggopties as $index => $biggopti) { |
| 323 | 327 | if ($this->should_show_biggopti($biggopti)) { |
| 324 | - $notice_class = isset($biggopti->notice_class) ? $biggopti->notice_class : 'default-' . $index; | |
| 325 | - if (!isset($grouped_biggopties[$notice_class])) { | |
| 326 | - $grouped_biggopties[$notice_class] = $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; | |
| 327 | 331 | } |
| 328 | 332 | } |
| 329 | 333 | } |
| 330 | 334 | } |
| @@ -329,10 +333,10 @@ | ||
| 329 | 333 | } |
| 330 | 334 | } |
| 331 | 335 | |
| 332 | 336 | // Build biggopties using the same pipeline as synchronous rendering |
| 333 | - foreach ($grouped_biggopties as $notice_class => $biggopti) { | |
| 334 | - $biggopti_id = isset($biggopti->id) ? $notice_class : $biggopti->id; | |
| 337 | + foreach ($grouped_biggopties as $display_id => $biggopti) { | |
| 338 | + $biggopti_id = isset($biggopti->id) ? $display_id : $biggopti->id; | |
| 335 | 339 | |
| 336 | 340 | self::add_biggopti([ |
| 337 | 341 | 'id' => 'api-biggopti-' . $biggopti_id, |
| 338 | 342 | 'type' => isset($biggopti->type) ? $biggopti->type : 'info', |
| @@ -354,12 +358,12 @@ | ||
| 354 | 358 | /** |
| 355 | 359 | * Dismiss Biggopti. |
| 356 | 360 | */ |
| 357 | 361 | public function dismiss() { |
| 358 | - $nonce = (isset($_POST['_wpnonce'])) ? sanitize_text_field($_POST['_wpnonce']) : ''; | |
| 359 | - $id = (isset($_POST['id'])) ? esc_attr($_POST['id']) : ''; | |
| 360 | - $time = (isset($_POST['time'])) ? esc_attr($_POST['time']) : ''; | |
| 361 | - $meta = (isset($_POST['meta'])) ? esc_attr($_POST['meta']) : ''; | |
| 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'])) : ''; | |
| 362 | 366 | |
| 363 | 367 | if ( ! wp_verify_nonce($nonce, 'ultimate-post-kit') ) { |
| 364 | 368 | wp_send_json_error(); |
| 365 | 369 | } |
| @@ -376,8 +380,16 @@ | ||
| 376 | 380 | if ('user' === $meta) { |
| 377 | 381 | update_user_meta(get_current_user_id(), $id, true); |
| 378 | 382 | } else { |
| 379 | 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); | |
| 380 | 392 | } |
| 381 | 393 | |
| 382 | 394 | wp_send_json_success(); |
| 383 | 395 | } |
| @@ -446,8 +458,24 @@ | ||
| 446 | 458 | if ('user' === $biggopti['dismissible-meta']) { |
| 447 | 459 | $expired = get_user_meta(get_current_user_id(), $biggopti_id, true); |
| 448 | 460 | } elseif ('transient' === $biggopti['dismissible-meta']) { |
| 449 | 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 | + } | |
| 450 | 478 | } |
| 451 | 479 | |
| 452 | 480 | // Biggopties visible after transient expire. |
| 453 | 481 | if (isset($biggopti['show_if'])) { |