← All changes
|
includes/extensions/Site_Preloader/Site_Preloader.php
+108
-19
51.1.44
→
51.1.86
View file →
| @@ -168,8 +168,17 @@ | ||
| 168 | 168 | // Color picker |
| 169 | 169 | wp_enqueue_style('wp-color-picker'); |
| 170 | 170 | wp_enqueue_script('wp-color-picker'); |
| 171 | 171 | |
| 172 | + // Alpha-enabled WP Color Picker (same library used in Settings -> Lightbox Colors) | |
| 173 | + wp_enqueue_script( | |
| 174 | + 'king-addons-wpcolorpicker-alpha', | |
| 175 | + KING_ADDONS_URL . 'includes/assets/libraries/wpcolorpicker/wpcolorpicker.js', | |
| 176 | + ['wp-color-picker'], | |
| 177 | + KING_ADDONS_VERSION, | |
| 178 | + true | |
| 179 | + ); | |
| 180 | + | |
| 172 | 181 | // Media uploader |
| 173 | 182 | wp_enqueue_media(); |
| 174 | 183 | |
| 175 | 184 | // Admin JS |
| @@ -175,9 +184,9 @@ | ||
| 175 | 184 | // Admin JS |
| 176 | 185 | wp_enqueue_script( |
| 177 | 186 | 'king-addons-site-preloader-admin', |
| 178 | 187 | KING_ADDONS_URL . 'includes/extensions/Site_Preloader/assets/admin.js', |
| 179 | - ['jquery', 'wp-color-picker'], | |
| 188 | + ['jquery', 'wp-color-picker', 'king-addons-wpcolorpicker-alpha'], | |
| 180 | 189 | KING_ADDONS_VERSION, |
| 181 | 190 | true |
| 182 | 191 | ); |
| 183 | 192 | |
| @@ -453,10 +462,10 @@ | ||
| 453 | 462 | 'pages' => $pages, |
| 454 | 463 | 'priority' => isset($_POST['priority']) ? absint($_POST['priority']) : 10, |
| 455 | 464 | 'template' => isset($_POST['template']) ? sanitize_key($_POST['template']) : '', |
| 456 | 465 | 'override_colors' => isset($_POST['override_colors']) && $_POST['override_colors'] === '1', |
| 457 | - 'bg_color' => isset($_POST['bg_color']) ? sanitize_hex_color($_POST['bg_color']) : '#ffffff', | |
| 458 | - 'accent_color' => isset($_POST['accent_color']) ? sanitize_hex_color($_POST['accent_color']) : '#0071e3', | |
| 466 | + 'bg_color' => $this->sanitize_color_value($_POST['bg_color'] ?? '', '#ffffff'), | |
| 467 | + 'accent_color' => $this->sanitize_color_value($_POST['accent_color'] ?? '', '#0071e3'), | |
| 459 | 468 | ]; |
| 460 | 469 | |
| 461 | 470 | if (!$is_new_rule) { |
| 462 | 471 | // Update existing rule |
| @@ -547,10 +556,15 @@ | ||
| 547 | 556 | } |
| 548 | 557 | |
| 549 | 558 | $preset_id = $settings['template'] ?? 'spinner-circle'; |
| 550 | 559 | |
| 560 | + $trigger_type = $settings['trigger_type'] ?? 'always'; | |
| 561 | + $cookie_name = self::COOKIE_NAME . '_' . sanitize_key($trigger_type); | |
| 562 | + | |
| 551 | 563 | $data_attrs = [ |
| 552 | 564 | 'data-preset' => $preset_id, |
| 565 | + 'data-trigger-type' => $trigger_type, | |
| 566 | + 'data-cookie-name' => $cookie_name, | |
| 553 | 567 | 'data-hide-strategy' => $settings['hide_strategy'] ?? 'window_load', |
| 554 | 568 | 'data-min-display-time' => absint($settings['min_display_time'] ?? 500), |
| 555 | 569 | 'data-max-display-time' => absint($settings['max_display_time'] ?? 5000), |
| 556 | 570 | 'data-hide-animation' => $settings['hide_animation'] ?? 'fade', |
| @@ -740,9 +754,17 @@ | ||
| 740 | 754 | |
| 741 | 755 | case 'fade-text': |
| 742 | 756 | echo '<div class="kng-preloader-fade-text">'; |
| 743 | 757 | $loading_text = !empty($text_content) ? $text_content : __('Loading', 'king-addons'); |
| 744 | - foreach (str_split($loading_text) as $index => $char) { | |
| 758 | + if (function_exists('mb_str_split')) { | |
| 759 | + $chars = mb_str_split($loading_text); | |
| 760 | + } else { | |
| 761 | + $chars = preg_split('//u', $loading_text, -1, PREG_SPLIT_NO_EMPTY); | |
| 762 | + } | |
| 763 | + if (!is_array($chars)) { | |
| 764 | + $chars = str_split($loading_text); | |
| 765 | + } | |
| 766 | + foreach ($chars as $index => $char) { | |
| 745 | 767 | echo '<span style="animation-delay: ' . (0.1 * $index) . 's">' . esc_html($char) . '</span>'; |
| 746 | 768 | } |
| 747 | 769 | echo '</div>'; |
| 748 | 770 | break; |
| @@ -797,9 +819,9 @@ | ||
| 797 | 819 | $css = ''; |
| 798 | 820 | |
| 799 | 821 | // Background |
| 800 | 822 | $bg_type = $settings['bg_type'] ?? 'solid'; |
| 801 | - $bg_color = $settings['bg_color'] ?? '#ffffff'; | |
| 823 | + $bg_color = $settings['bg_color'] ?? 'rgba(0,0,0,0)'; | |
| 802 | 824 | $bg_gradient_start = $settings['bg_gradient_start'] ?? '#ffffff'; |
| 803 | 825 | $bg_gradient_end = $settings['bg_gradient_end'] ?? '#f5f5f7'; |
| 804 | 826 | $bg_image = $settings['bg_image'] ?? ''; |
| 805 | 827 | $overlay_opacity = isset($settings['overlay_opacity']) ? floatval($settings['overlay_opacity']) : 1; |
| @@ -916,24 +938,24 @@ | ||
| 916 | 938 | if (defined('REST_REQUEST') && REST_REQUEST) { |
| 917 | 939 | return false; |
| 918 | 940 | } |
| 919 | 941 | |
| 920 | - // Check trigger type | |
| 942 | + // Check trigger type (cookie-based; avoids PHP session dependency) | |
| 921 | 943 | $trigger_type = $settings['trigger_type'] ?? 'always'; |
| 922 | - | |
| 944 | + $cookie_name = self::COOKIE_NAME . '_' . sanitize_key($trigger_type); | |
| 945 | + | |
| 923 | 946 | if ($trigger_type === 'first_visit') { |
| 924 | - if (isset($_COOKIE[self::COOKIE_NAME])) { | |
| 947 | + if (isset($_COOKIE[$cookie_name])) { | |
| 925 | 948 | return false; |
| 926 | 949 | } |
| 927 | 950 | } elseif ($trigger_type === 'once_per_session') { |
| 928 | - if (session_status() === PHP_SESSION_NONE) { | |
| 929 | - @session_start(); | |
| 930 | - } | |
| 931 | - if (isset($_SESSION[self::SESSION_KEY])) { | |
| 951 | + // Session cookie is handled on the frontend; we only need to check presence. | |
| 952 | + if (isset($_COOKIE[$cookie_name])) { | |
| 932 | 953 | return false; |
| 933 | 954 | } |
| 934 | 955 | } elseif ($trigger_type === 'once_per_day') { |
| 935 | - $cookie_time = isset($_COOKIE[self::COOKIE_NAME]) ? intval($_COOKIE[self::COOKIE_NAME]) : 0; | |
| 956 | + // Cookie value must be a unix timestamp (seconds). | |
| 957 | + $cookie_time = isset($_COOKIE[$cookie_name]) ? intval($_COOKIE[$cookie_name]) : 0; | |
| 936 | 958 | if ($cookie_time && (time() - $cookie_time) < DAY_IN_SECONDS) { |
| 937 | 959 | return false; |
| 938 | 960 | } |
| 939 | 961 | } |
| @@ -1172,9 +1194,9 @@ | ||
| 1172 | 1194 | 'device_mobile' => true, |
| 1173 | 1195 | |
| 1174 | 1196 | // Appearance - Background |
| 1175 | 1197 | 'bg_type' => 'solid', |
| 1176 | - 'bg_color' => '#ffffff', | |
| 1198 | + 'bg_color' => 'rgba(0,0,0,0)', | |
| 1177 | 1199 | 'bg_gradient_start' => '#ffffff', |
| 1178 | 1200 | 'bg_gradient_end' => '#f5f5f7', |
| 1179 | 1201 | 'bg_image' => '', |
| 1180 | 1202 | 'overlay_opacity' => 1, |
| @@ -1263,11 +1285,11 @@ | ||
| 1263 | 1285 | $sanitized['device_mobile'] = !empty($input['device_mobile']); |
| 1264 | 1286 | |
| 1265 | 1287 | // Background |
| 1266 | 1288 | $sanitized['bg_type'] = isset($input['bg_type']) ? sanitize_key($input['bg_type']) : 'solid'; |
| 1267 | - $sanitized['bg_color'] = isset($input['bg_color']) ? sanitize_hex_color($input['bg_color']) : '#ffffff'; | |
| 1268 | - $sanitized['bg_gradient_start'] = isset($input['bg_gradient_start']) ? sanitize_hex_color($input['bg_gradient_start']) : '#ffffff'; | |
| 1269 | - $sanitized['bg_gradient_end'] = isset($input['bg_gradient_end']) ? sanitize_hex_color($input['bg_gradient_end']) : '#f5f5f7'; | |
| 1289 | + $sanitized['bg_color'] = $this->sanitize_color_value($input['bg_color'] ?? '', 'rgba(0,0,0,0)'); | |
| 1290 | + $sanitized['bg_gradient_start'] = $this->sanitize_color_value($input['bg_gradient_start'] ?? '', '#ffffff'); | |
| 1291 | + $sanitized['bg_gradient_end'] = $this->sanitize_color_value($input['bg_gradient_end'] ?? '', '#f5f5f7'); | |
| 1270 | 1292 | $sanitized['bg_image'] = isset($input['bg_image']) ? esc_url_raw($input['bg_image']) : ''; |
| 1271 | 1293 | $sanitized['overlay_opacity'] = isset($input['overlay_opacity']) ? max(0, min(1, floatval($input['overlay_opacity']))) : 1; |
| 1272 | 1294 | |
| 1273 | 1295 | // Logo |
| @@ -1279,12 +1301,12 @@ | ||
| 1279 | 1301 | $sanitized['text_enabled'] = !empty($input['text_enabled']); |
| 1280 | 1302 | $sanitized['text_content'] = isset($input['text_content']) ? sanitize_text_field($input['text_content']) : ''; |
| 1281 | 1303 | $sanitized['text_size'] = isset($input['text_size']) ? absint($input['text_size']) : 16; |
| 1282 | 1304 | $sanitized['text_weight'] = isset($input['text_weight']) ? sanitize_key($input['text_weight']) : '400'; |
| 1283 | - $sanitized['text_color'] = isset($input['text_color']) ? sanitize_hex_color($input['text_color']) : '#1d1d1f'; | |
| 1305 | + $sanitized['text_color'] = $this->sanitize_color_value($input['text_color'] ?? '', '#1d1d1f'); | |
| 1284 | 1306 | |
| 1285 | 1307 | // Animation |
| 1286 | - $sanitized['accent_color'] = isset($input['accent_color']) ? sanitize_hex_color($input['accent_color']) : '#0071e3'; | |
| 1308 | + $sanitized['accent_color'] = $this->sanitize_color_value($input['accent_color'] ?? '', '#0071e3'); | |
| 1287 | 1309 | $sanitized['spinner_size'] = isset($input['spinner_size']) ? absint($input['spinner_size']) : 48; |
| 1288 | 1310 | |
| 1289 | 1311 | // Behavior |
| 1290 | 1312 | $sanitized['trigger_type'] = isset($input['trigger_type']) ? sanitize_key($input['trigger_type']) : 'always'; |
| @@ -1309,8 +1331,75 @@ | ||
| 1309 | 1331 | $sanitized['custom_css'] = wp_strip_all_tags($input['custom_css']); |
| 1310 | 1332 | } |
| 1311 | 1333 | |
| 1312 | 1334 | return $sanitized; |
| 1335 | + } | |
| 1336 | + | |
| 1337 | + /** | |
| 1338 | + * Sanitize a CSS color value coming from admin inputs. | |
| 1339 | + * Allows hex, 8-digit hex, rgb/rgba, and 'transparent'. | |
| 1340 | + * | |
| 1341 | + * @param mixed $value | |
| 1342 | + * @param string $fallback | |
| 1343 | + * @return string | |
| 1344 | + */ | |
| 1345 | + private function sanitize_color_value($value, string $fallback): string | |
| 1346 | + { | |
| 1347 | + if (!is_string($value)) { | |
| 1348 | + return $fallback; | |
| 1349 | + } | |
| 1350 | + | |
| 1351 | + $value = trim($value); | |
| 1352 | + if ($value === '') { | |
| 1353 | + return $fallback; | |
| 1354 | + } | |
| 1355 | + | |
| 1356 | + if (strcasecmp($value, 'transparent') === 0) { | |
| 1357 | + return 'transparent'; | |
| 1358 | + } | |
| 1359 | + | |
| 1360 | + $hex = sanitize_hex_color($value); | |
| 1361 | + if (!empty($hex)) { | |
| 1362 | + return $hex; | |
| 1363 | + } | |
| 1364 | + | |
| 1365 | + if (preg_match('/^#([0-9a-fA-F]{8})$/', $value, $m)) { | |
| 1366 | + return '#' . strtolower($m[1]); | |
| 1367 | + } | |
| 1368 | + | |
| 1369 | + if (preg_match('/^rgba?\((.+)\)$/i', $value, $m)) { | |
| 1370 | + $parts = array_map('trim', explode(',', $m[1])); | |
| 1371 | + if (count($parts) < 3 || count($parts) > 4) { | |
| 1372 | + return $fallback; | |
| 1373 | + } | |
| 1374 | + | |
| 1375 | + $r = is_numeric($parts[0]) ? (int) $parts[0] : -1; | |
| 1376 | + $g = is_numeric($parts[1]) ? (int) $parts[1] : -1; | |
| 1377 | + $b = is_numeric($parts[2]) ? (int) $parts[2] : -1; | |
| 1378 | + if ($r < 0 || $r > 255 || $g < 0 || $g > 255 || $b < 0 || $b > 255) { | |
| 1379 | + return $fallback; | |
| 1380 | + } | |
| 1381 | + | |
| 1382 | + if (count($parts) === 3) { | |
| 1383 | + return 'rgb(' . $r . ',' . $g . ',' . $b . ')'; | |
| 1384 | + } | |
| 1385 | + | |
| 1386 | + $aRaw = $parts[3]; | |
| 1387 | + if (!is_numeric($aRaw)) { | |
| 1388 | + return $fallback; | |
| 1389 | + } | |
| 1390 | + $a = (float) $aRaw; | |
| 1391 | + if ($a < 0) { | |
| 1392 | + $a = 0; | |
| 1393 | + } elseif ($a > 1) { | |
| 1394 | + $a = 1; | |
| 1395 | + } | |
| 1396 | + | |
| 1397 | + $aStr = rtrim(rtrim(sprintf('%.3F', $a), '0'), '.'); | |
| 1398 | + return 'rgba(' . $r . ',' . $g . ',' . $b . ',' . $aStr . ')'; | |
| 1399 | + } | |
| 1400 | + | |
| 1401 | + return $fallback; | |
| 1313 | 1402 | } |
| 1314 | 1403 | |
| 1315 | 1404 | /** |
| 1316 | 1405 | * Checks if Pro version is active. |