Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -687,10 +687,11 @@ function validate_title( $prepared_post, $request ) {
);
}

if ( ! is_title_valid( $title ) ) {
$title_error = get_title_error( $title );
if ( $title_error ) {
return new \WP_Error(
'rest_pattern_invalid_title',
__( 'Pattern title is invalid. The pattern title should describe the pattern.', 'wporg-patterns' ),
$title_error,
array( 'status' => 400 )
);
}
Expand Down Expand Up @@ -1120,33 +1121,33 @@ function check_for_spam( $post ) {
}

/**
* Helper function to check for a valid pattern title.
* Explain why a pattern title is invalid, so the author knows what to change.
*
* @param string $title Pattern title.
* @return boolean
* @return string The reason the title is invalid, or an empty string if it's valid.
*/
function is_title_valid( $title ) {
function get_title_error( $title ) {
if ( strip_shortcodes( $title ) !== $title || wp_strip_all_tags( $title ) !== $title ) {
return false;
return __( 'Pattern titles cannot contain HTML or shortcodes.', 'wporg-patterns' );
}

if ( content_has_block_directives( $title ) ) {
return false;
return __( 'Pattern titles cannot contain interactivity directives.', 'wporg-patterns' );
}

// Check title against a list of disallowed words.
// Note the space after `test ` to avoid matching "testimonial".
$disallow_list = array( 'test ', 'testing', 'my pattern', 'wordpress', 'example' );

if ( 'test' === strtolower( $title ) ) {
return false;
}
// Whole words only, so "Latest Posts" and "Testimonial" are fine.
$disallow_list = array( 'test', 'testing', 'my pattern', 'my patterns', 'wordpress', 'example' );

foreach ( $disallow_list as $disallowed ) {
if ( false !== stripos( $title, $disallowed ) ) {
return false;
$pattern = '/\b' . str_replace( ' ', '\s+', preg_quote( $disallowed, '/' ) ) . '\b/iu';
if ( preg_match( $pattern, $title, $matches ) ) {
return sprintf(
/* translators: %s: The word from the title that isn't allowed, e.g. "test". */
__( 'Pattern titles cannot include "%s". The title should describe the pattern.', 'wporg-patterns' ),
$matches[0]
);
}
}

return true;
return '';
}
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,16 @@ public function data_valid_title() {
array(
array_merge( $defaults, array( 'title' => 'Testimonial' ) ),
),
// Disallowed words inside other words.
array(
array_merge( $defaults, array( 'title' => 'Latest Posts' ) ),
),
array(
array_merge( $defaults, array( 'title' => 'Contest Banner' ) ),
),
array(
array_merge( $defaults, array( 'title' => 'Examples Grid' ) ),
),
array(
array(
'title' => '',
Expand Down Expand Up @@ -178,6 +188,49 @@ public function data_invalid_title() {
);
}

/**
* Test that the error says why the title is invalid.
*
* @dataProvider data_invalid_title_message
*
* @param string $title Submitted title.
* @param string $expected_message Expected error message.
*/
public function test_invalid_title_message( $title, $expected_message ) {
wp_set_current_user( self::$user );

$request = new WP_REST_Request( 'POST', '/wp/v2/wporg-pattern/' . self::$pattern_id );
$request->set_header( 'content-type', 'application/json' );
$request->set_body(
wp_json_encode(
array(
'title' => $title,
'status' => 'publish',
'content' => self::$valid_content,
)
)
);

$data = rest_do_request( $request )->get_data();
$this->assertSame( 'rest_pattern_invalid_title', $data['code'] );
$this->assertSame( $expected_message, $data['message'] );
}

/**
* Data provider for the invalid title messages.
*
* @return array
*/
public function data_invalid_title_message() {
return array(
array( 'Test Pattern', 'Pattern titles cannot include "Test". The title should describe the pattern.' ),
array( 'My Pattern', 'Pattern titles cannot include "My Pattern". The title should describe the pattern.' ),
array( 'My Patterns', 'Pattern titles cannot include "My Patterns". The title should describe the pattern.' ),
array( 'WordPress Header', 'Pattern titles cannot include "WordPress". The title should describe the pattern.' ),
array( 'Quote <span>markup</span>', 'Pattern titles cannot contain HTML or shortcodes.' ),
);
}

/**
* Test invalid pattern title: Published pattern, has empty title with no new title.
*/
Expand Down
Loading