PluginProbe
WP Discourse / trunk
WP Discourse vtrunk
2.6.4 2.6.3 1.2.1 1.2.2 1.2.5 1.2.6 1.2.7 1.2.8 1.3.0 1.3.1 1.3.2 1.3.3 1.3.4 1.3.5 1.3.6 1.3.7 1.3.8 1.3.85 1.4.0 1.4.15 1.4.2 1.4.3 1.4.4 1.4.5 1.4.6 All 150 releases
wp-discourse / admin / settings-validator.php

settings-validator.php in WP Discourse trunk, at admin/settings-validator.php

908 lines 26.8 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Validation methods for the settings page.
4 *
5 * @link https://github.com/discourse/wp-discourse/blob/master/lib/settings-validator.php
6 * @package WPDiscourse
7 */
8
9 namespace WPDiscourse\Admin;
10
11 use WPDiscourse\Shared\PluginUtilities;
12
13 /**
14 * Class SettingsValidator
15 *
16 * @package WPDiscourse\Validator
17 */
18 class SettingsValidator {
19
20 use PluginUtilities;
21
22 /**
23 * Indicates whether or not the "discourse_sso_common['sso-secret']" option has been set.
24 *
25 * @access protected
26 * @var bool|void
27 */
28 protected $sso_secret_set;
29
30 /**
31 * Indicates whether or not the "discourse_sso_provider['enable-sso']" option is enabled.
32 *
33 * @access protected
34 * @var bool|void
35 */
36 protected $sso_provider_enabled;
37
38 /**
39 * Indicates whether or not the "discourse_sso_client['sso-client-enabled']" option is enabled.
40 *
41 * @access protected
42 * @var bool|void
43 */
44 protected $sso_client_enabled;
45
46 /**
47 * Indicates whether or not 'use_discourse_comments' is enabled.
48 *
49 * @access protected
50 * @var bool
51 */
52 protected $use_discourse_comments = false;
53
54 /**
55 * Indicates whether or not 'use_discourse_webhook' is enabled.
56 *
57 * @access protected
58 * @var bool
59 */
60 protected $use_discourse_webhook;
61
62 /**
63 * Indicates whether or not 'use_discourse_user_webhook' is enabled.
64 *
65 * @access protected
66 * @var bool
67 */
68 protected $use_discourse_user_webhook;
69
70 /**
71 * Gives access to the plugin options.
72 *
73 * @access protected
74 * @var array|void
75 */
76 protected $options;
77
78 /**
79 * SettingsValidator constructor.
80 *
81 * Adds the callback function for each of the validator filters that are applied
82 * in `admin.php`.
83 */
84 public function __construct() {
85 add_action( 'admin_init', array( $this, 'setup_options' ) );
86
87 add_filter( 'wpdc_validate_url', array( $this, 'validate_url' ) );
88 add_filter( 'wpdc_validate_api_key', array( $this, 'validate_api_key' ) );
89 add_filter( 'wpdc_validate_publish_username', array( $this, 'validate_publish_username' ) );
90 add_filter( 'wpdc_validate_connection_logs', array( $this, 'validate_checkbox' ) );
91
92 add_filter( 'wpdc_validate_publish_category', array( $this, 'validate_publish_category' ) );
93 add_filter( 'wpdc_validate_publish_category_update', array( $this, 'validate_checkbox' ) );
94 add_filter( 'wpdc_validate_allow_tags', array( $this, 'validate_checkbox' ) );
95 add_filter( 'wpdc_validate_max_tags', array( $this, 'validate_max_tags' ) );
96 add_filter( 'wpdc_validate_publish_as_unlisted', array( $this, 'validate_checkbox' ) );
97 add_filter( 'wpdc_validate_full_post_content', array( $this, 'validate_checkbox' ) );
98 add_filter( 'wpdc_validate_auto_publish', array( $this, 'validate_checkbox' ) );
99 add_filter( 'wpdc_validate_force_publish', array( $this, 'validate_checkbox' ) );
100 add_filter( 'wpdc_validate_force_publish_max_age', array( $this, 'validate_force_publish_max_age' ) );
101 add_filter( 'wpdc_validate_add_featured_link', array( $this, 'validate_checkbox' ) );
102 add_filter( 'wpdc_validate_auto_track', array( $this, 'validate_checkbox' ) );
103 add_filter( 'wpdc_validate_allowed_post_types', array( $this, 'validate_allowed_post_types' ) );
104 add_filter( 'wpdc_validate_exclude_tags', array( $this, 'validate_exclude_tags' ) );
105 add_filter( 'wpdc_validate_publish_failure_notice', array( $this, 'validate_checkbox' ) );
106 add_filter( 'wpdc_validate_publish_failure_email', array( $this, 'validate_email' ) );
107 add_filter( 'wpdc_validate_hide_discourse_name_field', array( $this, 'validate_checkbox' ) );
108 add_filter( 'wpdc_validate_discourse_username_editable', array( $this, 'validate_checkbox' ) );
109 add_filter( 'wpdc_validate_direct_db_publication_flags', array( $this, 'validate_checkbox' ) );
110 add_filter( 'wpdc_validate_verbose_publication_logs', array( $this, 'validate_checkbox' ) );
111
112 add_filter( 'wpdc_validate_enable_discourse_comments', array( $this, 'validate_checkbox' ) );
113 add_filter( 'wpdc_validate_comment_type', array( $this, 'validate_radio_string_value' ) );
114 add_filter( 'wpdc_validate_cache_html', array( $this, 'validate_checkbox' ) );
115 add_filter( 'wpdc_validate_clear_cached_comment_html', array( $this, 'validate_clear_comments_html' ) );
116 add_filter( 'wpdc_validate_ajax_load', array( $this, 'validate_checkbox' ) );
117 add_filter( 'wpdc_validate_load_comment_css', array( $this, 'validate_checkbox' ) );
118 add_filter( 'wpdc_validate_discourse_new_tab', array( $this, 'validate_checkbox' ) );
119 add_filter( 'wpdc_validate_hide_wordpress_comments', array( $this, 'validate_checkbox' ) );
120 add_filter( 'wpdc_validate_show_existing_comments', array( $this, 'validate_checkbox' ) );
121 add_filter( 'wpdc_validate_existing_comments_heading', array( $this, 'validate_existing_comments_heading' ) );
122 add_filter( 'wpdc_validate_max_comments', array( $this, 'validate_max_comments' ) );
123 add_filter( 'wpdc_validate_min_replies', array( $this, 'validate_min_replies' ) );
124 add_filter( 'wpdc_validate_min_score', array( $this, 'validate_min_score' ) );
125 add_filter( 'wpdc_validate_min_trust_level', array( $this, 'validate_min_trust_level' ) );
126 add_filter( 'wpdc_validate_bypass_trust_level_score', array( $this, 'validate_bypass_trust_level_score' ) );
127 add_filter( 'wpdc_validate_custom_excerpt_length', array( $this, 'validate_custom_excerpt_length' ) );
128 add_filter( 'wpdc_validate_custom_datetime_format', array( $this, 'validate_text_input' ) );
129 add_filter( 'wpdc_validate_only_show_moderator_liked', array( $this, 'validate_checkbox' ) );
130 add_filter( 'wpdc_validate_display_subcategories', array( $this, 'validate_checkbox' ) );
131 add_filter( 'wpdc_validate_verbose_comment_logs', array( $this, 'validate_checkbox' ) );
132
133 add_filter( 'wpdc_validate_discourse_link_text', array( $this, 'validate_text_input' ) );
134 add_filter( 'wpdc_validate_start_discussion_text', array( $this, 'validate_text_input' ) );
135 add_filter( 'wpdc_validate_continue_discussion_text', array( $this, 'validate_text_input' ) );
136 add_filter( 'wpdc_validate_join_discussion_text', array( $this, 'validate_text_input' ) );
137 add_filter( 'wpdc_validate_comments_singular_text', array( $this, 'validate_text_input' ) );
138 add_filter( 'wpdc_validate_comments_plural_text', array( $this, 'validate_text_input' ) );
139 add_filter( 'wpdc_validate_no_comments_text', array( $this, 'validate_text_input' ) );
140 add_filter( 'wpdc_validate_notable_replies_text', array( $this, 'validate_text_input' ) );
141 add_filter( 'wpdc_validate_comments_not_available_text', array( $this, 'validate_text_input' ) );
142 add_filter( 'wpdc_validate_participants_text', array( $this, 'validate_text_input' ) );
143 add_filter( 'wpdc_validate_published_at_text', array( $this, 'validate_text_input' ) );
144 add_filter( 'wpdc_validate_single_reply_text', array( $this, 'validate_text_input' ) );
145 add_filter( 'wpdc_validate_many_replies_text', array( $this, 'validate_text_input' ) );
146 add_filter( 'wpdc_validate_more_replies_more_text', array( $this, 'validate_text_input' ) );
147 add_filter( 'wpdc_validate_external_login_text', array( $this, 'validate_text_input' ) );
148 add_filter( 'wpdc_validate_link_to_discourse_text', array( $this, 'validate_text_input' ) );
149 add_filter( 'wpdc_validate_linked_to_discourse_text', array( $this, 'validate_text_input' ) );
150
151 add_filter( 'wpdc_validate_use_discourse_webhook', array( $this, 'validate_use_discourse_webhook' ) );
152 add_filter( 'wpdc_validate_webhook_match_old_topics', array( $this, 'validate_webhook_match_old_topics' ) );
153 add_filter( 'wpdc_validate_use_discourse_user_webhook', array( $this, 'validate_use_discourse_user_webhook' ) );
154 add_filter( 'wpdc_validate_webhook_match_user_email', array( $this, 'validate_checkbox' ) );
155 add_filter( 'wpdc_validate_webhook_secret', array( $this, 'validate_webhook_secret' ) );
156 add_filter( 'wpdc_validate_verbose_webhook_logs', array( $this, 'validate_checkbox' ) );
157
158 add_filter( 'wpdc_validate_sso_client_enabled', array( $this, 'validate_sso_client_enabled' ) );
159 add_filter( 'wpdc_validate_sso_client_login_form_change', array( $this, 'validate_checkbox' ) );
160 add_filter( 'wpdc_validate_sso_client_login_form_redirect', array( $this, 'validate_sso_client_login_form_redirect' ) );
161 add_filter( 'wpdc_validate_sso_client_sync_by_email', array( $this, 'validate_checkbox' ) );
162 add_filter( 'wpdc_validate_sso_client_sync_logout', array( $this, 'validate_checkbox' ) );
163
164 add_filter( 'wpdc_validate_enable_sso', array( $this, 'validate_enable_sso' ) );
165 add_filter( 'wpdc_validate_auto_create_sso_user', array( $this, 'validate_checkbox' ) );
166 add_filter( 'wpdc_validate_verbose_sso_logs', array( $this, 'validate_checkbox' ) );
167
168 add_filter( 'wpdc_validate_sso_secret', array( $this, 'validate_sso_secret' ) );
169 add_filter( 'wpdc_validate_login_path', array( $this, 'validate_login_path' ) );
170 add_filter( 'wpdc_validate_real_name_as_discourse_name', array( $this, 'validate_checkbox' ) );
171 add_filter( 'wpdc_validate_force_avatar_update', array( $this, 'validate_checkbox' ) );
172 add_filter( 'wpdc_validate_redirect_without_login', array( $this, 'validate_checkbox' ) );
173
174 add_filter( 'wpdc_validate_site_multisite_configuration_enabled', array( $this, 'validate_checkbox' ) );
175 add_filter( 'wpdc_validate_site_url', array( $this, 'validate_url' ) );
176 add_filter( 'wpdc_validate_site_api_key', array( $this, 'validate_api_key' ) );
177 add_filter( 'wpdc_validate_site_publish_username', array( $this, 'validate_publish_username' ) );
178 add_filter( 'wpdc_validate_site_use_discourse_webhook', array( $this, 'validate_use_discourse_webhook' ) );
179 add_filter( 'wpdc_validate_site_webhook_match_old_topics', array( $this, 'validate_checkbox' ) );
180 add_filter( 'wpdc_validate_site_webhook_secret', array( $this, 'validate_webhook_secret' ) );
181 add_filter( 'wpdc_validate_site_webhook_match_user_email', array( $this, 'validate_checkbox' ) );
182 add_filter( 'wpdc_validate_site_use_discourse_user_webhook', array( $this, 'validate_checkbox' ) );
183 add_filter( 'wpdc_validate_site_hide_discourse_name_field', array( $this, 'validate_checkbox' ) );
184 add_filter( 'wpdc_validate_site_sso_secret', array( $this, 'validate_sso_secret' ) );
185 add_filter( 'wpdc_validate_site_enable_sso', array( $this, 'validate_checkbox' ) );
186 add_filter( 'wpdc_validate_site_sso_client_enabled', array( $this, 'validate_checkbox' ) );
187 }
188
189 /**
190 * Setup options.
191 */
192 public function setup_options() {
193 $this->options = $this->get_options();
194
195 $this->sso_provider_enabled = ! empty( $this->options['enable-sso'] );
196 $this->sso_client_enabled = ! empty( $this->options['sso-client-enabled'] );
197 $this->sso_secret_set = ! empty( $this->options['sso-secret'] );
198 }
199
200 /**
201 * Validates the Discourse URL.
202 *
203 * @param string $input The input to be validated.
204 *
205 * @return string
206 */
207 public function validate_url( $input ) {
208 $regex = '/^(http:|https:)/';
209
210 // Make sure the url starts with a valid protocol.
211 if ( ! preg_match( $regex, $input ) ) {
212 add_settings_error( 'discourse', 'discourse_url', __( 'The Discourse URL needs to be set to a valid URL that begins with either \'http:\' or \'https:\'.', 'wp-discourse' ) );
213
214 $url = '';
215 } else {
216 $url = untrailingslashit( esc_url_raw( $input ) );
217
218 if ( ! filter_var( $url, FILTER_VALIDATE_URL ) ) {
219 add_settings_error( 'discourse', 'discourse_url', __( 'The Discourse URL you provided is not a valid URL.', 'wp-discourse' ) );
220
221 }
222 }
223
224 return $url;
225 }
226
227 /**
228 * Validates the api key.
229 *
230 * @param string $input The input to be validated.
231 *
232 * @return string
233 */
234 public function validate_api_key( $input ) {
235 $regex = '/^\s*([0-9]*[a-z]*|[a-z]*[0-9]*)*\s*$/';
236
237 if ( empty( $input ) ) {
238 add_settings_error( 'discourse', 'api_key', __( 'You must provide an API key.', 'wp-discourse' ) );
239
240 $api_key = '';
241 } else {
242 $api_key = trim( $input );
243
244 if ( ! preg_match( $regex, $input ) ) {
245 add_settings_error( 'discourse', 'api_key', __( 'The API key you provided is not valid.', 'wp-discourse' ) );
246 }
247 }
248
249 return $api_key;
250 }
251
252 /**
253 * Validates the publish_username.
254 *
255 * @param string $input The input to be validated.
256 *
257 * @return string
258 */
259 public function validate_publish_username( $input ) {
260 if ( ! empty( $input ) ) {
261 $publish_username = $this->sanitize_text( $input );
262 } else {
263 add_settings_error( 'discourse', 'publish_username', __( 'You need to provide a Discourse username.', 'wp-discourse' ) );
264
265 $publish_username = '';
266 }
267
268 return $publish_username;
269 }
270
271 /**
272 * Validates the 'publish_category' select input.
273 *
274 * Returns the category id.
275 *
276 * @param string $input The input to be validated.
277 *
278 * @return string
279 */
280 public function validate_publish_category( $input ) {
281 return $this->sanitize_int( $input );
282 }
283
284 /**
285 * Validates the 'allowed_post_types' multi-select.
286 *
287 * @param array $input The array of allowed post-types.
288 *
289 * @return array
290 */
291 public function validate_allowed_post_types( $input ) {
292 $output = array();
293 foreach ( $input as $post_type ) {
294 $output[] = sanitize_text_field( $post_type );
295 }
296
297 return $output;
298 }
299
300 /**
301 * Validates the 'exclude_tags' input.
302 *
303 * @param mixed $input The excluded tags.
304 *
305 * @return array
306 */
307 public function validate_exclude_tags( $input ) {
308 $output = array();
309
310 if ( is_string( $input ) ) {
311 $input = explode( ',', $input );
312 }
313
314 foreach ( $input as $tag_slug ) {
315 $tag_slug = trim( $tag_slug );
316
317 if ( '' == $tag_slug ) {
318 continue;
319 }
320
321 if ( term_exists( $tag_slug, 'post_tag' ) ) {
322 $output[] = sanitize_text_field( $tag_slug );
323 } else {
324 add_settings_error(
325 'discourse_exclude_tags',
326 'tag-does-not-exist',
327 "Exclude Posts By Tag: '$tag_slug' is not a valid tag.",
328 'warning'
329 );
330 }
331 }
332
333 return array_unique( $output );
334 }
335
336 /**
337 * Validates the 'clear_cached_comment_html input.
338 *
339 * @param string $input The input to be validated.
340 *
341 * @return int
342 */
343 public function validate_clear_comments_html( $input ) {
344 if ( 1 === intval( $input ) ) {
345 $this->clear_cached_html();
346 }
347
348 return 0;
349 }
350
351 /**
352 * Validates the 'existing_comments_heading' input.
353 *
354 * @param string $input The input to be validated.
355 *
356 * @return string
357 */
358 public function validate_existing_comments_heading( $input ) {
359 return $this->sanitize_html( $input );
360 }
361
362 /**
363 * Validates the 'max_comments' number input.
364 *
365 * @param int $input The input to be validated.
366 *
367 * @return mixed
368 */
369 public function validate_max_comments( $input ) {
370 return $this->validate_int(
371 $input,
372 'max_comments',
373 0,
374 null,
375 __( 'The max visible comments must be set to at least 0.', 'wp-discourse' ),
376 $this->use_discourse_comments
377 );
378 }
379
380 /**
381 * Validates the 'min_replies' number input.
382 *
383 * @param int $input The input to be validated.
384 *
385 * @return mixed
386 */
387 public function validate_min_replies( $input ) {
388 return $this->validate_int(
389 $input,
390 'min_replies',
391 0,
392 null,
393 __( 'The min number of replies setting requires a number greater than or equal to 0.', 'wp-discourse' ),
394 $this->use_discourse_comments
395 );
396 }
397
398 /**
399 * Validates the 'min_score' number input.
400 *
401 * @param int $input The input to be validated.
402 *
403 * @return mixed
404 */
405 public function validate_min_score( $input ) {
406 return $this->validate_int(
407 $input,
408 'min_score',
409 0,
410 null,
411 __( 'The min score of posts setting requires a number greater than or equal to 0.', 'wp-discourse' ),
412 $this->use_discourse_comments
413 );
414 }
415
416 /**
417 * Validates the 'min_trust_level' number input.
418 *
419 * @param int $input The input to be validated.
420 *
421 * @return mixed
422 */
423 public function validate_min_trust_level( $input ) {
424 return $this->validate_int(
425 $input,
426 'min_trust_level',
427 0,
428 5,
429 __( 'The trust level setting requires a number between 0 and 5.', 'wp-discourse' ),
430 $this->use_discourse_comments
431 );
432 }
433
434 /**
435 * Validates the 'bypass_trust_level_score' number input.
436 *
437 * @param int $input The input to be validated.
438 *
439 * @return mixed
440 */
441 public function validate_bypass_trust_level_score( $input ) {
442 return $this->validate_int(
443 $input,
444 'bypass_trust_level',
445 0,
446 null,
447 __( 'The bypass trust level score setting requires an integer greater than or equal to 0.', 'wp-discourse' ),
448 $this->use_discourse_comments
449 );
450 }
451
452 /**
453 * Validates the 'custom_excerpt_length' number input.
454 *
455 * @param int $input The input to be validated.
456 *
457 * @return mixed
458 */
459 public function validate_custom_excerpt_length( $input ) {
460
461 return $this->validate_int(
462 $input,
463 'excerpt_length',
464 0,
465 null,
466 __( 'The custom excerpt length setting requires a positive integer.', 'wp-discourse' ),
467 true
468 );
469 }
470
471 /**
472 * Validates the 'max_tags' input.
473 *
474 * @param int $input The input to be validated.
475 *
476 * @return mixed
477 */
478 public function validate_max_tags( $input ) {
479 return $this->validate_int( $input );
480 }
481
482 /**
483 * Validates use_discourse_webhook.
484 *
485 * @param string $input The input to be validated.
486 *
487 * @return bool|int
488 */
489 public function validate_use_discourse_webhook( $input ) {
490 $this->use_discourse_webhook = $this->validate_checkbox( $input );
491
492 return $this->use_discourse_webhook;
493 }
494
495 /**
496 * Validates user_discourse_user_webhook.
497 *
498 * @param string $input The input to be validated.
499 *
500 * @return bool|int
501 */
502 public function validate_use_discourse_user_webhook( $input ) {
503 $this->use_discourse_user_webhook = $this->validate_checkbox( $input );
504
505 return $this->use_discourse_user_webhook;
506 }
507
508 /**
509 * Validates the webhook_secret input.
510 *
511 * @param string $input The input to be validated.
512 *
513 * @return string
514 */
515 public function validate_webhook_secret( $input ) {
516 if ( ( $this->use_discourse_webhook || $this->use_discourse_user_webhook ) && strlen( $input ) < 12 ) {
517 add_settings_error( 'discourse', 'webhook_secret', __( 'To use a Discourse webhook, the secret must be set to a value at least 12 characters long.', 'wp-discourse' ) );
518
519 return '';
520 }
521
522 return $input;
523 }
524
525 /**
526 * Validates the webhook_match_old_topics input.
527 *
528 * @param string $input The input to be validated.
529 *
530 * @return int
531 */
532 public function validate_webhook_match_old_topics( $input ) {
533 $match_old_topics = $this->validate_checkbox( $input );
534
535 return $match_old_topics;
536 }
537
538 /**
539 * Validates the 'enable_sso'checkbox.
540 *
541 * @param string $input The input to be validated.
542 *
543 * @return int
544 */
545 public function validate_enable_sso( $input ) {
546 $new_value = $this->sanitize_checkbox( $input );
547
548 if ( 1 === $new_value && $this->sso_client_enabled ) {
549 add_settings_error(
550 'discourse',
551 'sso_client_enabled',
552 __(
553 "You have the 'DiscourseConnect Client' option enabled. Visit the 'DiscourseConnect Client' settings tab
554 to disable it before enabling your site to function as the DiscourseConnect provider.",
555 'wp-discourse'
556 )
557 );
558
559 return 0;
560 }
561
562 if ( 1 === $new_value && ! $this->sso_secret_set ) {
563 add_settings_error(
564 'discourse',
565 'sso_provider_no_secret',
566 __(
567 'Before enabling your site to function as the DiscourseConnect provider,
568 you need to set the DiscourseConnect Secret Key.',
569 'wp-discourse'
570 )
571 );
572
573 return 0;
574 }
575
576 // When the SSO Provider option is updated, clear the comment cache to update links to Discourse.
577 $this->clear_cached_html();
578
579 return $new_value;
580 }
581
582 /**
583 * Validates the 'sso_client_enabled' checkbox.
584 *
585 * @param string $input The input to be validated.
586 *
587 * @return int
588 */
589 public function validate_sso_client_enabled( $input ) {
590 $new_value = $this->sanitize_checkbox( $input );
591
592 if ( 1 === $new_value && $this->sso_provider_enabled ) {
593 add_settings_error(
594 'discourse',
595 'sso_provider_enabled',
596 __(
597 "You have the 'DiscourseConnect Provider' option enabled. Click on the 'DiscourseConnect Provider' settings tab
598 to disable it before enabling your site to function as a DiscourseConnect client.",
599 'wp-discourse'
600 )
601 );
602
603 return 0;
604 }
605
606 if ( 1 === $new_value && ! $this->sso_secret_set ) {
607 add_settings_error(
608 'discourse',
609 'sso_client_no_secret',
610 __(
611 'Before enabling your site to function as a DiscourseConnect client,
612 you need to set the DiscourseConnect Secret Key.',
613 'wp-discourse'
614 )
615 );
616
617 return 0;
618 }
619
620 return $this->sanitize_checkbox( $input );
621 }
622
623 /**
624 * Validates the sso_client_login_form_redirect redirect text input.
625 *
626 * @param string $input The input to be validated.
627 *
628 * @return string
629 */
630 public function validate_sso_client_login_form_redirect( $input ) {
631 if ( empty( $input ) ) {
632
633 return '';
634 }
635 $regex = '/^(http:|https:)/';
636
637 // Make sure the url starts with a valid protocol.
638 if ( ! preg_match( $regex, $input ) ) {
639 add_settings_error( 'discourse', 'sso_client_login_redirect', __( 'The redirect URL needs to be set to a valid URL that begins with either \'http:\' or \'https:\'.', 'wp-discourse' ) );
640
641 $url = '';
642 } else {
643 $url = untrailingslashit( esc_url_raw( $input ) );
644
645 if ( ! filter_var( $url, FILTER_VALIDATE_URL ) ) {
646 add_settings_error( 'discourse', 'sso_client_login_redirect', __( 'The redirect URL you provided is not a valid URL.', 'wp-discourse' ) );
647 }
648 }
649
650 return $url;
651 }
652
653 /**
654 * Validates the 'sso_secret' text input.
655 *
656 * @param string $input The input to be validated.
657 *
658 * @return string
659 */
660 public function validate_sso_secret( $input ) {
661 $secret = trim( $input );
662 if ( strlen( $secret ) < 10 ) {
663 add_settings_error( 'discourse', 'sso_secret', __( 'The DiscourseConnect secret key must be at least 10 characters long.', 'wp-discourse' ) );
664
665 return '';
666 }
667
668 return $secret;
669 }
670
671 /**
672 * Validates the 'login_path' text input.
673 *
674 * @param string $input The input to be validated.
675 *
676 * @return string
677 */
678 public function validate_login_path( $input ) {
679 if ( $this->sso_provider_enabled && $input ) {
680
681 $regex = '/^\//';
682 if ( ! preg_match( $regex, $input ) ) {
683 add_settings_error( 'discourse', 'login_path', __( 'The path to login page setting needs to be a valid file path, starting with \'/\'.', 'wp-discourse' ) );
684 }
685
686 // It's valid.
687 return $this->sanitize_text( $input );
688 }
689
690 // Sanitize, but don't validate. SSO is not enabled.
691 return $this->sanitize_text( $input );
692 }
693
694 /**
695 * Validates the 'auto-create-login-redirect' field.
696 *
697 * @param string $input The input to be validated.
698 *
699 * @return string
700 */
701 public function validate_auto_create_login_redirect( $input ) {
702 if ( $this->sso_provider_enabled && $input ) {
703
704 $regex = '/^\//';
705 if ( ! preg_match( $regex, $input ) ) {
706 add_settings_error( 'discourse', 'auto_create_login_redirect', __( 'The path to the login redirect page setting needs to be a valid file path, starting with \'/\'.', 'wp-discourse' ) );
707 }
708
709 // It's valid.
710 return $this->sanitize_text( $input );
711 }
712
713 // Sanitize, but don't validate. SSO is not enabled.
714 return $this->sanitize_text( $input );
715 }
716
717 /**
718 * Validates the 'auto-create-welcome-redirect' field.
719 *
720 * @param string $input The input to be validated.
721 *
722 * @return string
723 */
724 public function validate_auto_create_welcome_redirect( $input ) {
725 if ( $this->sso_provider_enabled && $input ) {
726
727 $regex = '/^\//';
728 if ( ! preg_match( $regex, $input ) ) {
729 add_settings_error( 'discourse', 'auto_create_welcome_redirect', __( 'The path to the welcome page setting needs to be a valid file path, starting with \'/\'.', 'wp-discourse' ) );
730 }
731
732 // It's valid.
733 return $this->sanitize_text( $input );
734 }
735
736 // Sanitize, but don't validate. SSO is not enabled.
737 return $this->sanitize_text( $input );
738 }
739
740 /**
741 * Validates the `force-publish-max-age` input.
742 *
743 * @param string $input The input to be validated.
744 *
745 * @return int
746 */
747 public function validate_force_publish_max_age( $input ) {
748 return $this->sanitize_int( $input );
749 }
750
751 /**
752 * Validate a checkbox input.
753 *
754 * @param string $input The input to be validated.
755 *
756 * @return int
757 */
758 public function validate_checkbox( $input ) {
759 return $this->sanitize_checkbox( $input );
760 }
761
762 /**
763 * Validate a radio input that returns a string.
764 *
765 * @param string $input The input to be validated.
766 *
767 * @return string
768 */
769 public function validate_radio_string_value( $input ) {
770 return $this->validate_text_input( $input );
771 }
772
773 /**
774 * Validate a text input.
775 *
776 * @param string $input The input to be validated.
777 *
778 * @return string
779 */
780 public function validate_text_input( $input ) {
781 if ( ! empty( $input ) ) {
782 return $this->sanitize_text( $input );
783 } else {
784 return '';
785 }
786 }
787
788 /**
789 * Validates an email input.
790 *
791 * @param string $input The input to be validated.
792 *
793 * @return string
794 */
795 public function validate_email( $input ) {
796 if ( ! empty( $input ) ) {
797
798 return sanitize_email( $input );
799 } else {
800
801 return '';
802 }
803 }
804
805 /**
806 * Helper methods
807 ******************************/
808
809 /**
810 * A helper method to sanitize text inputs.
811 *
812 * @param string $input The input to be sanitized.
813 *
814 * @return string
815 */
816 protected function sanitize_text( $input ) {
817 return sanitize_text_field( $input );
818 }
819
820 /**
821 * A helper method to sanitize the value returned from checkbox inputs.
822 *
823 * @param string $input The value returned from the checkbox.
824 *
825 * @return int
826 */
827 protected function sanitize_checkbox( $input ) {
828 return 1 === intval( $input ) ? 1 : 0;
829 }
830
831 /**
832 * A helper function to sanitize HTML.
833 *
834 * @param string $input HTML input to be sanitized.
835 *
836 * @return string
837 */
838 protected function sanitize_html( $input ) {
839 return wp_kses_post( $input );
840 }
841
842 /**
843 * A helper function to sanitize an int.
844 *
845 * @param mixed|int $input The input to be validated.
846 *
847 * @return int
848 */
849 protected function sanitize_int( $input ) {
850 return intval( $input );
851 }
852
853 /**
854 * A helper function to validate and sanitize integers.
855 *
856 * @param int $input The input to be validated.
857 * @param string $option_id The option being validated.
858 * @param null $min The minimum allowed value.
859 * @param null $max The maximum allowed value.
860 * @param string $error_message The error message to return.
861 * @param bool $add_error Whether or not to add a setting error.
862 *
863 * @return mixed
864 */
865 protected function validate_int( $input, $option_id = null, $min = null, $max = null, $error_message = '', $add_error = false ) {
866 $options = array();
867
868 if ( isset( $min ) ) {
869 $options['min_range'] = $min;
870 }
871 if ( isset( $max ) ) {
872 $options['max_range'] = $max;
873 }
874
875 $input = filter_var(
876 $input,
877 FILTER_VALIDATE_INT,
878 array(
879 'options' => $options,
880 )
881 );
882
883 if ( false === $input ) {
884 if ( $add_error ) {
885 add_settings_error( 'discourse', $option_id, $error_message );
886 }
887
888 // The input is not valid, but the setting's section is not being used, sanitize the input and return it.
889 return null;
890 } else {
891 // Valid input.
892 return $input;
893 }
894 }
895
896 /**
897 * Clears all cached comment HTML.
898 */
899 protected function clear_cached_html() {
900 $transient_keys = get_option( 'wpdc_cached_html_keys' );
901 if ( ! empty( $transient_keys ) ) {
902 foreach ( $transient_keys as $transient_key ) {
903 delete_transient( $transient_key );
904 }
905 }
906 }
907 }
908