PluginProbe
Defender Security – Malware Scanner, Login Security & Firewall / 6.2.1
Defender Security – Malware Scanner, Login Security & Firewall v6.2.1
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 / class-local-config-store.php

class-local-config-store.php in Defender Security – Malware Scanner, Login Security & Firewall 6.2.1, at src/component/config/class-local-config-store.php

342 lines 8.2 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Local Config Store for Configs UI (Smush-style single option storage).
4 *
5 * @package WP_Defender\Component\Config
6 */
7
8 namespace WP_Defender\Component\Config;
9
10 use WP_Defender\Component\Backup_Settings;
11
12 /**
13 * Handles Configs persistence in a single option key.
14 */
15 class Local_Config_Store {
16
17 /**
18 * Local option key for all configs.
19 */
20 public const OPTION_KEY = 'wp-defender-preset_configs';
21
22 /**
23 * Backup settings service.
24 *
25 * @var Backup_Settings
26 */
27 private $service;
28
29 /**
30 * Constructor.
31 *
32 * @param Backup_Settings $service Backup settings service.
33 */
34 public function __construct( Backup_Settings $service ) {
35 $this->service = $service;
36 }
37
38 /**
39 * Gets all locally stored configs.
40 *
41 * @return array
42 */
43 public function get_all(): array {
44 $this->maybe_initialize_from_legacy();
45 $configs = get_site_option( self::OPTION_KEY, array() );
46
47 return is_array( $configs ) ? $configs : array();
48 }
49
50 /**
51 * Gets one config by key.
52 *
53 * @param string $key Config key.
54 *
55 * @return array|null
56 */
57 public function get_one( string $key ): ?array {
58 $configs = $this->get_all();
59 $key = trim( $key );
60
61 if ( '' === $key || ! isset( $configs[ $key ] ) || ! is_array( $configs[ $key ] ) ) {
62 return null;
63 }
64
65 return $configs[ $key ];
66 }
67
68 /**
69 * Persists full configs map.
70 *
71 * @param array $configs Configs map keyed by config key.
72 *
73 * @return void
74 */
75 public function save_all( array $configs ): void {
76 update_site_option( self::OPTION_KEY, $configs );
77 }
78
79 /**
80 * Creates a config from current Defender settings.
81 *
82 * @param string $name Config name.
83 * @param string $description Config description.
84 * @param string $note_added_time Note timestamp.
85 *
86 * @return array
87 */
88 public function create_from_current( string $name, string $description = '', string $note_added_time = '' ): array {
89 $configs = $this->get_all();
90 $key = $this->generate_key( 'wp_defender_config' );
91 $settings = $this->service->parse_data_for_import();
92
93 $data = array_merge(
94 array(
95 'key' => $key,
96 'name' => sanitize_text_field( $name ),
97 'description' => sanitize_textarea_field( $description ),
98 'note_added_time' => sanitize_text_field( $note_added_time ),
99 'immortal' => false,
100 'is_removable' => true,
101 'is_active' => false,
102 'date' => (string) time(),
103 ),
104 $settings
105 );
106
107 unset( $data['labels'] );
108
109 $configs[ $key ] = $data;
110 $this->save_all( $configs );
111
112 return $data;
113 }
114
115 /**
116 * Adds imported config.
117 *
118 * @param array $importer Imported config payload.
119 *
120 * @return array
121 */
122 public function add_imported( array $importer ): array {
123 $configs = $this->get_all();
124 $key = $this->generate_key( 'wp_defender_config_import' );
125
126 $data = array(
127 'key' => $key,
128 'name' => sanitize_text_field( (string) ( $importer['name'] ?? '' ) ),
129 'description' => isset( $importer['description'] ) ? sanitize_textarea_field( (string) $importer['description'] ) : '',
130 'note_added_time' => isset( $importer['note_added_time'] ) ? sanitize_text_field( (string) $importer['note_added_time'] ) : '',
131 'immortal' => false,
132 'is_removable' => true,
133 'is_active' => false,
134 'date' => (string) time(),
135 'configs' => $importer['configs'],
136 'strings' => $this->service->import_module_strings( $importer ),
137 );
138
139 $configs[ $key ] = $data;
140 $this->save_all( $configs );
141
142 return $data;
143 }
144
145 /**
146 * Updates config metadata.
147 *
148 * @param string $key Config key.
149 * @param string|null $name Name.
150 * @param string|null $description Description.
151 * @param string|null $note_added_time Note timestamp.
152 *
153 * @return bool
154 */
155 public function update_metadata( string $key, ?string $name, ?string $description, ?string $note_added_time ): bool {
156 $configs = $this->get_all();
157 if ( ! isset( $configs[ $key ] ) || ! is_array( $configs[ $key ] ) ) {
158 return false;
159 }
160
161 if ( null !== $name && '' !== trim( $name ) ) {
162 $configs[ $key ]['name'] = sanitize_text_field( $name );
163 }
164 if ( null !== $description ) {
165 $configs[ $key ]['description'] = sanitize_textarea_field( $description );
166 }
167 if ( null !== $note_added_time ) {
168 $configs[ $key ]['note_added_time'] = sanitize_text_field( $note_added_time );
169 }
170
171 $this->save_all( $configs );
172
173 return true;
174 }
175
176 /**
177 * Applies a config by key.
178 *
179 * @param string $key Config key.
180 *
181 * @return array|null
182 */
183 public function apply( string $key ): ?array {
184 $configs = $this->get_all();
185 if ( ! isset( $configs[ $key ] ) || ! is_array( $configs[ $key ] ) ) {
186 return null;
187 }
188
189 $config = $configs[ $key ];
190 if ( ! isset( $config['configs'] ) || ! is_array( $config['configs'] ) ) {
191 return null;
192 }
193
194 foreach ( $configs as $config_key => &$value ) {
195 if ( ! is_array( $value ) ) {
196 continue;
197 }
198 $value['is_active'] = ( $config_key === $key );
199 }
200 $this->save_all( $configs );
201
202 return $config;
203 }
204
205 /**
206 * Deletes one config by key.
207 *
208 * @param string $key Config key.
209 *
210 * @return bool
211 */
212 public function delete_one( string $key ): bool {
213 $configs = $this->get_all();
214 if ( ! isset( $configs[ $key ] ) || ! is_array( $configs[ $key ] ) ) {
215 return false;
216 }
217
218 $is_removable = isset( $configs[ $key ]['is_removable'] ) ? (bool) $configs[ $key ]['is_removable'] : true;
219 $is_immortal = isset( $configs[ $key ]['immortal'] ) ? (bool) $configs[ $key ]['immortal'] : false;
220 if ( ! $is_removable || $is_immortal ) {
221 return false;
222 }
223
224 unset( $configs[ $key ] );
225 $this->save_all( $configs );
226
227 return true;
228 }
229
230 /**
231 * Deletes all removable configs except keep keys.
232 *
233 * @param array $keep_keys Keys to preserve.
234 *
235 * @return void
236 */
237 public function sync_keep_list( array $keep_keys ): void {
238 $keep_keys = array_fill_keys( array_map( 'strval', $keep_keys ), true );
239 $configs = $this->get_all();
240
241 foreach ( $configs as $key => $config ) {
242 if ( isset( $keep_keys[ $key ] ) ) {
243 continue;
244 }
245
246 $is_removable = isset( $config['is_removable'] ) ? (bool) $config['is_removable'] : true;
247 $is_immortal = isset( $config['immortal'] ) ? (bool) $config['immortal'] : false;
248 if ( ! $is_removable || $is_immortal ) {
249 continue;
250 }
251
252 unset( $configs[ $key ] );
253 }
254
255 $this->save_all( $configs );
256 }
257
258 /**
259 * Gets configs for frontend list response.
260 *
261 * @return array
262 */
263 public function get_frontend_configs(): array {
264 $configs = $this->get_all();
265
266 foreach ( $configs as $key => &$config ) {
267 if ( ! is_array( $config ) ) {
268 continue;
269 }
270 $config['key'] = $key;
271 $config['strings'] = $this->service->import_module_strings( $config );
272 if ( isset( $config['configs'] ) ) {
273 unset( $config['configs'] );
274 }
275 }
276
277 return $configs;
278 }
279
280 /**
281 * Gets full config payload for download/apply.
282 *
283 * @param string $key Config key.
284 *
285 * @return array|null
286 */
287 public function get_full_for_key( string $key ): ?array {
288 $config = $this->get_one( $key );
289 if ( null === $config ) {
290 return null;
291 }
292
293 $sample = $this->service->gather_data();
294 foreach ( $sample as $slug => $data ) {
295 foreach ( $data as $setting_key => $val ) {
296 if ( ! isset( $config['configs'][ $slug ][ $setting_key ] ) ) {
297 $config['configs'][ $slug ][ $setting_key ] = null;
298 }
299 }
300 }
301
302 return $config;
303 }
304
305 /**
306 * Initializes local storage from legacy per-option configs if needed.
307 *
308 * @return void
309 */
310 private function maybe_initialize_from_legacy(): void {
311 $existing = get_site_option( self::OPTION_KEY, null );
312 if ( is_array( $existing ) ) {
313 return;
314 }
315
316 $legacy = $this->service->get_configs();
317 if ( array() === $legacy ) {
318 update_site_option( self::OPTION_KEY, array() );
319 return;
320 }
321
322 foreach ( $legacy as $key => &$config ) {
323 if ( ! is_array( $config ) ) {
324 continue;
325 }
326 $config['key'] = (string) $key;
327 }
328 update_site_option( self::OPTION_KEY, $legacy );
329 }
330
331 /**
332 * Generates a unique config key.
333 *
334 * @param string $prefix Prefix.
335 *
336 * @return string
337 */
338 private function generate_key( string $prefix ): string {
339 return $prefix . '_' . time() . '_' . wp_rand( 1000, 9999 );
340 }
341 }
342