PluginProbe
King Addons for Elementor – 100+ Elementor Widgets, 4 000+ Elementor Templates, WooCommerce Builder, Mega Menu, Popup Builder / 51.1.87
King Addons for Elementor – 100+ Elementor Widgets, 4 000+ Elementor Templates, WooCommerce Builder, Mega Menu, Popup Builder v51.1.87
51.1.87 51.1.86 51.1.84 51.1.85 51.1.83 51.1.82 51.1.81 51.1.79 51.1.78 51.1.77 51.1.76 51.1.74 51.1.75 51.1.65 51.1.64 51.1.63 trunk 51.1.14 51.1.2 51.1.35 51.1.36 51.1.37 51.1.38 51.1.39 51.1.44 All 41 releases
king-addons / includes / wishlist / Wishlist_Session.php

Wishlist_Session.php in King Addons for Elementor – 100+ Elementor Widgets, 4 000+ Elementor Templates, WooCommerce Builder, Mega Menu, Popup Builder 51.1.87, at includes/wishlist/Wishlist_Session.php

134 lines 3.2 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace King_Addons\Wishlist;
4
5 if (!defined('ABSPATH')) {
6 exit;
7 }
8
9 /**
10 * Manages wishlist session keys for guests and logged-in users.
11 */
12 class Wishlist_Session
13 {
14 private const COOKIE_NAME = 'ka_wishlist_session';
15 private const COOKIE_TTL_SECONDS = 2592000; // 30 days
16
17 /**
18 * Cookie name used for guest wishlist identity.
19 *
20 * @return string Cookie name.
21 */
22 public static function cookie_name(): string
23 {
24 return self::COOKIE_NAME;
25 }
26
27 /**
28 * Read the existing session cookie without creating one.
29 *
30 * @return string Session key or empty string.
31 */
32 public function get_existing_key(): string
33 {
34 if (empty($_COOKIE[self::COOKIE_NAME])) {
35 return '';
36 }
37
38 return sanitize_text_field(wp_unslash($_COOKIE[self::COOKIE_NAME]));
39 }
40
41 /**
42 * Get a session key tied to a browser.
43 *
44 * Pass $create = true only when a guest actually needs a persistent
45 * wishlist (add/toggle). Reading a page must not Set-Cookie, or public
46 * caches such as LiteSpeed cannot store the homepage for first visitors.
47 *
48 * @param bool $create Whether to mint and persist a cookie if none exists.
49 * @return string Session key, or empty string when none exists and $create is false.
50 */
51 public function get_session_key(bool $create = false): string
52 {
53 $existing = $this->get_existing_key();
54 if ($existing !== '') {
55 return $existing;
56 }
57
58 if (!$create) {
59 return '';
60 }
61
62 $session_key = wp_generate_uuid4();
63 $this->persist_cookie($session_key);
64
65 return $session_key;
66 }
67
68 /**
69 * Persist the wishlist session cookie.
70 *
71 * @param string $session_key Session key to store.
72 * @return void
73 */
74 public function persist_cookie(string $session_key): void
75 {
76 if ($session_key === '' || headers_sent()) {
77 return;
78 }
79
80 setcookie(
81 self::COOKIE_NAME,
82 $session_key,
83 $this->cookie_options(time() + self::COOKIE_TTL_SECONDS)
84 );
85 $_COOKIE[self::COOKIE_NAME] = $session_key;
86 }
87
88 /**
89 * Clear the wishlist session cookie.
90 *
91 * @return void
92 */
93 public function clear(): void
94 {
95 self::expire_if_present();
96 }
97
98 /**
99 * Drop a leftover guest cookie without minting a new one.
100 *
101 * @return void
102 */
103 public static function expire_if_present(): void
104 {
105 if (empty($_COOKIE[self::COOKIE_NAME]) || headers_sent()) {
106 return;
107 }
108
109 setcookie(
110 self::COOKIE_NAME,
111 '',
112 (new self())->cookie_options(time() - YEAR_IN_SECONDS)
113 );
114 unset($_COOKIE[self::COOKIE_NAME]);
115 }
116
117 /**
118 * Shared cookie flags for set and expire.
119 *
120 * @param int $expires Unix expiry timestamp.
121 * @return array<string, mixed> setcookie options.
122 */
123 private function cookie_options(int $expires): array
124 {
125 return [
126 'expires' => $expires,
127 'path' => COOKIEPATH ? COOKIEPATH : '/',
128 'secure' => is_ssl(),
129 'httponly' => true,
130 'samesite' => 'Lax',
131 ];
132 }
133 }
134