PluginProbe ʕ •ᴥ•ʔ
VikAppointments Services Booking Calendar / 1.2.21
VikAppointments Services Booking Calendar v1.2.21
1.2.21 1.2.20 trunk 1.2.17 1.2.18 1.2.19
vikappointments / libraries / adapter / session / handler.php
vikappointments / libraries / adapter / session Last commit date
handler.php 3 days ago session.php 3 days ago
handler.php
186 lines
1 <?php
2 /**
3 * @package VikWP - Libraries
4 * @subpackage adapter.session
5 * @author E4J s.r.l.
6 * @copyright Copyright (C) 2023 E4J s.r.l. All Rights Reserved.
7 * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL
8 * @link https://vikwp.com
9 */
10
11 // No direct access
12 defined('ABSPATH') or die('No script kiddies please!');
13
14 /**
15 * Class used to handle the PHP session.
16 * Provides the methods to begin a new session and to destroy it.
17 *
18 * @since 10.0
19 */
20 class JSessionHandler
21 {
22 /**
23 * Starts a new session, only if it doesn't already exist.
24 *
25 * @return void
26 */
27 public static function start()
28 {
29 /**
30 * Prevent the handler from starting a new session in case the process was launched
31 * from wp-cron.php, which manually sends some headers at the beginning of the file.
32 *
33 * @since 10.1.65
34 */
35 if (defined('DOING_CRON') && DOING_CRON)
36 {
37 return;
38 }
39
40 /**
41 * Do not go ahead in case the session has been already started, otherwise duplicate
42 * calls to this method risks to register the same hook more than once.
43 *
44 * @since 10.1.70
45 */
46 if (self::isStarted())
47 {
48 return;
49 }
50
51 /**
52 * In case the headers have been already sent, trigger warning and abort.
53 *
54 * @since 10.1.70
55 */
56 if (headers_sent())
57 {
58 trigger_error('Session cannot be started after headers have already been sent', E_USER_WARNING);
59 return;
60 }
61
62 session_start();
63
64 /**
65 * Filters whether to preempt an HTTP request's return value.
66 * It is needed to support concurrent cURL requests (see Site Health).
67 *
68 * Returning a non-false value from the filter will short-circuit the HTTP request and return
69 * early with that value. A filter should return either:
70 *
71 * - An array containing 'headers', 'body', 'response', 'cookies', and 'filename' elements
72 * - A WP_Error instance
73 * - boolean false (to avoid short-circuiting the response)
74 *
75 * Returning any other value may result in unexpected behaviour.
76 *
77 * @since 2.9.0
78 *
79 * @param false|array|WP_Error $preempt Whether to preempt an HTTP request's return value. Default false.
80 * @param array $r HTTP request arguments.
81 * @param string $url The request URL.
82 */
83 add_filter('pre_http_request', function($preempt, $r, $url)
84 {
85 $input = JFactory::getApplication()->input;
86
87 $httpUrl = new JUri($url);
88 $baseUrl = new JUri(site_url());
89
90 /**
91 * As WP Site Health suggests, an active session might close timeouts for loopback connection.
92 * For this reason, every time an HTTP request is made, we should try to detect whether the
93 * provided end-point has the same root of the current website, meaning that we are performing
94 * a self connection, probably through the REST API.
95 *
96 * @since 10.1.39
97 */
98 if (strpos($httpUrl->toString(['host', 'path']), $baseUrl->toString(['host', 'path'])) !== false)
99 {
100 // loopback detected, terminate the session before starting a request
101 session_write_close();
102 }
103
104 return $preempt;
105 }, 10, 3);
106
107 /**
108 * Suppress "session active" critical error when Site Health performs its tests.
109 *
110 * Even if the session is active on Site Health, the plugin always call the
111 * `session_write_close` method before making any HTTP requests.
112 *
113 * @since 5.5.0
114 */
115 add_action('init', function() {
116 global $pagenow;
117
118 // check if the current page is Site Health
119 if (preg_match("/^site-health/i", $pagenow))
120 {
121 // always write session to avoid receiving a critical issue
122 session_write_close();
123 }
124 });
125 }
126
127 /**
128 * Destroys the current active session, only if it already exists.
129 *
130 * @param boolean $restart True to immediately restart a new session.
131 *
132 * @return void
133 */
134 public static function destroy($restart = true)
135 {
136 if (!self::isStarted())
137 {
138 return;
139 }
140
141 session_destroy();
142
143 if ($restart)
144 {
145 self::start();
146 }
147 }
148
149 /**
150 * Checks if a session has been started.
151 *
152 * @return boolean True if active, otherwise false.
153 */
154 public static function isStarted()
155 {
156 /**
157 * Make sure the session status is currently active. This because,
158 * in case someone had manually closed the session, this method would
159 * have improperly returned true.
160 *
161 * @since 10.1.43
162 */
163 return session_status() === PHP_SESSION_ACTIVE && self::getId();
164 }
165
166 /**
167 * Returns the session ID, if any.
168 *
169 * @return string The unique session ID if active, otherwise an empty string.
170 */
171 public static function getId()
172 {
173 return session_id();
174 }
175
176 /**
177 * Returns the session name, if any.
178 *
179 * @return string The session name.
180 */
181 public static function getName()
182 {
183 return session_name();
184 }
185 }
186