PluginProbe
Defender Security – Malware Scanner, Login Security & Firewall / 3.1.0
Defender Security – Malware Scanner, Login Security & Firewall v3.1.0
6.3.0 6.2.3 6.2.4 6.2.0 6.2.1 6.2.2 6.1.0 5.3.1 5.4.0 5.4.1 5.5.0 5.5.1 5.6.0 5.6.1 5.6.2 5.7.0 5.7.1 5.7.2 5.8.0 5.8.1 5.9.0 6.0.0 6.0.1 3.0.1 3.1.0 All 141 releases
defender-security / src / component / config / config-hub-helper.php

config-hub-helper.php in Defender Security – Malware Scanner, Login Security & Firewall 3.1.0, at src/component/config/config-hub-helper.php

509 lines 12.0 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace WP_Defender\Component\Config;
4
5 use WP_Defender\Component\Backup_Settings;
6 use WP_Defender\Behavior\WPMUDEV;
7
8 /**
9 * Hub_Helper class.
10 */
11 class Config_Hub_Helper {
12
13 public const CONFIGS_TRANSIENT_KEY = 'wpdefender_preset_configs';
14 public const CONFIGS_TRANSIENT_TIME_KEY = 'wpdefender_preset_configs_transient_time';
15 public const ACTIVE_FLAG_CLEAR_KEY = 'wpdefender_config_clear_active_tag';
16 public const CONFIGS_TRANSIENT_TIME = 600; // 600 = 10 minutes.
17
18 /**
19 * WPMU DEV Plugin ID.
20 */
21 public const WDP_ID = '1081723';
22
23 /**
24 * Service class.
25 *
26 * @var Backup_Settings
27 */
28 private $service;
29
30 /**
31 * Get configs from transient.
32 *
33 * @param Backup_Settings $service Config service.
34 *
35 * @return array
36 */
37 public static function get_configs( Backup_Settings $service ) {
38 $configs = get_site_transient( self::CONFIGS_TRANSIENT_KEY );
39
40 if ( false === $configs ) {
41 $_this = new self();
42 $_this->service = $service;
43 $configs = $_this->fetch_current_configs();
44
45 set_site_transient( self::CONFIGS_TRANSIENT_KEY, $configs, self::CONFIGS_TRANSIENT_TIME );
46 update_site_option( self::CONFIGS_TRANSIENT_TIME_KEY, time() );
47 }
48
49 return $configs;
50 }
51
52 /**
53 * Get our special WDP ID header line from the file.
54 *
55 * @return array Plugin details: name, id.
56 */
57 private function get_plugin_details() {
58 $wpmudev = new WPMUDEV();
59
60 return array(
61 'name' => 'Defender' . ( $wpmudev->is_pro() ? ' Pro' : '' ),
62 'id' => self::WDP_ID,
63 );
64 }
65
66 /**
67 * Fetch and prepare configs to store to transient.
68 *
69 * @return array
70 */
71 private function fetch_current_configs() {
72 $stored_configs = $this->service->get_configs();
73 $wpmudev = new WPMUDEV();
74 $def_details = $this->get_plugin_details();
75
76 // Check config has `hub_id`. If not then send request to HUB and set it.
77 $stored_configs = $this->check_and_save_configs_to_hub( $stored_configs, $def_details, $wpmudev );
78
79 if ( defined( WPMUDEV::class . '::API_PACKAGE_CONFIGS' ) ) {
80 // Fetch configs from API.
81 $response = $wpmudev->make_wpmu_request(
82 WPMUDEV::API_PACKAGE_CONFIGS,
83 array( 'package_id' => $def_details['id'] ),
84 array( 'method' => 'GET' )
85 );
86 } else {
87 $response = false;
88 }
89
90 $final_configs = array();
91
92 // Loop to set default config.
93 // Exclude default config from match with HUB config.
94 foreach ( $stored_configs as $sc_key => $sc_value ) {
95 if ( 0 === strpos( $sc_key, 'wp_defender_config_default' ) ) {
96 $final_configs[ $sc_key ] = $sc_value;
97 break;
98 }
99
100 // Sometimes key does not match for default config.
101 if ( isset( $sc_value['immortal'] ) && $sc_value['immortal'] ) {
102 $final_configs[ $sc_key ] = $sc_value;
103 break;
104 }
105 }
106
107 return $this->prepare_hub_configs_response( $response, $final_configs, $stored_configs );
108 }
109
110 /**
111 * Check configs are saved on hub. If not in hub then create it.
112 *
113 * @param array $stored_configs All configs from DB.
114 * @param array $def_details Defender plugin details.
115 * @param WPMUDEV $wpmudev Defender plugin details.
116 *
117 * @return array
118 */
119 private function check_and_save_configs_to_hub( $stored_configs, $def_details, $wpmudev ) {
120 foreach ( $stored_configs as $sc_key => &$sc_value ) {
121 // Check it is for default config.
122 if ( 0 === strpos( $sc_key, 'wp_defender_config_default' ) ) {
123 continue;
124 }
125
126 // Sometimes key does not match for default config.
127 if ( isset( $sc_value['immortal'] ) && $sc_value['immortal'] ) {
128 continue;
129 }
130
131 if ( isset( $sc_value['hub_id'] ) ) {
132 continue;
133 }
134
135 $hub_id = $this->insert_to_hub( $sc_value, $def_details, $wpmudev );
136
137 // If data is not inserted to HUB.
138 if ( ! $hub_id ) {
139 continue;
140 }
141
142 $sc_value['hub_id'] = $hub_id;
143
144 update_site_option( $sc_key, $sc_value );
145 }
146
147 return $stored_configs;
148 }
149
150 /**
151 * Insert new config to hub.
152 *
153 * @param array $sc_value Single config from DB.
154 * @param array $def_details Defender plugin details.
155 * @param WPMUDEV $wpmudev Defender plugin details.
156 *
157 * @return int ID from hub.
158 */
159 private function insert_to_hub( $sc_value, $def_details, $wpmudev ) {
160 if ( ! defined( WPMUDEV::class . '::API_PACKAGE_CONFIGS' ) ) {
161 return false;
162 }
163
164 if ( empty( $sc_value['configs'] ) ) {
165 return false;
166 }
167
168 if ( empty( $sc_value['labels'] ) ) {
169 $config_component = wd_di()->get( Backup_Settings::class );
170 $sc_value['labels'] = $config_component->prepare_config_labels( $sc_value['configs'] );
171 }
172
173 $data = array(
174 'name' => $sc_value['name'],
175 'description' => $sc_value['description'],
176 'package' => $def_details,
177 'config' => wp_json_encode(
178 array(
179 'strings' => $sc_value['strings'],
180 'configs' => $sc_value['configs'],
181 'labels' => $sc_value['labels'],
182 )
183 ),
184 );
185
186 $response = $wpmudev->make_wpmu_request(
187 WPMUDEV::API_PACKAGE_CONFIGS,
188 $data,
189 array( 'method' => 'POST' )
190 );
191
192 if ( is_wp_error( $response ) ) {
193 return false;
194 }
195
196 return $response['id'];
197 }
198
199 /**
200 * Add config to HUB.
201 *
202 * @param array $data Config data.
203 *
204 * @return int
205 */
206 public static function add_configs_to_hub( $data ) {
207 $_this = new self();
208 $wpmudev = new WPMUDEV();
209 $def_details = $_this->get_plugin_details();
210
211 delete_site_transient( self::CONFIGS_TRANSIENT_KEY );
212
213 return $_this->insert_to_hub( $data, $def_details, $wpmudev );
214 }
215
216 /**
217 * Delete config from HUB.
218 *
219 * @param int $hub_id ID of config from HUB.
220 *
221 * @return bool
222 */
223 public static function delete_configs_from_hub( $hub_id ) {
224 if ( ! defined( WPMUDEV::class . '::API_PACKAGE_CONFIGS' ) ) {
225 return false;
226 }
227
228 $wpmudev = new WPMUDEV();
229 $url = $wpmudev->get_endpoint( WPMUDEV::API_PACKAGE_CONFIGS );
230 $response = self::send_request(
231 $url . '/' . $hub_id,
232 array(),
233 $wpmudev->get_apikey(),
234 'DELETE'
235 );
236
237 if ( isset( $response['deleted'] ) && $response['deleted'] ) {
238 delete_site_transient( self::CONFIGS_TRANSIENT_KEY );
239
240 return true;
241 }
242
243 return false;
244 }
245
246 /**
247 * Update config on HUB.
248 *
249 * @param array $config Full config data.
250 *
251 * @return bool
252 */
253 public static function update_on_hub( $config ) {
254 if ( ! isset( $config['hub_id'] ) ) {
255 return false;
256 }
257
258 if ( ! defined( WPMUDEV::class . '::API_PACKAGE_CONFIGS' ) ) {
259 return false;
260 }
261
262 $wpmudev = new WPMUDEV();
263 $url = $wpmudev->get_endpoint( WPMUDEV::API_PACKAGE_CONFIGS );
264
265 $data = array(
266 'name' => $config['name'],
267 'description' => $config['description'],
268 );
269
270 $response = self::send_request(
271 $url . '/' . $config['hub_id'],
272 $data,
273 $wpmudev->get_apikey(),
274 'PUT'
275 );
276
277 if ( isset( $response['id'] ) && $response['id'] ) {
278 delete_site_transient( self::CONFIGS_TRANSIENT_KEY );
279
280 return true;
281 }
282
283 return false;
284 }
285
286 /**
287 * API request.
288 *
289 * @param string $url
290 * @param array $body
291 * @param mixed $api_key
292 * @param string $method
293 *
294 * @return bool|array
295 */
296 private static function send_request( $url, $body, $api_key, $method ) {
297 $request = wp_remote_request(
298 $url,
299 array(
300 'method' => $method,
301 'headers' => array(
302 'Authorization' => $api_key,
303 ),
304 'body' => $body,
305 )
306 );
307
308 if ( is_wp_error( $request ) ) {
309 return false;
310 }
311
312 return json_decode( $request['body'], true );
313 }
314
315 /**
316 * Delete transient for matching condition.
317 *
318 * @return void
319 */
320 public static function clear_config_transient() {
321 if ( ! isset( $_GET['page'], $_GET['view'], $_GET['transient'] ) ) {
322 return;
323 }
324
325 // If page is not config.
326 if ( ! ( 'wdf-setting' === $_GET['page'] && 'configs' === $_GET['view'] ) ) {
327 return;
328 }
329
330 if ( 'clear' === $_GET['transient'] ) {
331 delete_site_transient( self::CONFIGS_TRANSIENT_KEY );
332 }
333 }
334
335 /**
336 * Prepare configs getting from HUB.
337 *
338 * @param mixed $response
339 * @param array $final_configs
340 * @param array $stored_configs
341 *
342 * @return array
343 */
344 private function prepare_hub_configs_response( $response, $final_configs, $stored_configs ) {
345 if ( ! is_array( $response ) || is_wp_error( $response ) ) {
346 return $stored_configs;
347 }
348
349 // Store id of keys that need to delete. Because they are deleted on HUB.
350 $delete_hub_ids = array();
351 $once_delete_unset = array();
352
353 // Loop through all items found in the API.
354 foreach ( $response as $api_config ) {
355 $found = false;
356
357 // Find key and value from stored configs.
358 foreach ( $stored_configs as $sc_key => $sc_value ) {
359 if ( isset( $sc_value['hub_id'] ) ) {
360 // Once it is unset from the deleted array don't re-add it.
361 if ( ! isset( $once_delete_unset[ $sc_value['hub_id'] ] ) ) {
362 $delete_hub_ids[ $sc_value['hub_id'] ] = $sc_key;
363 }
364
365 if ( $sc_value['hub_id'] === $api_config['id'] ) {
366 $sc_value['name'] = $api_config['name'];
367 $sc_value['description'] = $api_config['description'];
368 $final_configs[ $sc_key ] = $sc_value;
369 $found = true;
370
371 unset( $delete_hub_ids[ $sc_value['hub_id'] ] );
372 $once_delete_unset[ $sc_value['hub_id'] ] = $sc_key;
373 break;
374 }
375 }
376 }
377
378 if ( $found ) {
379 continue;
380 }
381
382 // Need to prepare this data because these are coming from HUB.
383 $key = 'wp_defender_config_hub_' . $api_config['id'];
384
385 $final_configs[ $key ] = $this->format_hub_config_to_save( $api_config );
386 $this->service->index_key( $key );
387 }
388
389 $this->delete_hub_removed_configs( $delete_hub_ids );
390
391 return $final_configs;
392 }
393
394 /**
395 * Delete configs that are delete from HUB.
396 *
397 * @param array $delete_hub_ids
398 */
399 private function delete_hub_removed_configs( $delete_hub_ids ) {
400 foreach ( $delete_hub_ids as $key ) {
401 delete_site_option( $key );
402 $this->service->remove_index( $key );
403 }
404 }
405
406 /**
407 * Need to prepare this data because these are coming from HUB.
408 *
409 * @param array $api_config
410 *
411 * @return array
412 */
413 private function format_hub_config_to_save( $api_config ) {
414 $api_config_array = json_decode( $api_config['config'], true );
415
416 $api_config_array['hub_id'] = $api_config['id'];
417 $api_config_array['name'] = $api_config['name'];
418 $api_config_array['description'] = $api_config['description'];
419 $api_config_array['immortal'] = false;
420
421 unset( $api_config_array['labels'] );
422
423 return $api_config_array;
424 }
425
426 /**
427 * Delete config cache and create a new cache.
428 *
429 * @param Backup_Settings $service
430 *
431 * @return array
432 */
433 public static function get_fresh_frontend_configs( Backup_Settings $service ) {
434 delete_site_transient( self::CONFIGS_TRANSIENT_KEY );
435
436 $configs = self::get_configs( $service );
437
438 foreach ( $configs as &$config ) {
439 unset( $config['configs'] );
440 }
441
442 return $configs;
443 }
444
445 /**
446 * Set a flag to clear active tag.
447 */
448 public static function set_clear_active_flag() {
449 $value = get_site_option( self::ACTIVE_FLAG_CLEAR_KEY, 'cleared' );
450
451 if ( 'clear' !== $value ) {
452 update_site_option( self::ACTIVE_FLAG_CLEAR_KEY, 'clear' );
453 }
454 }
455
456 /**
457 * Check active flag need to remove or not.
458 *
459 * @return bool
460 */
461 public static function check_remove_active_flag() {
462 $value = get_site_option( self::ACTIVE_FLAG_CLEAR_KEY, 'cleared' );
463
464 if ( 'clear' === $value ) {
465 update_site_option( self::ACTIVE_FLAG_CLEAR_KEY, 'cleared' );
466
467 return true;
468 }
469
470 return false;
471 }
472
473 /**
474 * Active a config from.
475 *
476 * @param $hub_id
477 *
478 * @throws \DI\DependencyException
479 * @throws \DI\NotFoundException
480 */
481 public static function active_config_from_hub_id( $hub_id ) {
482 $config_component = wd_di()->get( Backup_Settings::class );
483 $configs = $config_component->get_configs();
484
485 foreach ( $configs as $key => $config ) {
486 $need_update = false;
487
488 // Remove previous active status.
489 if ( $config['is_active'] ) {
490 $config['is_active'] = false;
491 $need_update = true;
492 }
493
494 // Add current active status.
495 if ( (int) $config['hub_id'] === (int) $hub_id ) {
496 $config['is_active'] = true;
497 $need_update = true;
498 }
499
500 if ( $need_update ) {
501 update_site_option( $key, $config );
502 }
503 }
504
505 // Clear cache to reflect in frontend.
506 delete_site_transient( self::CONFIGS_TRANSIENT_KEY );
507 }
508 }
509