PluginProbe ʕ •ᴥ•ʔ
WP STAGING – WordPress Backups, Restore, Migration & Clone / 4.11.0
WP STAGING – WordPress Backups, Restore, Migration & Clone v4.11.0
4.11.0 4.10.0 4.9.5 4.9.4 4.9.3 4.9.2 4.9.1 4.9.0 4.8.1 trunk 3.0.0 3.0.1 3.0.2 3.0.3 3.0.4 3.0.5 3.0.6 3.1.0 3.1.1 3.1.2 3.1.3 3.1.4 3.10.0 3.2.0 3.3.1 3.3.2 3.3.3 3.4.1 3.4.3 3.5.0 3.6.0 3.7.1 3.8.0 3.8.1 3.8.2 3.8.3 3.8.4 3.8.5 3.8.6 3.8.7 3.9.0 3.9.1 3.9.2 3.9.3 3.9.4 4.0.0 4.1.0 4.1.1 4.1.2 4.1.3 4.1.4 4.2.0 4.2.1 4.3.0 4.3.1 4.3.2 4.4.0 4.5.0 4.6.0 4.7.0 4.7.1 4.7.2 4.7.3 4.8.0
wp-staging / Framework / BackgroundProcessing / FeatureDetection.php
wp-staging / Framework / BackgroundProcessing Last commit date
Exceptions 1 day ago Job 1 day ago Action.php 1 day ago BackgroundProcessingServiceProvider.php 1 day ago Demo.php 1 day ago FeatureDetection.php 1 day ago Queue.php 1 day ago QueueActionAware.php 1 day ago QueueProcessor.php 1 day ago WithQueueAwareness.php 1 day ago
FeatureDetection.php
236 lines
1 <?php
2
3
4
5
6
7
8
9 namespace WPStaging\Framework\BackgroundProcessing;
10
11 use WP_Error;
12 use WPStaging\Framework\Adapter\WpAdapter;
13 use WPStaging\Framework\Network\HttpBasicAuth;
14 use WPStaging\Framework\Notices\Notices;
15
16 use function WPStaging\functions\debug_log;
17
18
19
20
21
22
23 class FeatureDetection
24 {
25 use HttpBasicAuth;
26
27
28 const ACTION_AJAX_TEST = 'wpstg_ajax_test_action';
29
30
31 const ACTION_AJAX_SUPPORT_FEATURE_DETECTION = 'wpstg_q_ajax_support_feature_detection';
32
33
34 const FILTER_HTTPS_LOCAL_SSL_VERIFY = 'https_local_ssl_verify';
35
36
37 const AJAX_OPTION_NAME = 'wpstg_q_feature_detection_ajax_available';
38
39
40 const AJAX_REQUEST_QUERY_VAR = 'wpstg_q_ajax_check';
41
42
43
44
45
46
47 protected $isAjaxAvailableCache;
48
49
50
51
52
53
54
55
56 public function isAjaxAvailable($showAdminNotice = true)
57 {
58
59 if ($this->isAjaxAvailableCache === null) {
60
61
62 $notRightContext = wp_installing() || (defined('REST_REQUEST') && REST_REQUEST) || (new WpAdapter())->doingAjax()
63 || wp_doing_cron() || !is_admin();
64
65 if ($notRightContext) {
66
67 debug_log(sprintf(
68 "isAjaxAvailable not right context: Is WP Installing? %s - Is Rest? %s - Is Ajax? %s - Is Cron? %s - Is admin? %s",
69 wp_installing() ? 'true' : 'false',
70 (defined('REST_REQUEST') && REST_REQUEST) ? 'true' : 'false',
71 (new WpAdapter())->doingAjax() ? 'true' : 'false',
72 wp_doing_cron() ? 'true' : 'false',
73 is_admin() ? 'true' : 'false'
74 ), 'info', false);
75 return true;
76 }
77
78 $availableOptionValue = get_option(self::AJAX_OPTION_NAME, null);
79
80 if (!in_array($availableOptionValue, ['y', 'n'], true)) {
81 $available = $this->runAjaxFeatureTest();
82 $availableOptionValue = $available ? 'y' : 'n';
83 update_option(self::AJAX_OPTION_NAME, $availableOptionValue, false);
84 }
85
86 $this->isAjaxAvailableCache = $availableOptionValue === 'y';
87 }
88
89 if (!$this->isAjaxAvailableCache && $showAdminNotice) {
90 add_action(Notices::ACTION_ADMIN_NOTICES, [$this, 'ajaxSupportMissingAdminNotice']);
91 }
92
93
94
95 return $this->isAjaxAvailableCache;
96 }
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116 public function runAjaxFeatureTest()
117 {
118
119 debug_log('Starting from a clean state...', 'info', false);
120 delete_option(self::AJAX_OPTION_NAME);
121
122 $ajaxUrl = add_query_arg([
123 'action' => self::ACTION_AJAX_TEST,
124 '_ajax_nonce' => wp_create_nonce(self::ACTION_AJAX_TEST),
125 ], admin_url('admin-ajax.php'));
126
127 $hash = md5(uniqid(__CLASS__, true));
128
129 debug_log('Sending request to: ' . $ajaxUrl, 'info', false);
130
131 $response = wp_remote_post(esc_url_raw($ajaxUrl), [
132 'headers' => array_merge(
133 ['X-WPSTG-Request' => self::ACTION_AJAX_TEST],
134 $this->getHttpAuthHeaders()
135 ),
136 'blocking' => false,
137 'timeout' => 0.01,
138 'cookies' => !empty($_COOKIE) ? $_COOKIE : [],
139 'sslverify' => apply_filters(self::FILTER_HTTPS_LOCAL_SSL_VERIFY, false),
140 'body' => [self::AJAX_OPTION_NAME => $hash],
141 ]);
142
143 debug_log(wp_json_encode($response), 'info', false);
144
145 if ($response instanceof WP_Error) {
146 return false;
147 }
148
149 $test = static function () {
150
151 global $wpdb;
152 $fetched = $wpdb->get_var(
153 $wpdb->prepare(
154 "SELECT `option_value` from `{$wpdb->options}` WHERE `option_name` = '%s' AND `option_value` = 'y'",
155 self::AJAX_OPTION_NAME
156 )
157 );
158
159 debug_log('Fetched is equal to: ' . $fetched, 'info', false);
160 debug_log('Fetched is equal to (get_option): ' . get_option(self::AJAX_OPTION_NAME), 'info', false);
161
162 return $fetched === 'y';
163 };
164
165 $waited = 0;
166 $waitStep = .5 * 1e6;
167 $timeout = 10 * 1e6;
168
169 do {
170 debug_log('runAjaxFeatureTest waited ' . number_format($waited / 1e6, 1) . ' seconds...', 'info', false);
171 $waited += $waitStep;
172 usleep((int)$waitStep);
173
174 if ($test()) {
175
176 debug_log('runAjaxFeatureTest worked', 'info', false);
177 return true;
178 }
179 } while ($waited <= $timeout);
180
181
182 debug_log('runAjaxFeatureTest did not work', 'info', false);
183 return false;
184 }
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199 public function updateAjaxTestOption()
200 {
201 debug_log('Running updateAjaxTestOption', 'info', false);
202 check_ajax_referer(self::ACTION_AJAX_TEST);
203
204 if (!update_option(self::AJAX_OPTION_NAME, 'y', false)) {
205 debug_log('updateAjaxTestOption update_option returned false', 'info', false);
206 }
207
208 debug_log('Complete updateAjaxTestOption. New value: ' . get_option(self::AJAX_OPTION_NAME), 'info', false);
209 }
210
211
212
213
214
215
216
217 public function ajaxSupportMissingAdminNotice()
218 {
219 $message = __(
220 'WP STAGING Background Processing system cannot use AJAX: this will prevent it from performing at its best.',
221 'wp-staging'
222 );
223 $checkLink = sprintf(
224 '<a href="%s">%s</a>',
225 esc_url(admin_url('/?' . self::AJAX_REQUEST_QUERY_VAR . '=1')),
226 __('Click here to check again now.', 'wp-staging')
227 );
228 ?>
229 <div class="notice notice-warning is-dismissible wpstg__notice wpstg__notice--warning">
230 <p><?php echo wp_kses_post($message); ?></p>
231 <p><?php echo wp_kses_post($checkLink); ?></p>
232 </div>
233 <?php
234 }
235 }
236