diff --git a/src/wp-admin/options-permalink.php b/src/wp-admin/options-permalink.php index 6fab4d2143..78b8d49dde 100644 --- a/src/wp-admin/options-permalink.php +++ b/src/wp-admin/options-permalink.php @@ -82,6 +82,9 @@ if ( isset($_POST['permalink_structure']) || isset($_POST['category_base']) ) { else $permalink_structure = $blog_prefix . $permalink_structure; } + + $permalink_structure = sanitize_option( 'permalink_structure', $permalink_structure ); + $wp_rewrite->set_permalink_structure( $permalink_structure ); } @@ -99,6 +102,24 @@ if ( isset($_POST['permalink_structure']) || isset($_POST['category_base']) ) { $wp_rewrite->set_tag_base( $tag_base ); } + $message = __( 'Permalink structure updated.' ); + + if ( $iis7_permalinks ) { + if ( $permalink_structure && ! $usingpi && ! $writable ) { + $message = __( 'You should update your web.config now.' ); + } elseif ( $permalink_structure && ! $usingpi && $writable ) { + $message = __( 'Permalink structure updated. Remove write access on web.config file now!' ); + } + } elseif ( ! $is_nginx && $permalink_structure && ! $usingpi && ! $writable && $update_required ) { + $message = __( 'You should update your .htaccess now.' ); + } + + if ( ! get_settings_errors() ) { + add_settings_error( 'general', 'settings_updated', $message, 'updated' ); + } + + set_transient( 'settings_errors', get_settings_errors(), 30 ); + wp_redirect( admin_url( 'options-permalink.php?settings-updated=true' ) ); exit; } @@ -125,42 +146,12 @@ if ( $iis7_permalinks ) { } } -if ( $wp_rewrite->using_index_permalinks() ) - $usingpi = true; -else - $usingpi = false; +$usingpi = $wp_rewrite->using_index_permalinks(); flush_rewrite_rules(); require( ABSPATH . 'wp-admin/admin-header.php' ); - -if ( ! empty( $_GET['settings-updated'] ) ) : ?> -

-

- -

diff --git a/src/wp-includes/formatting.php b/src/wp-includes/formatting.php index 4f632eef9a..46d9a9068a 100644 --- a/src/wp-includes/formatting.php +++ b/src/wp-includes/formatting.php @@ -4204,6 +4204,14 @@ function sanitize_option( $option, $value ) { $value = esc_url_raw( $value ); $value = str_replace( 'http://', '', $value ); } + + if ( 'permalink_structure' === $option && '' !== $value && ! preg_match( '/%[^\/%]+%/', $value ) ) { + $error = sprintf( + /* translators: %s: Codex URL */ + __( 'A structure tag is required when using custom permalinks. Learn more' ), + __( 'https://codex.wordpress.org/Using_Permalinks#Choosing_your_permalink_structure' ) + ); + } break; case 'default_role' : diff --git a/tests/phpunit/tests/option/sanitize-option.php b/tests/phpunit/tests/option/sanitize-option.php index 8efa985b00..bb4a814c54 100644 --- a/tests/phpunit/tests/option/sanitize-option.php +++ b/tests/phpunit/tests/option/sanitize-option.php @@ -119,4 +119,42 @@ class Tests_Sanitize_Option extends WP_UnitTestCase { $this->assertSame( $expected, sanitize_option( 'blogname', $value ) ); $this->assertSame( $expected, sanitize_option( 'blogdescription', $value ) ); } + + /** + * @dataProvider permalink_structure_provider + */ + public function test_sanitize_permalink_structure( $provided, $expected, $valid ) { + global $wp_settings_errors; + + $old_wp_settings_errors = (array) $wp_settings_errors; + + $actual = sanitize_option( 'permalink_structure', $provided); + $errors = get_settings_errors( 'permalink_structure' ); + + // Clear errors. + $wp_settings_errors = $old_wp_settings_errors; + + if ( $valid ) { + $this->assertEmpty( $errors ); + } else { + $this->assertNotEmpty( $errors ); + $this->assertEquals( 'invalid_permalink_structure', $errors[0]['code'] ); + } + + $this->assertEquals( $expected, $actual ); + } + + public function permalink_structure_provider() { + return array( + array( '', '', true ), + array( '%postname', false, false ), + array( '%/%', false, false ), + array( '%%%', false, false ), + array( '%a%', '%a%', true ), + array( '%postname%', '%postname%', true ), + array( '/%postname%/', '/%postname%/', true ), + array( '/%year%/%monthnum%/%day%/%postname%/', '/%year%/%monthnum%/%day%/%postname%/', true ), + array( '/%year/%postname%/', '/%year/%postname%/', true ), + ); + } }