| @@ -10,8 +10,46 @@ | ||
| 10 | 10 | if ( ! defined( 'ABSPATH' ) ) { |
| 11 | 11 | exit; |
| 12 | 12 | } |
| 13 | 13 | |
| 14 | +add_action( 'admin_notices', __NAMESPACE__ . '\\frontend_url_notice' ); | |
| 15 | +/** | |
| 16 | + * Callback for WordPress 'admin_notices' action. | |
| 17 | + * | |
| 18 | + * Show frontend_url missing error if it doesn't exist. | |
| 19 | + * | |
| 20 | + * @return void | |
| 21 | + */ | |
| 22 | +function frontend_url_notice() { | |
| 23 | + $screen = get_current_screen(); | |
| 24 | + | |
| 25 | + // Exit if not this plugin's settings page. | |
| 26 | + if ( 'settings_page_faustwp-settings' !== $screen->id ) { | |
| 27 | + return; | |
| 28 | + } | |
| 29 | + | |
| 30 | + $frontend_url_setting = faustwp_get_setting( 'frontend_uri' ); | |
| 31 | + | |
| 32 | + if ( empty( $frontend_url_setting ) ) { | |
| 33 | + ?> | |
| 34 | + <div class="notice notice-error is-dismissible" style="background-color: #FFEAE9;"> | |
| 35 | + <p><?php esc_html_e( 'Front-end site URL is required to utilize url rewrites and previews.', 'faustwp' ); ?></p> | |
| 36 | + <p><?php esc_html_e( 'It is highly recommended that you update it below to avoid unexpected behavior.', 'faustwp' ); ?></p> | |
| 37 | + <p> | |
| 38 | + <?php | |
| 39 | + printf( | |
| 40 | + /* translators: Link text */ | |
| 41 | + esc_html__( 'See the %1$s Getting Started Documentation%2$s for more details.', 'faustwp' ), | |
| 42 | + '<a href="https://faustjs.org/docs/getting-started" target="_blank" rel="noopener noreferrer">', | |
| 43 | + '</a>' | |
| 44 | + ); | |
| 45 | + ?> | |
| 46 | + </p> | |
| 47 | + </div> | |
| 48 | + <?php | |
| 49 | + } | |
| 50 | +} | |
| 51 | + | |
| 14 | 52 | add_action( 'admin_menu', __NAMESPACE__ . '\\register_settings_menu' ); |
| 15 | 53 | /** |
| 16 | 54 | * Callback for WordPress 'admin_menu' action. |
| 17 | 55 | * |
| @@ -24,10 +62,10 @@ | ||
| 24 | 62 | */ |
| 25 | 63 | function register_settings_menu() { |
| 26 | 64 | add_submenu_page( |
| 27 | 65 | 'options-general.php', |
| 28 | - __( 'Headless', 'faustwp' ), | |
| 29 | - __( 'Headless', 'faustwp' ), | |
| 66 | + __( 'Faust', 'faustwp' ), | |
| 67 | + __( 'Faust', 'faustwp' ), | |
| 30 | 68 | 'manage_options', |
| 31 | 69 | 'faustwp-settings', |
| 32 | 70 | __NAMESPACE__ . '\\display_settings_page' |
| 33 | 71 | ); |
| @@ -124,8 +162,74 @@ | ||
| 124 | 162 | 'settings_section' |
| 125 | 163 | ); |
| 126 | 164 | } |
| 127 | 165 | |
| 166 | +add_filter( 'sanitize_option_faustwp_settings', __NAMESPACE__ . '\\sanitize_faustwp_settings', 10, 2 ); | |
| 167 | +/** | |
| 168 | + * Validates and sanitizes Faust settings. | |
| 169 | + * | |
| 170 | + * The plugin settings page will display any relevant errors when | |
| 171 | + * rejecting invalid settings values. Updates to Faust settings that | |
| 172 | + * are not initiated from the plugin settings page will not return or | |
| 173 | + * display errors, but will still reject invalid values. | |
| 174 | + * | |
| 175 | + * Once settings are validated, the sanitized values are returned. | |
| 176 | + * | |
| 177 | + * @param array $settings Faust settings array to validate and sanitize. | |
| 178 | + * @param string $option WP option name where settings are saved. | |
| 179 | + * @return array Sanitized settings. | |
| 180 | + */ | |
| 181 | +function sanitize_faustwp_settings( $settings, $option ) { | |
| 182 | + $errors = null; | |
| 183 | + $protocols = array( 'http', 'https' ); | |
| 184 | + foreach ( $settings as $name => $value ) { | |
| 185 | + switch ( $name ) { | |
| 186 | + case 'frontend_uri': | |
| 187 | + if ( '' === $value || preg_match( '#http(s?)://(.+)#i', $value ) ) { | |
| 188 | + $settings[ $name ] = esc_url_raw( $value, $protocols ); | |
| 189 | + } else { | |
| 190 | + $errors[ $name ] = __( 'The Front-end site URL you entered did not appear to be a valid URL. Please enter a valid URL.', 'faustwp' ); | |
| 191 | + $settings[ $name ] = faustwp_get_setting( $name ); | |
| 192 | + } | |
| 193 | + break; | |
| 194 | + | |
| 195 | + case 'secret_key': | |
| 196 | + if ( ! wp_is_uuid( $value, 4 ) ) { | |
| 197 | + $errors[ $name ] = __( 'The secret key you entered did not appear to be a valid UUID.', 'faustwp' ); | |
| 198 | + $settings[ $name ] = get_secret_key(); | |
| 199 | + } | |
| 200 | + break; | |
| 201 | + | |
| 202 | + case 'menu_locations': | |
| 203 | + $settings[ $name ] = sanitize_text_field( $value ); | |
| 204 | + break; | |
| 205 | + | |
| 206 | + case 'enable_redirects': | |
| 207 | + case 'enable_rewrites': | |
| 208 | + case 'disable_theme': | |
| 209 | + case 'enable_image_source': | |
| 210 | + if ( $value ) { | |
| 211 | + $settings[ $name ] = '1'; | |
| 212 | + } else { | |
| 213 | + unset( $settings[ $name ] ); | |
| 214 | + } | |
| 215 | + break; | |
| 216 | + | |
| 217 | + default: | |
| 218 | + // Remove any settings we don't expect. | |
| 219 | + unset( $settings[ $name ] ); | |
| 220 | + } | |
| 221 | + } | |
| 222 | + | |
| 223 | + if ( null !== $errors && is_array( $errors ) ) { | |
| 224 | + foreach ( $errors as $name => $error ) { | |
| 225 | + add_settings_error( $option, "faustwp_invalid_{$name}", $error ); | |
| 226 | + } | |
| 227 | + } | |
| 228 | + | |
| 229 | + return $settings; | |
| 230 | +} | |
| 231 | + | |
| 128 | 232 | add_action( 'load-settings_page_faustwp-settings', __NAMESPACE__ . '\\handle_regenerate_secret_key', 5 ); |
| 129 | 233 | /** |
| 130 | 234 | * Callback for WordPress 'load-{$page_hook}' action. |
| 131 | 235 | * |
| @@ -252,9 +356,9 @@ | ||
| 252 | 356 | |
| 253 | 357 | ?> |
| 254 | 358 | <input type="text" id="frontend_uri" name="faustwp_settings[frontend_uri]" value="<?php echo esc_attr( $frontend_uri ); ?>" class="regular-text" /> |
| 255 | 359 | <p class="description"> |
| 256 | - <?php esc_html_e( 'The URL to your headless front-end. This is used for authenticated post previews and for rewriting links to point to your front-end site.', 'faustwp' ); ?> | |
| 360 | + <?php esc_html_e( 'The full URL to your headless front-end, including https:// or http://. This is used for authenticated post previews and for rewriting links to point to your front-end site.', 'faustwp' ); ?> | |
| 257 | 361 | </p> |
| 258 | 362 | <?php |
| 259 | 363 | } |
| 260 | 364 | |
| @@ -272,8 +376,19 @@ | ||
| 272 | 376 | $enable_image_source = is_image_source_replacement_enabled(); |
| 273 | 377 | |
| 274 | 378 | ?> |
| 275 | 379 | <fieldset> |
| 380 | + <legend style="margin-bottom:5px;padding:0;"> | |
| 381 | + <p class="description"> | |
| 382 | + <?php | |
| 383 | + printf( | |
| 384 | + /* translators: %s: Documentation URL. */ | |
| 385 | + wp_kses_post( __( 'Learn more about <a href="%s" target="_blank" rel="noopener noreferrer">features</a>.', 'faustwp' ) ), | |
| 386 | + 'https://faustjs.org/docs/faustwp/settings' | |
| 387 | + ); | |
| 388 | + ?> | |
| 389 | + </p> | |
| 390 | + </legend> | |
| 276 | 391 | <label for="disable_theme"> |
| 277 | 392 | <input type="checkbox" id="disable_theme" name="faustwp_settings[disable_theme]" value="1" <?php checked( $disable_theme ); ?> /> |
| 278 | 393 | <?php esc_html_e( 'Disable WordPress theme admin pages', 'faustwp' ); ?> |
| 279 | 394 | </label> |
| @@ -337,8 +452,11 @@ | ||
| 337 | 452 | ); |
| 338 | 453 | |
| 339 | 454 | $faustwp = array( |
| 340 | 455 | 'wpgraphqlIsInstalled' => array_key_exists( 'wp-graphql/wp-graphql.php', get_plugins() ), |
| 456 | + 'icons' => array( | |
| 457 | + 'checkSmall' => get_icon( 'check-small' ), | |
| 458 | + ), | |
| 341 | 459 | 'strings' => array( |
| 342 | 460 | 'default' => esc_html__( 'Install and Activate', 'faustwp' ), |
| 343 | 461 | 'installing' => esc_html__( 'Installing…', 'faustwp' ), |
| 344 | 462 | 'active' => esc_html__( 'WPGraphQL is active', 'faustwp' ), |
| @@ -367,5 +485,22 @@ | ||
| 367 | 485 | '<a href="' . esc_url( $url ) . '">' . esc_html__( 'Settings', 'faustwp' ) . '</a>', |
| 368 | 486 | ), |
| 369 | 487 | $links |
| 370 | 488 | ); |
| 489 | +} | |
| 490 | + | |
| 491 | +add_filter( 'faustwp_get_setting', __NAMESPACE__ . '\\trim_frontend_uri_trailing_slash', 10, 2 ); | |
| 492 | +/** | |
| 493 | + * Ensure that this plugin's frontend_uri setting does not have a trailing slash. | |
| 494 | + * | |
| 495 | + * @param mixed $value The setting value. | |
| 496 | + * @param string $name The setting name. | |
| 497 | + * | |
| 498 | + * @return string | |
| 499 | + */ | |
| 500 | +function trim_frontend_uri_trailing_slash( $value, $name ) { | |
| 501 | + if ( 'frontend_uri' !== $name ) { | |
| 502 | + return $value; | |
| 503 | + } | |
| 504 | + | |
| 505 | + return untrailingslashit( $value ); | |
| 371 | 506 | } |