This project does not seem to handle request data directly as such no vulnerable execution paths were found.
include
, or for example
via PHP's auto-loading mechanism.
These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
1 | <?php |
||
2 | /** |
||
3 | * Plugin Options. |
||
4 | * |
||
5 | * @package WP_To_Diaspora\Options |
||
6 | * @since 1.3.0 |
||
7 | */ |
||
8 | |||
9 | // Exit if accessed directly. |
||
10 | defined( 'ABSPATH' ) || exit; |
||
11 | |||
12 | /** |
||
13 | * Class to manage the settings using the Settings API. |
||
14 | */ |
||
15 | class WP2D_Options { |
||
16 | |||
17 | /** |
||
18 | * Only instance of this class. |
||
19 | * |
||
20 | * @var WP2D_Options |
||
21 | */ |
||
22 | private static $instance; |
||
23 | |||
24 | /** |
||
25 | * All default plugin options. |
||
26 | * |
||
27 | * @var array |
||
28 | */ |
||
29 | private static $default_options = [ |
||
30 | 'aspects_list' => [], |
||
31 | 'services_list' => [], |
||
32 | 'post_to_diaspora' => true, |
||
33 | 'enabled_post_types' => [ 'post' ], |
||
34 | 'fullentrylink' => true, |
||
35 | 'display' => 'full', |
||
36 | 'tags_to_post' => [ 'global', 'custom', 'post' ], |
||
37 | 'global_tags' => '', |
||
38 | 'aspects' => [ 'public' ], |
||
39 | 'services' => [], |
||
40 | 'auth_key_hash' => '', |
||
41 | 'version' => WP2D_VERSION, |
||
42 | ]; |
||
43 | |||
44 | /** |
||
45 | * Valid values for select fields. |
||
46 | * |
||
47 | * @var array |
||
48 | */ |
||
49 | private static $valid_values = [ |
||
50 | 'display' => [ 'full', 'excerpt', 'none' ], |
||
51 | 'tags_to_post' => [ 'global', 'custom', 'post' ], |
||
52 | ]; |
||
53 | |||
54 | /** |
||
55 | * All plugin options. |
||
56 | * |
||
57 | * @var array |
||
58 | */ |
||
59 | private static $options; |
||
60 | |||
61 | /** Singleton, keep private. */ |
||
62 | final private function __clone() { |
||
63 | } |
||
64 | |||
65 | /** Singleton, keep private. */ |
||
66 | final private function __construct() { |
||
67 | } |
||
68 | |||
69 | /** |
||
70 | * Create / Get the instance of this class. |
||
71 | * |
||
72 | * @return WP2D_Options Instance of this class. |
||
73 | */ |
||
74 | public static function instance() { |
||
75 | if ( null === self::$instance ) { |
||
76 | self::$instance = new self(); |
||
77 | self::$instance->setup(); |
||
78 | } |
||
79 | |||
80 | return self::$instance; |
||
81 | } |
||
82 | |||
83 | /** |
||
84 | * Set up the options menu. |
||
85 | */ |
||
86 | private function setup() { |
||
87 | |||
88 | // Populate options array. |
||
89 | $this->get_option(); |
||
90 | |||
91 | // Setup Options page and Contextual Help. |
||
92 | add_action( 'admin_menu', [ $this, 'setup_wpadmin_pages' ] ); |
||
93 | |||
94 | // Register all settings. |
||
95 | add_action( 'admin_init', [ $this, 'register_settings' ] ); |
||
96 | } |
||
97 | |||
98 | |||
99 | /** |
||
100 | * Get the currently selected tab. |
||
101 | * |
||
102 | * @todo Multi-level if statement to make it look prettier. |
||
103 | * |
||
104 | * @param string $default Tab to select if the current selection is invalid. |
||
105 | * |
||
106 | * @return string Return the currently selected tab. |
||
107 | */ |
||
108 | private function current_tab( $default = 'defaults' ) { |
||
109 | $tab = sanitize_key( $_GET['tab'] ?? $default ); // phpcs:ignore WordPress.Security.NonceVerification.Recommended |
||
110 | |||
111 | // If the pod settings aren't configured yet, open the 'Setup' tab. |
||
112 | if ( ! $this->is_pod_set_up() ) { |
||
113 | $tab = 'setup'; |
||
114 | } |
||
115 | |||
116 | return $tab; |
||
117 | } |
||
118 | |||
119 | /** |
||
120 | * Output all options tabs and return an array of them all, if requested by $return. |
||
121 | * |
||
122 | * @param bool $return Define if the options tabs should be returned. |
||
123 | * |
||
124 | * @return array (If requested) An array of the outputted options tabs. |
||
125 | */ |
||
126 | private function options_page_tabs( $return = false ) { |
||
127 | // The array defining all options sections to be shown as tabs. |
||
128 | $tabs = []; |
||
129 | if ( $this->is_pod_set_up() ) { |
||
130 | $tabs['defaults'] = __( 'Defaults', 'wp-to-diaspora' ); |
||
131 | } |
||
132 | |||
133 | // Add the 'Setup' tab to the end of the list. |
||
134 | $tabs['setup'] = __( 'Setup', 'wp-to-diaspora' ) . '<span id="pod-connection-status" class="dashicons-before hidden"></span><span class="spinner"></span>'; |
||
135 | |||
136 | // Container for all options tabs. |
||
137 | $out = '<h2 id="options-tabs" class="nav-tab-wrapper">'; |
||
138 | foreach ( $tabs as $tab => $name ) { |
||
139 | // The tab link. |
||
140 | $out .= '<a class="nav-tab' . ( $this->current_tab() === $tab ? ' nav-tab-active' : '' ) . '" href="?page=wp_to_diaspora&tab=' . $tab . '">' . $name . '</a>'; |
||
141 | } |
||
142 | $out .= '</h2>'; |
||
143 | |||
144 | // Output the container with all tabs. |
||
145 | echo $out; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped |
||
146 | |||
147 | // Check if the tabs should be returned. |
||
148 | if ( $return ) { |
||
149 | return $tabs; |
||
150 | } |
||
151 | |||
152 | return []; |
||
153 | } |
||
154 | |||
155 | |||
156 | /** |
||
157 | * Set up admin options page. |
||
158 | */ |
||
159 | public function admin_options_page() { |
||
160 | ?> |
||
161 | <div class="wrap"> |
||
162 | <h2>WP to diaspora*</h2> |
||
163 | |||
164 | <div id="wp2d-message" class="notice hidden" <?php echo defined( 'WP2D_DEBUGGING' ) ? ' data-debugging' : ''; ?>></div> |
||
165 | |||
166 | <?php |
||
167 | // Check the connection status to diaspora. |
||
168 | if ( ! $this->is_pod_set_up() ) { |
||
169 | add_settings_error( |
||
170 | 'wp_to_diaspora_settings', |
||
171 | 'wp_to_diaspora_connected', |
||
172 | __( 'First of all, set up the connection to your pod below.', 'wp-to-diaspora' ), |
||
173 | 'updated' |
||
174 | ); |
||
175 | } else { |
||
176 | // Get initial aspects list and connected services. |
||
177 | // DON'T check for empty services list here!! |
||
178 | // It could always be empty, resulting in this code being run every time the page is loaded. |
||
179 | // The aspects will at least have a "Public" entry after the initial fetch. |
||
180 | $aspects_list = $this->get_option( 'aspects_list' ); |
||
181 | if ( ( $force = get_transient( 'wp2d_no_js_force_refetch' ) ) || empty( $aspects_list ) ) { |
||
182 | |||
183 | // Set up the connection to diaspora*. |
||
184 | $api = WP2D_Helpers::api_quick_connect(); |
||
185 | if ( ! $api->has_last_error() ) { |
||
186 | // Get the loaded aspects. |
||
187 | if ( is_array( $aspects = $api->get_aspects() ) ) { |
||
188 | // Save the new list of aspects. |
||
189 | $this->set_option( 'aspects_list', $aspects ); |
||
190 | } |
||
191 | |||
192 | // Get the loaded services. |
||
193 | if ( is_array( $services = $api->get_services() ) ) { |
||
194 | // Save the new list of services. |
||
195 | $this->set_option( 'services_list', $services ); |
||
196 | } |
||
197 | |||
198 | $this->save(); |
||
199 | } |
||
200 | |||
201 | if ( $force ) { |
||
202 | delete_transient( 'wp2d_no_js_force_refetch' ); |
||
203 | $message = ( ! $api->has_last_error() ) ? __( 'Connection successful.', 'wp-to-diaspora' ) : $api->get_last_error(); |
||
204 | add_settings_error( |
||
205 | 'wp_to_diaspora_settings', |
||
206 | 'wp_to_diaspora_connected', |
||
207 | $message, |
||
208 | $api->has_last_error() ? 'error' : 'updated' |
||
209 | ); |
||
210 | } |
||
211 | } |
||
212 | } |
||
213 | |||
214 | // Output success or error message. |
||
215 | settings_errors( 'wp_to_diaspora_settings' ); |
||
216 | ?> |
||
217 | |||
218 | <?php $page_tabs = array_keys( $this->options_page_tabs( true ) ); ?> |
||
219 | |||
220 | <form action="<?php echo esc_url( admin_url( 'options.php' ) ); ?>" method="post"> |
||
221 | <input id="wp2d_no_js" type="hidden" name="wp_to_diaspora_settings[no_js]" value="1"> |
||
222 | <?php |
||
223 | // Load the settings fields. |
||
224 | settings_fields( 'wp_to_diaspora_settings' ); |
||
225 | do_settings_sections( 'wp_to_diaspora_settings' ); |
||
226 | |||
227 | // Get the name of the current tab, if set, else take the first one from the list. |
||
228 | $tab = $this->current_tab( $page_tabs[0] ); |
||
229 | |||
230 | // Add Save and Reset buttons. |
||
231 | echo '<input id="submit-' . esc_attr( $tab ) . '" name="wp_to_diaspora_settings[submit_' . esc_attr( $tab ) . ']" type="submit" class="button-primary" value="' . esc_attr__( 'Save Changes', 'wp-to-diaspora' ) . '" /> '; |
||
232 | if ( 'setup' !== $tab ) { |
||
233 | echo '<input id="reset-' . esc_attr( $tab ) . '" name="wp_to_diaspora_settings[reset_' . esc_attr( $tab ) . ']" type="submit" class="button-secondary" value="' . esc_attr__( 'Reset Defaults', 'wp-to-diaspora' ) . '" />'; |
||
234 | } |
||
235 | ?> |
||
236 | |||
237 | </form> |
||
238 | </div> |
||
239 | |||
240 | <?php |
||
241 | } |
||
242 | |||
243 | /** |
||
244 | * Return if the settings for the pod setup have been entered. |
||
245 | * |
||
246 | * @return bool If the setup for the pod has been done. |
||
247 | */ |
||
248 | public function is_pod_set_up() { |
||
249 | return ( $this->get_option( 'pod' ) && $this->get_option( 'username' ) && $this->get_option( 'password' ) ); |
||
250 | } |
||
251 | |||
252 | /** |
||
253 | * Setup Contextual Help and Options pages. |
||
254 | */ |
||
255 | public function setup_wpadmin_pages() { |
||
256 | // Add options page. |
||
257 | $hook = add_options_page( 'WP to diaspora*', 'WP to diaspora*', 'manage_options', 'wp_to_diaspora', [ $this, 'admin_options_page' ] ); |
||
258 | |||
259 | // Setup the contextual help menu after the options page has been loaded. |
||
260 | add_action( 'load-' . $hook, [ 'WP2D_Contextual_Help', 'instance' ] ); |
||
261 | |||
262 | // Setup the contextual help menu tab for post types. Checks are made there! |
||
263 | add_action( 'load-post.php', [ 'WP2D_Contextual_Help', 'instance' ] ); |
||
264 | add_action( 'load-post-new.php', [ 'WP2D_Contextual_Help', 'instance' ] ); |
||
265 | } |
||
266 | |||
267 | /** |
||
268 | * Initialise the settings sections and fields of the currently selected tab. |
||
269 | */ |
||
270 | public function register_settings() { |
||
271 | // Register the settings with validation callback. |
||
272 | register_setting( 'wp_to_diaspora_settings', 'wp_to_diaspora_settings', [ $this, 'validate_settings' ] ); |
||
273 | |||
274 | // Load only the sections of the selected tab. |
||
275 | switch ( $this->current_tab() ) { |
||
276 | case 'defaults': |
||
277 | // Add a "Defaults" section that contains all posting settings to be used by default. |
||
278 | add_settings_section( 'wp_to_diaspora_defaults_section', __( 'Posting Defaults', 'wp-to-diaspora' ), [ $this, 'defaults_section' ], 'wp_to_diaspora_settings' ); |
||
279 | break; |
||
280 | case 'setup': |
||
281 | // Add a "Setup" section that contains the Pod domain, Username and Password. |
||
282 | add_settings_section( 'wp_to_diaspora_setup_section', __( 'diaspora* Setup', 'wp-to-diaspora' ), [ $this, 'setup_section' ], 'wp_to_diaspora_settings' ); |
||
283 | break; |
||
284 | } |
||
285 | } |
||
286 | |||
287 | |||
288 | /** |
||
289 | * Callback for the "Setup" section. |
||
290 | */ |
||
291 | public function setup_section() { |
||
292 | esc_html_e( 'Set up the connection to your diaspora* account.', 'wp-to-diaspora' ); |
||
293 | |||
294 | // Pod entry field. |
||
295 | add_settings_field( 'pod', __( 'Diaspora* Pod', 'wp-to-diaspora' ), [ $this, 'pod_render' ], 'wp_to_diaspora_settings', 'wp_to_diaspora_setup_section' ); |
||
296 | |||
297 | // Username entry field. |
||
298 | add_settings_field( 'username', __( 'Username', 'wp-to-diaspora' ), [ $this, 'username_render' ], 'wp_to_diaspora_settings', 'wp_to_diaspora_setup_section' ); |
||
299 | |||
300 | // Password entry field. |
||
301 | add_settings_field( 'password', __( 'Password', 'wp-to-diaspora' ), [ $this, 'password_render' ], 'wp_to_diaspora_settings', 'wp_to_diaspora_setup_section' ); |
||
302 | } |
||
303 | |||
304 | /** |
||
305 | * Render the "Pod" field. |
||
306 | */ |
||
307 | public function pod_render() { |
||
308 | /** |
||
309 | * Update entries: |
||
310 | * curl -G 'https://the-federation.info/graphql?raw' --data-urlencode 'query={nodes(platform:"diaspora"){host}}' | jq '.data.nodes[].host' |
||
311 | */ |
||
312 | |||
313 | $pod_list = [ |
||
314 | '20190827.club', |
||
315 | 'a.grumpy.world', |
||
316 | 'azazel.ultragreen.net', |
||
317 | 'berlinspora.de', |
||
318 | 'bobspora.com', |
||
319 | 'borg.zbkbie.com', |
||
320 | 'brighton.social', |
||
321 | 'catpod.cat.scot', |
||
322 | 'd-resources.hopto.org', |
||
323 | 'd.consumium.org', |
||
324 | 'd.kretschmann.social', |
||
325 | 'deko.cloud', |
||
326 | 'despora.de', |
||
327 | 'dia.delaregula.fr', |
||
328 | 'dia.goexchange.de', |
||
329 | 'dia.gordons.gen.nz', |
||
330 | 'diapod.org', |
||
331 | 'diasp.de', |
||
332 | 'diasp.eu', |
||
333 | 'diasp.eu.com', |
||
334 | 'diasp.in', |
||
335 | 'diasp.nl', |
||
336 | 'diasp.org', |
||
337 | 'diaspod.de', |
||
338 | 'diaspora-fr.org', |
||
339 | 'diaspora.animalnet.de', |
||
340 | 'diaspora.anjara.eu', |
||
341 | 'diaspora.asrun.eu', |
||
342 | 'diaspora.baucum.me', |
||
343 | 'diaspora.club', |
||
344 | 'diaspora.conxtor.com', |
||
345 | 'diaspora.counterspin.org.nz', |
||
346 | 'diaspora.cyber-tribal.com', |
||
347 | 'diaspora.flyar.net', |
||
348 | 'diaspora.gegeweb.eu', |
||
349 | 'diaspora.goethe12.de', |
||
350 | 'diaspora.goethe20.de', |
||
351 | 'diaspora.hofud.com', |
||
352 | 'diaspora.immae.eu', |
||
353 | 'diaspora.itopie.ch', |
||
354 | 'diaspora.koehn.com', |
||
355 | 'diaspora.laka.lv', |
||
356 | 'diaspora.lamsade.fr', |
||
357 | 'diaspora.mathematicon.com', |
||
358 | 'diaspora.microdata.co.uk', |
||
359 | 'diaspora.mifritscher.de', |
||
360 | 'diaspora.normandie-libre.fr', |
||
361 | 'diaspora.odat.xyz', |
||
362 | 'diaspora.ofstad.xyz', |
||
363 | 'diaspora.permutationsofchaos.com', |
||
364 | 'diaspora.psyco.fr', |
||
365 | 'diaspora.ruhrmail.de', |
||
366 | 'diaspora.sceal.ie', |
||
367 | 'diaspora.schoenf.de', |
||
368 | 'diaspora.snakenode.eu', |
||
369 | 'diaspora.solusar.de', |
||
370 | 'diaspora.somethinghub.com', |
||
371 | 'diaspora.stevesullam.com', |
||
372 | 'diaspora.thus.ch', |
||
373 | 'diaspora.town', |
||
374 | 'diaspora.trancart.eu', |
||
375 | 'diaspora.vrije-mens.org', |
||
376 | 'diaspora.williamsonday.org', |
||
377 | 'diaspora.willispickering.com', |
||
378 | 'diaspora.yuais.net', |
||
379 | 'diasporabr.com.br', |
||
380 | 'diasporapod.no', |
||
381 | 'diasporing.ch', |
||
382 | 'dicespora.net', |
||
383 | 'dorf-post.de', |
||
384 | 'expod.de', |
||
385 | 'eyepod.oksocial.net', |
||
386 | 'failure.net', |
||
387 | 'federatica.space', |
||
388 | 'framasphere.org', |
||
389 | 'freehuman.fr', |
||
390 | 'friendsmeet.win', |
||
391 | 'iitians.xyz', |
||
392 | 'iliketoast.net', |
||
393 | 'ingtech.net', |
||
394 | 'jardin.umaneti.net', |
||
395 | 'jochem.name', |
||
396 | 'joindiaspora.com', |
||
397 | 'kitsune.click', |
||
398 | 'lanx.fr', |
||
399 | 'librenet.gr', |
||
400 | 'livepods.net', |
||
401 | 'lstoll-diaspora.herokuapp.com', |
||
402 | 'manapod.space', |
||
403 | 'mastodon.webseed.com', |
||
404 | 'mindfeed.herokuapp.com', |
||
405 | 'mondiaspora.net', |
||
406 | 'mondiaspora.org', |
||
407 | 'nerdpol.ch', |
||
408 | 'nodewatch.ninja', |
||
409 | 'nota.404.mn', |
||
410 | 'parlote.facil.services', |
||
411 | 'paxation.org', |
||
412 | 'pekospora.pekoyama.com', |
||
413 | 'pluspora.com', |
||
414 | 'pod.aevl.us', |
||
415 | 'pod.afox.me', |
||
416 | 'pod.alhague.net', |
||
417 | 'pod.asap-soft.com', |
||
418 | 'pod.automat.one', |
||
419 | 'pod.buergi.lugs.ch', |
||
420 | 'pod.chabotsi.fr', |
||
421 | 'pod.dapor.net', |
||
422 | 'pod.ddna.co', |
||
423 | 'pod.diaspora.software', |
||
424 | 'pod.dukun.de', |
||
425 | 'pod.fab-l3.org', |
||
426 | 'pod.ferner-online.de', |
||
427 | 'pod.fulll.name', |
||
428 | 'pod.g3l.org', |
||
429 | 'pod.geraspora.de', |
||
430 | 'pod.gothic.net.au', |
||
431 | 'pod.haxxors.com', |
||
432 | 'pod.hoizi.net', |
||
433 | 'pod.interlin.nl', |
||
434 | 'pod.jamidisi-edu.de', |
||
435 | 'pod.jns.im', |
||
436 | 'pod.jotoma.de', |
||
437 | 'pod.libreplanetbr.org', |
||
438 | 'pod.mttv.it', |
||
439 | 'pod.omgsrsly.net', |
||
440 | 'pod.orkz.net', |
||
441 | 'pod.pc-tiede.de', |
||
442 | 'pod.reckord.de', |
||
443 | 'pod.redfish.ca', |
||
444 | 'pod.rusa.fr', |
||
445 | 'pod.tchncs.de', |
||
446 | 'pod.thing.org', |
||
447 | 'podbay.net', |
||
448 | 'poddery.com', |
||
449 | 'podington.oksocial.net', |
||
450 | 'podling.oksocial.net', |
||
451 | 'podricing.pw', |
||
452 | 'protagio.social', |
||
453 | 'pubpod.alqualonde.org', |
||
454 | 'revreso.de', |
||
455 | 'rhizome.hfbk.net', |
||
456 | 'ruhrspora.de', |
||
457 | 'sechat.org', |
||
458 | 'shrekislove.us', |
||
459 | 'sn.xxz.su', |
||
460 | 'social.blackrosehosting.com', |
||
461 | 'social.cooleysekula.net', |
||
462 | 'social.daxbau.net', |
||
463 | 'social.dbernhardt.com', |
||
464 | 'social.elinux.org', |
||
465 | 'social.gibberfish.org', |
||
466 | 'social.hiernaux.eu', |
||
467 | 'social.milhousfamily.com', |
||
468 | 'social.mrzyx.de', |
||
469 | 'social.prien.xyz', |
||
470 | 'social.sejourne.info', |
||
471 | 'social.sip247.com', |
||
472 | 'spora.grin.hu', |
||
473 | 'spyurk.am', |
||
474 | 'sysad.org', |
||
475 | 'test.poddery.com', |
||
476 | 'tovari.ch', |
||
477 | 'twitt-dev.opencaribbean.org', |
||
478 | 'tyrell.marway.org', |
||
479 | 'wertier.de', |
||
480 | 'wgserv.eu', |
||
481 | 'whatsnewz.com', |
||
482 | 'wk3.org', |
||
483 | 'www.diasporaix.de', |
||
484 | 'www.fessebouc.fr', |
||
485 | 'www.reteasociala.ro', |
||
486 | 'xn--b1aafeapdba0ada1es.xn--p1ai', |
||
487 | ]; |
||
488 | ?> |
||
489 | https://<input type="text" name="wp_to_diaspora_settings[pod]" value="<?php echo esc_attr( $this->get_option( 'pod' ) ); ?>" placeholder="e.g. joindiaspora.com" autocomplete="on" list="pod-list" required> |
||
490 | <datalist id="pod-list"> |
||
491 | <?php foreach ( $pod_list as $pod ) : ?> |
||
492 | <option value="<?php echo esc_attr( $pod ); ?>"></option> |
||
493 | <?php endforeach; ?> |
||
494 | </datalist> |
||
495 | <?php |
||
496 | } |
||
497 | |||
498 | /** |
||
499 | * Render the "Username" field. |
||
500 | */ |
||
501 | public function username_render() { |
||
502 | ?> |
||
503 | <input type="text" name="wp_to_diaspora_settings[username]" value="<?php echo esc_attr( $this->get_option( 'username' ) ); ?>" placeholder="<?php esc_attr_e( 'Username', 'wp-to-diaspora' ); ?>" required> |
||
504 | <?php |
||
505 | } |
||
506 | |||
507 | /** |
||
508 | * Render the "Password" field. |
||
509 | */ |
||
510 | public function password_render() { |
||
511 | // Special case if we already have a password. |
||
512 | $has_password = ( '' !== $this->get_option( 'password', '' ) ); |
||
513 | $placeholder = $has_password ? __( 'Password already set.', 'wp-to-diaspora' ) : __( 'Password', 'wp-to-diaspora' ); |
||
514 | $required = $has_password ? '' : ' required'; |
||
515 | ?> |
||
516 | <input type="password" name="wp_to_diaspora_settings[password]" value="" placeholder="<?php echo esc_attr( $placeholder ); ?>"<?php echo esc_attr( $required ); ?>> |
||
517 | <?php if ( $has_password ) : ?> |
||
518 | <p class="description"><?php esc_html_e( 'If you would like to change the password type a new one. Otherwise leave this blank.', 'wp-to-diaspora' ); ?></p> |
||
519 | <?php endif; |
||
520 | } |
||
521 | |||
522 | |||
523 | /** |
||
524 | * Callback for the "Defaults" section. |
||
525 | */ |
||
526 | public function defaults_section() { |
||
527 | esc_html_e( 'Define the default posting behaviour for all posts here. These settings can be modified for each post individually, by changing the values in the "WP to diaspora*" meta box, which gets displayed in your post edit screen.', 'wp-to-diaspora' ); |
||
528 | |||
529 | // Post types field. |
||
530 | add_settings_field( 'enabled_post_types', __( 'Post types', 'wp-to-diaspora' ), [ $this, 'post_types_render' ], 'wp_to_diaspora_settings', 'wp_to_diaspora_defaults_section' ); |
||
531 | |||
532 | // Post to diaspora* checkbox. |
||
533 | add_settings_field( 'post_to_diaspora', __( 'Post to diaspora*', 'wp-to-diaspora' ), [ $this, 'post_to_diaspora_render' ], 'wp_to_diaspora_settings', 'wp_to_diaspora_defaults_section', $this->get_option( 'post_to_diaspora' ) ); |
||
534 | |||
535 | // Full entry link checkbox. |
||
536 | add_settings_field( 'fullentrylink', __( 'Show "Posted at" link?', 'wp-to-diaspora' ), [ $this, 'fullentrylink_render' ], 'wp_to_diaspora_settings', 'wp_to_diaspora_defaults_section', $this->get_option( 'fullentrylink' ) ); |
||
537 | |||
538 | // Full text, excerpt or none radio buttons. |
||
539 | add_settings_field( 'display', __( 'Display', 'wp-to-diaspora' ), [ $this, 'display_render' ], 'wp_to_diaspora_settings', 'wp_to_diaspora_defaults_section', $this->get_option( 'display' ) ); |
||
540 | |||
541 | // Tags to post dropdown. |
||
542 | add_settings_field( 'tags_to_post', __( 'Tags to post', 'wp-to-diaspora' ), [ $this, 'tags_to_post_render' ], 'wp_to_diaspora_settings', 'wp_to_diaspora_defaults_section', $this->get_option( 'tags_to_post', 'gc' ) ); |
||
543 | |||
544 | // Global tags field. |
||
545 | add_settings_field( 'global_tags', __( 'Global tags', 'wp-to-diaspora' ), [ $this, 'global_tags_render' ], 'wp_to_diaspora_settings', 'wp_to_diaspora_defaults_section', $this->get_option( 'global_tags' ) ); |
||
546 | |||
547 | // Aspects checkboxes. |
||
548 | add_settings_field( 'aspects', __( 'Aspects', 'wp-to-diaspora' ), [ $this, 'aspects_services_render' ], 'wp_to_diaspora_settings', 'wp_to_diaspora_defaults_section', [ 'aspects', $this->get_option( 'aspects' ) ] ); |
||
549 | |||
550 | // Services checkboxes. |
||
551 | add_settings_field( 'services', __( 'Services', 'wp-to-diaspora' ), [ $this, 'aspects_services_render' ], 'wp_to_diaspora_settings', 'wp_to_diaspora_defaults_section', [ 'services', $this->get_option( 'services' ) ] ); |
||
552 | } |
||
553 | |||
554 | /** |
||
555 | * Render the "Post types" checkboxes. |
||
556 | */ |
||
557 | public function post_types_render() { |
||
558 | $post_types = get_post_types( [ 'public' => true ], 'objects' ); |
||
559 | |||
560 | // Remove excluded post types from the list. |
||
561 | $excluded_post_types = [ 'attachment', 'nav_menu_item', 'revision' ]; |
||
562 | foreach ( $excluded_post_types as $excluded ) { |
||
563 | unset( $post_types[ $excluded ] ); |
||
564 | } |
||
565 | ?> |
||
566 | |||
567 | <select id="enabled-post-types" multiple data-placeholder="<?php esc_attr_e( 'None', 'wp-to-diaspora' ); ?>" class="chosen" name="wp_to_diaspora_settings[enabled_post_types][]"> |
||
568 | <?php foreach ( $post_types as $post_type ) : ?> |
||
569 | <option value="<?php echo esc_attr( $post_type->name ); ?>" <?php selected( in_array( $post_type->name, $this->get_option( 'enabled_post_types' ), true ) ); ?>><?php echo esc_html( $post_type->label ); ?></option> |
||
570 | <?php endforeach; ?> |
||
571 | </select> |
||
572 | |||
573 | <p class="description"><?php esc_html_e( 'Choose which post types can be posted to diaspora*.', 'wp-to-diaspora' ); ?></p> |
||
574 | |||
575 | <?php |
||
576 | } |
||
577 | |||
578 | /** |
||
579 | * Render the "Post to diaspora*" checkbox. |
||
580 | * |
||
581 | * @param bool $post_to_diaspora If this checkbox is checked or not. |
||
582 | */ |
||
583 | public function post_to_diaspora_render( $post_to_diaspora ) { |
||
584 | $label = ( 'settings_page_wp_to_diaspora' === get_current_screen()->id ) ? __( 'Yes', 'wp-to-diaspora' ) : __( 'Post to diaspora*', 'wp-to-diaspora' ); |
||
585 | ?> |
||
586 | <label><input type="checkbox" id="post-to-diaspora" name="wp_to_diaspora_settings[post_to_diaspora]" value="1" <?php checked( $post_to_diaspora ); ?>><?php echo esc_html( $label ); ?></label> |
||
587 | <?php |
||
588 | } |
||
589 | |||
590 | /** |
||
591 | * Render the "Show 'Posted at' link" checkbox. |
||
592 | * |
||
593 | * @param bool $show_link If the checkbox is checked or not. |
||
594 | */ |
||
595 | public function fullentrylink_render( $show_link ) { |
||
596 | $description = __( 'Include a link back to your original post.', 'wp-to-diaspora' ); |
||
597 | $checkbox = '<input type="checkbox" id="fullentrylink" name="wp_to_diaspora_settings[fullentrylink]" value="1"' . checked( $show_link, true, false ) . '>'; |
||
598 | |||
599 | if ( 'settings_page_wp_to_diaspora' === get_current_screen()->id ) : ?> |
||
600 | <label><?php echo $checkbox; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?><?php esc_html_e( 'Yes', 'wp-to-diaspora' ); ?></label> |
||
601 | <p class="description"><?php echo esc_html( $description ); ?></p> |
||
602 | <?php else : ?> |
||
603 | <label title="<?php echo esc_attr( $description ); ?>"><?php echo $checkbox; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?><?php esc_html_e( 'Show "Posted at" link?', 'wp-to-diaspora' ); ?></label> |
||
604 | <?php endif; |
||
605 | } |
||
606 | |||
607 | /** |
||
608 | * Render the "Display" radio buttons. |
||
609 | * |
||
610 | * @param string $display The selected radio button. |
||
611 | */ |
||
612 | public function display_render( $display ) { |
||
613 | ?> |
||
614 | <label><input type="radio" name="wp_to_diaspora_settings[display]" value="full" <?php checked( $display, 'full' ); ?>><?php esc_html_e( 'Full Post', 'wp-to-diaspora' ); ?></label><br/> |
||
615 | <label><input type="radio" name="wp_to_diaspora_settings[display]" value="excerpt" <?php checked( $display, 'excerpt' ); ?>><?php esc_html_e( 'Excerpt', 'wp-to-diaspora' ); ?></label><br/> |
||
616 | <label><input type="radio" name="wp_to_diaspora_settings[display]" value="none" <?php checked( $display, 'none' ); ?>><?php esc_html_e( 'None', 'wp-to-diaspora' ); ?></label> |
||
617 | <?php |
||
618 | } |
||
619 | |||
620 | /** |
||
621 | * Render the "Tags to post" field. |
||
622 | * |
||
623 | * @param array $tags_to_post The types of tags to be posted. |
||
624 | */ |
||
625 | public function tags_to_post_render( $tags_to_post ) { |
||
626 | $on_settings_page = ( 'settings_page_wp_to_diaspora' === get_current_screen()->id ); |
||
627 | $description = esc_html__( 'Choose which tags should be posted to diaspora*.', 'wp-to-diaspora' ); |
||
628 | |||
629 | if ( ! $on_settings_page ) { |
||
630 | echo '<label>' . esc_html( $description ); |
||
631 | } |
||
632 | |||
633 | ?> |
||
634 | <select id="tags-to-post" multiple data-placeholder="<?php esc_attr_e( 'No tags', 'wp-to-diaspora' ); ?>" class="chosen" name="wp_to_diaspora_settings[tags_to_post][]"> |
||
635 | <option value="global" <?php selected( in_array( 'global', $tags_to_post, true ) ); ?>><?php esc_html_e( 'Global tags', 'wp-to-diaspora' ); ?></option> |
||
636 | <option value="custom" <?php selected( in_array( 'custom', $tags_to_post, true ) ); ?>><?php esc_html_e( 'Custom tags', 'wp-to-diaspora' ); ?></option> |
||
637 | <option value="post" <?php selected( in_array( 'post', $tags_to_post, true ) ); ?>><?php esc_html_e( 'Post tags', 'wp-to-diaspora' ); ?></option> |
||
638 | </select> |
||
639 | |||
640 | <?php if ( $on_settings_page ) : ?> |
||
641 | <p class="description"><?php echo esc_html( $description ); ?></p> |
||
642 | <?php else : ?> |
||
643 | </label> |
||
644 | <?php endif; |
||
645 | } |
||
646 | |||
647 | /** |
||
648 | * Render the "Global tags" field. |
||
649 | * |
||
650 | * @param array $tags The global tags to be posted. |
||
651 | */ |
||
652 | public function global_tags_render( $tags ) { |
||
653 | WP2D_Helpers::arr_to_str( $tags ); |
||
654 | ?> |
||
655 | <input type="text" class="regular-text wp2d-tags" name="wp_to_diaspora_settings[global_tags]" value="<?php echo esc_attr( $tags ); ?>" placeholder="<?php esc_attr_e( 'Global tags', 'wp-to-diaspora' ); ?>"> |
||
656 | <p class="description"><?php esc_html_e( 'Custom tags to add to all posts being posted to diaspora*.', 'wp-to-diaspora' ); ?></p> |
||
657 | <?php |
||
658 | } |
||
659 | |||
660 | /** |
||
661 | * Render the "Custom tags" field. |
||
662 | * |
||
663 | * @param array $tags The custom tags to be posted. |
||
664 | */ |
||
665 | public function custom_tags_render( $tags ) { |
||
666 | WP2D_Helpers::arr_to_str( $tags ); |
||
667 | ?> |
||
668 | <label title="<?php esc_attr_e( 'Custom tags to add to this post when it\'s posted to diaspora*.', 'wp-to-diaspora' ); ?>"> |
||
669 | <?php esc_html_e( 'Custom tags', 'wp-to-diaspora' ); ?> |
||
670 | <input type="text" class="widefat wp2d-tags" name="wp_to_diaspora_settings[custom_tags]" value="<?php echo esc_attr( $tags ); ?>"> |
||
671 | </label> |
||
672 | <p class="description"><?php esc_html_e( 'Separate tags with commas', 'wp-to-diaspora' ); ?></p> |
||
673 | <?php |
||
674 | } |
||
675 | |||
676 | /** |
||
677 | * Render the "Aspects" and "Services" checkboxes. |
||
678 | * |
||
679 | * @param array $args Array containing the type and items to output as checkboxes. |
||
680 | */ |
||
681 | public function aspects_services_render( $args ) { |
||
682 | [ $type, $items ] = $args; |
||
0 ignored issues
–
show
The variable
$items seems only to be defined at a later point. Did you maybe move this code here without moving the variable definition?
This error can happen if you refactor code and forget to move the variable initialization. Let’s take a look at a simple example: function someFunction() {
$x = 5;
echo $x;
}
The above code is perfectly fine. Now imagine that we re-order the statements: function someFunction() {
echo $x;
$x = 5;
}
In that case, ![]() |
|||
683 | |||
684 | // This is where the 2 types show their differences. |
||
685 | switch ( $type ) { |
||
686 | case 'aspects': |
||
687 | $refresh_button = __( 'Refresh Aspects', 'wp-to-diaspora' ); |
||
688 | $description = esc_html__( 'Choose which aspects to share to.', 'wp-to-diaspora' ); |
||
689 | $empty_label = '<input type="checkbox" name="wp_to_diaspora_settings[aspects][]" value="public" checked="checked">' . esc_html__( 'Public', 'wp-to-diaspora' ); |
||
690 | break; |
||
691 | |||
692 | case 'services': |
||
693 | $refresh_button = __( 'Refresh Services', 'wp-to-diaspora' ); |
||
694 | $description = sprintf( |
||
695 | '%1$s<br><a href="%2$s" target="_blank">%3$s</a>', |
||
696 | esc_html__( 'Choose which services to share to.', 'wp-to-diaspora' ), |
||
697 | esc_url( 'https://' . $this->get_option( 'pod' ) . '/services' ), |
||
698 | esc_html__( 'Show available services on my pod.', 'wp-to-diaspora' ) |
||
699 | ); |
||
700 | $empty_label = esc_html__( 'No services connected yet.', 'wp-to-diaspora' ); |
||
701 | break; |
||
702 | |||
703 | default: |
||
704 | return; |
||
705 | } |
||
706 | |||
707 | $items = array_filter( (array) $items ) ?: []; |
||
0 ignored issues
–
show
The variable
$items seems only to be defined at a later point. Did you maybe move this code here without moving the variable definition?
This error can happen if you refactor code and forget to move the variable initialization. Let’s take a look at a simple example: function someFunction() {
$x = 5;
echo $x;
}
The above code is perfectly fine. Now imagine that we re-order the statements: function someFunction() {
echo $x;
$x = 5;
}
In that case, ![]() |
|||
708 | |||
709 | // Special case for this field if it's displayed on the settings page. |
||
710 | $on_settings_page = ( 'settings_page_wp_to_diaspora' === get_current_screen()->id ); |
||
711 | |||
712 | if ( ! $on_settings_page ) { |
||
713 | echo $description; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped |
||
714 | $description = ''; |
||
715 | } |
||
716 | |||
717 | ?> |
||
718 | <div id="<?php echo esc_attr( $type ); ?>-container" data-<?php echo esc_attr( $type ); ?>-selected="<?php echo esc_attr( implode( ',', $items ) ); ?>"> |
||
719 | <?php if ( $list = (array) $this->get_option( $type . '_list' ) ) : ?> |
||
720 | <?php foreach ( $list as $id => $name ) : ?> |
||
721 | <label><input type="checkbox" name="wp_to_diaspora_settings[<?php echo esc_attr( $type ); ?>][]" value="<?php echo esc_attr( $id ); ?>" <?php checked( in_array( $id, $items, false ) ); // phpcs:ignore WordPress.PHP.StrictInArray.FoundNonStrictFalse ?>><?php echo esc_html( $name ); ?></label> |
||
722 | <?php endforeach; ?> |
||
723 | <?php else : ?> |
||
724 | <label><?php echo $empty_label; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?></label> |
||
725 | <?php endif; ?> |
||
726 | </div> |
||
727 | <p class="description"> |
||
728 | <?php echo $description; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?> |
||
729 | <a id="refresh-<?php echo esc_attr( $type ); ?>-list" class="button hide-if-no-js"><?php echo esc_html( $refresh_button ); ?></a> |
||
730 | <span class="spinner"></span> |
||
731 | <span class="hide-if-js"><?php printf( esc_html_x( 'To update this list, %1$sre-save your login info%2$s.', 'placeholders are link tags to the settings page.', 'wp-to-diaspora' ), '<a href="' . esc_url( admin_url( 'options-general.php?page=wp_to_diaspora' ) ) . '&tab=setup" target="_blank">', '</a>' ); ?></span> |
||
732 | </p> |
||
733 | <?php |
||
734 | } |
||
735 | |||
736 | |||
737 | /** |
||
738 | * Get a specific option. |
||
739 | * |
||
740 | * @param null|string $option ID of option to get. |
||
741 | * @param mixed $default Override default value if option not found. |
||
742 | * |
||
743 | * @return mixed Requested option value. |
||
744 | */ |
||
745 | public function get_option( $option = null, $default = null ) { |
||
746 | if ( null === self::$options ) { |
||
747 | self::$options = get_option( 'wp_to_diaspora_settings', self::$default_options ); |
||
748 | } |
||
749 | if ( null !== $option ) { |
||
750 | if ( isset( self::$options[ $option ] ) ) { |
||
751 | // Return found option value. |
||
752 | return self::$options[ $option ]; |
||
753 | } elseif ( null !== $default ) { |
||
754 | // Return overridden default value. |
||
755 | return $default; |
||
756 | } elseif ( isset( self::$default_options[ $option ] ) ) { |
||
757 | // Return default option value. |
||
758 | return self::$default_options[ $option ]; |
||
759 | } |
||
760 | } |
||
761 | |||
762 | return $default; |
||
763 | } |
||
764 | |||
765 | /** |
||
766 | * Get all options. |
||
767 | * |
||
768 | * @return array All the options. |
||
769 | */ |
||
770 | public function get_options() { |
||
771 | return self::$options; |
||
772 | } |
||
773 | |||
774 | /** |
||
775 | * Set a certain option. |
||
776 | * |
||
777 | * @param string $option ID of option to get. |
||
778 | * @param array|string $value Value to be set for the passed option. |
||
779 | * @param bool $save Save the options immediately after setting them. |
||
780 | */ |
||
781 | public function set_option( $option, $value, $save = false ) { |
||
782 | if ( null !== $option ) { |
||
783 | if ( null !== $value ) { |
||
784 | self::$options[ $option ] = $value; |
||
785 | } else { |
||
786 | unset( self::$options[ $option ] ); |
||
787 | } |
||
788 | } |
||
789 | |||
790 | $save && $this->save(); |
||
791 | } |
||
792 | |||
793 | /** |
||
794 | * Save the options. |
||
795 | */ |
||
796 | public function save() { |
||
797 | update_option( 'wp_to_diaspora_settings', self::$options ); |
||
798 | } |
||
799 | |||
800 | /** |
||
801 | * Get all valid input values for the passed field. |
||
802 | * |
||
803 | * @param string $field Field to get the valid values for. |
||
804 | * |
||
805 | * @return array List of valid values. |
||
806 | */ |
||
807 | public function get_valid_values( $field ) { |
||
808 | if ( array_key_exists( $field, self::$valid_values ) ) { |
||
809 | return self::$valid_values[ $field ]; |
||
810 | } |
||
811 | } |
||
812 | |||
813 | /** |
||
814 | * Check if a value is valid for the passed field. |
||
815 | * |
||
816 | * @param string $field Field to check the valid value for. |
||
817 | * @param mixed $value Value to check validity. |
||
818 | * |
||
819 | * @return bool If the passed value is valid. |
||
820 | */ |
||
821 | public function is_valid_value( $field, $value ) { |
||
822 | if ( $valids = $this->get_valid_values( $field ) ) { |
||
823 | return in_array( $value, $valids, true ); |
||
824 | } |
||
825 | |||
826 | return false; |
||
827 | } |
||
828 | |||
829 | /** |
||
830 | * Attempt to upgrade the password from using AUTH_KEY to using WP2D_AUTH_KEY. |
||
831 | * |
||
832 | * @since 2.2.0 |
||
833 | * |
||
834 | * @param bool $save If the password should be saved to the options immediately. |
||
835 | */ |
||
836 | public function attempt_password_upgrade( $save = false ) { |
||
837 | if ( AUTH_KEY !== WP2D_ENC_KEY ) { |
||
838 | $old_pw = WP2D_Helpers::decrypt( (string) $this->get_option( 'password' ), AUTH_KEY ); |
||
839 | if ( null !== $old_pw ) { |
||
840 | $new_pw = WP2D_Helpers::encrypt( $old_pw, WP2D_ENC_KEY ); |
||
841 | $this->set_option( 'password', $new_pw, $save ); |
||
842 | } |
||
843 | } |
||
844 | } |
||
845 | |||
846 | /** |
||
847 | * Validate all settings. |
||
848 | * |
||
849 | * @param array $input RAW input values. |
||
850 | * |
||
851 | * @return array Validated input values. |
||
852 | */ |
||
853 | public function validate_settings( $input ) { |
||
854 | /* Validate all settings before saving to the database. */ |
||
855 | |||
856 | // Saving the pod setup details. |
||
857 | if ( isset( $input['submit_setup'] ) ) { |
||
858 | $input['pod'] = trim( sanitize_text_field( $input['pod'] ), ' /' ); |
||
859 | $input['username'] = sanitize_text_field( $input['username'] ); |
||
860 | $input['password'] = sanitize_text_field( $input['password'] ); |
||
861 | |||
862 | // If password is blank, it hasn't been changed. |
||
863 | // If new password is equal to the encrypted password already saved, it was just passed again. It happens everytime update_option('wp_to_diaspora_settings') is called. |
||
864 | if ( '' === $input['password'] || $this->get_option( 'password' ) === $input['password'] ) { |
||
865 | // Attempt a password upgrade if applicable. |
||
866 | $this->attempt_password_upgrade( true ); |
||
867 | $input['password'] = $this->get_option( 'password' ); |
||
868 | } else { |
||
869 | $input['password'] = WP2D_Helpers::encrypt( $input['password'] ); |
||
870 | } |
||
871 | |||
872 | // Keep a note of the current AUTH_KEY. |
||
873 | $this->set_option( 'auth_key_hash', md5( AUTH_KEY ), true ); |
||
874 | |||
875 | // This is for when JS in not enabled, to make sure that the aspects and services |
||
876 | // are re-fetched when displaying the options page after saving. |
||
877 | if ( isset( $input['no_js'] ) ) { |
||
878 | set_transient( 'wp2d_no_js_force_refetch', true ); |
||
879 | } |
||
880 | } |
||
881 | |||
882 | // Saving the default options. |
||
883 | if ( isset( $input['submit_defaults'] ) ) { |
||
884 | if ( ! isset( $input['enabled_post_types'] ) ) { |
||
885 | $input['enabled_post_types'] = []; |
||
886 | } |
||
887 | |||
888 | // Checkboxes. |
||
889 | $this->validate_checkboxes( [ 'post_to_diaspora', 'fullentrylink' ], $input ); |
||
890 | |||
891 | // Single Selects. |
||
892 | $this->validate_single_selects( 'display', $input ); |
||
893 | |||
894 | // Multiple Selects. |
||
895 | $this->validate_multi_selects( 'tags_to_post', $input ); |
||
896 | |||
897 | // Get unique, non-empty, trimmed tags and clean them up. |
||
898 | $this->validate_tags( $input['global_tags'] ); |
||
899 | |||
900 | // Clean up the list of aspects. If the list is empty, only use the 'Public' aspect. |
||
901 | $this->validate_aspects_services( $input['aspects'], [ 'public' ] ); |
||
902 | |||
903 | // Clean up the list of services. |
||
904 | $this->validate_aspects_services( $input['services'] ); |
||
905 | } |
||
906 | |||
907 | // Reset to defaults. |
||
908 | if ( isset( $input['reset_defaults'] ) ) { |
||
909 | // Set the input to the default options. |
||
910 | $input = self::$default_options; |
||
911 | |||
912 | // Don't reset the fetched lists of aspects and services. |
||
913 | unset( $input['pod_list'], $input['aspects_list'], $input['services_list'] ); |
||
914 | } |
||
915 | |||
916 | // Unset all unused input fields. |
||
917 | unset( $input['submit_defaults'], $input['reset_defaults'], $input['submit_setup'] ); |
||
918 | |||
919 | // Parse inputs with default options and return. |
||
920 | return wp_parse_args( $input, array_merge( self::$default_options, self::$options ) ); |
||
921 | } |
||
922 | |||
923 | /** |
||
924 | * Validate checkboxes, make them either true or false. |
||
925 | * |
||
926 | * @param string|array $checkboxes Checkboxes to validate. |
||
927 | * @param array $options Options values themselves. |
||
928 | * |
||
929 | * @return array The validated options. |
||
930 | */ |
||
931 | public function validate_checkboxes( $checkboxes, &$options ) { |
||
932 | foreach ( WP2D_Helpers::str_to_arr( $checkboxes ) as $checkbox ) { |
||
0 ignored issues
–
show
The expression
\WP2D_Helpers::str_to_arr($checkboxes) of type array|string is not guaranteed to be traversable. How about adding an additional type check?
There are different options of fixing this problem.
![]() |
|||
933 | $options[ $checkbox ] = isset( $options[ $checkbox ] ); |
||
934 | } |
||
935 | |||
936 | return $options; |
||
937 | } |
||
938 | |||
939 | /** |
||
940 | * Validate single-select fields and make sure their selected value are valid. |
||
941 | * |
||
942 | * @param string|array $selects Name(s) of the select fields. |
||
943 | * @param array $options Options values themselves. |
||
944 | * |
||
945 | * @return array The validated options. |
||
946 | */ |
||
947 | public function validate_single_selects( $selects, &$options ) { |
||
948 | foreach ( WP2D_Helpers::str_to_arr( $selects ) as $select ) { |
||
0 ignored issues
–
show
The expression
\WP2D_Helpers::str_to_arr($selects) of type array|string is not guaranteed to be traversable. How about adding an additional type check?
There are different options of fixing this problem.
![]() |
|||
949 | if ( isset( $options[ $select ] ) && ! $this->is_valid_value( $select, $options[ $select ] ) ) { |
||
950 | unset( $options[ $select ] ); |
||
951 | } |
||
952 | } |
||
953 | |||
954 | return $options; |
||
955 | } |
||
956 | |||
957 | /** |
||
958 | * Validate multi-select fields and make sure their selected values are valid. |
||
959 | * |
||
960 | * @param string|array $selects Name(s) of the select fields. |
||
961 | * @param array $options Options values themselves. |
||
962 | * |
||
963 | * @return array The validated options. |
||
964 | */ |
||
965 | public function validate_multi_selects( $selects, &$options ) { |
||
966 | foreach ( WP2D_Helpers::str_to_arr( $selects ) as $select ) { |
||
0 ignored issues
–
show
The expression
\WP2D_Helpers::str_to_arr($selects) of type array|string is not guaranteed to be traversable. How about adding an additional type check?
There are different options of fixing this problem.
![]() |
|||
967 | if ( isset( $options[ $select ] ) ) { |
||
968 | foreach ( (array) $options[ $select ] as $option_value ) { |
||
969 | if ( ! $this->is_valid_value( $select, $option_value ) ) { |
||
970 | unset( $options[ $select ] ); |
||
971 | break; |
||
972 | } |
||
973 | } |
||
974 | } else { |
||
975 | $options[ $select ] = []; |
||
976 | } |
||
977 | } |
||
978 | |||
979 | return $options; |
||
980 | } |
||
981 | |||
982 | /** |
||
983 | * Clean up the passed tags. Keep only alphanumeric, hyphen and underscore characters. |
||
984 | * |
||
985 | * @param array|string $tags Tags to be cleaned as array or comma seperated values. |
||
986 | * |
||
987 | * @return array The cleaned tags. |
||
988 | */ |
||
989 | public function validate_tags( &$tags ) { |
||
990 | WP2D_Helpers::str_to_arr( $tags ); |
||
991 | |||
992 | $tags = array_map( [ $this, 'validate_tag' ], |
||
993 | array_unique( |
||
994 | array_filter( $tags, 'trim' ) |
||
995 | ) |
||
996 | ); |
||
997 | |||
998 | return $tags; |
||
999 | } |
||
1000 | |||
1001 | /** |
||
1002 | * Clean up the passed tag. Keep only alphanumeric, hyphen and underscore characters. |
||
1003 | * |
||
1004 | * @todo What about eastern characters? (chinese, indian, etc.) |
||
1005 | * |
||
1006 | * @param string $tag Tag to be cleaned. |
||
1007 | * |
||
1008 | * @return string The clean tag. |
||
1009 | */ |
||
1010 | public function validate_tag( &$tag ) { |
||
1011 | $tag = preg_replace( '/[^\w $\-]/u', '', str_replace( ' ', '-', trim( $tag ) ) ); |
||
1012 | |||
1013 | return $tag; |
||
1014 | } |
||
1015 | |||
1016 | /** |
||
1017 | * Validate the passed aspects or services. |
||
1018 | * |
||
1019 | * @param array $aspects_services List of aspects or services that need to be validated. |
||
1020 | * @param array $default Default value if not valid. |
||
1021 | * |
||
1022 | * @return array The validated list of aspects or services. |
||
1023 | */ |
||
1024 | public function validate_aspects_services( &$aspects_services, array $default = [] ) { |
||
1025 | if ( empty( $aspects_services ) || ! is_array( $aspects_services ) ) { |
||
1026 | $aspects_services = $default; |
||
1027 | } else { |
||
1028 | array_walk( $aspects_services, 'sanitize_text_field' ); |
||
1029 | } |
||
1030 | |||
1031 | return $aspects_services; |
||
1032 | } |
||
1033 | } |
||
1034 |
This check marks access to variables or properties that have not been declared yet. While PHP has no explicit notion of declaring a variable, accessing it before a value is assigned to it is most likely a bug.