diff --git a/public_html/wp-content/plugins/pattern-directory/bin/update-contains-block-types.php b/public_html/wp-content/plugins/pattern-directory/bin/update-contains-block-types.php new file mode 100644 index 000000000..4c6e5ea83 --- /dev/null +++ b/public_html/wp-content/plugins/pattern-directory/bin/update-contains-block-types.php @@ -0,0 +1,102 @@ + or explicitly run over --all.\n" ); + die(); +} + +if ( ! $opts['apply'] ) { + echo "Dry run, will not update any patterns.\n"; +} + +$args = array( + 'post_type' => POST_TYPE, + 'post_status' => array( 'publish', 'pending' ), + 'posts_per_page' => isset( $opts['per_page'] ) ? $opts['per_page'] : -1, + 'post_parent' => 0, + 'orderby' => 'date', + 'order' => 'DESC', + 'meta_query' => array( + // Only update patterns without this meta. + array( + 'key' => 'wpop_contains_block_types', + 'compare' => 'NOT EXISTS', + ), + ), +); +if ( isset( $opts['post'] ) ) { + $args = array( + 'post_type' => POST_TYPE, + 'p' => absint( $opts['post'] ), + ); +} + +$query = new \WP_Query( $args ); +$meta_updated = 0; + +while ( $query->have_posts() ) { + $query->the_post(); + $pattern = get_post(); + $pattern_id = $pattern->ID; + $blocks = parse_blocks( $pattern->post_content ); + $all_blocks = _flatten_blocks( $blocks ); + + // Get the list of block names and convert it to a single string. + $block_names = wp_list_pluck( $all_blocks, 'blockName' ); + $block_names = array_filter( $block_names ); + $block_names = array_unique( $block_names ); + sort( $block_names ); + $used_blocks = implode( ',', $block_names ); + + if ( $opts['apply'] ) { + $result = update_post_meta( $pattern_id, 'wpop_contains_block_types', $used_blocks ); + if ( $result ) { + $meta_updated++; + } else if ( $opts['verbose'] ) { + echo "Error updating {$pattern_id}.\n"; // phpcs:ignore + } + } else if ( $opts['verbose'] ) { + echo "Will update {$pattern_id} with '{$used_blocks}'.\n"; // phpcs:ignore + } +} + +echo "Updated {$meta_updated} patterns.\n"; // phpcs:ignore +echo "Done.\n\n"; // phpcs:ignore diff --git a/public_html/wp-content/plugins/pattern-directory/includes/pattern-post-type.php b/public_html/wp-content/plugins/pattern-directory/includes/pattern-post-type.php index 67e54d754..e291a9268 100644 --- a/public_html/wp-content/plugins/pattern-directory/includes/pattern-post-type.php +++ b/public_html/wp-content/plugins/pattern-directory/includes/pattern-post-type.php @@ -15,6 +15,7 @@ add_action( 'rest_api_init', __NAMESPACE__ . '\register_rest_fields' ); add_action( 'init', __NAMESPACE__ . '\register_post_statuses' ); add_action( 'transition_post_status', __NAMESPACE__ . '\status_transitions', 10, 3 ); +add_action( 'post_updated', __NAMESPACE__ . '\update_contains_block_types_meta' ); add_action( 'enqueue_block_editor_assets', __NAMESPACE__ . '\enqueue_editor_assets' ); add_filter( 'allowed_block_types_all', __NAMESPACE__ . '\remove_disallowed_blocks', 10, 2 ); add_action( 'enqueue_block_editor_assets', __NAMESPACE__ . '\disable_block_directory', 0 ); @@ -249,6 +250,24 @@ function register_post_type_data() { ), ) ); + + register_post_meta( + POST_TYPE, + 'wpop_contains_block_types', + array( + 'type' => 'string', + 'description' => 'A list of block types used in this pattern', + 'single' => true, + 'default' => '', + 'sanitize_callback' => 'sanitize_text_field', + 'auth_callback' => __NAMESPACE__ . '\can_edit_this_pattern', + 'show_in_rest' => array( + 'schema' => array( + 'type' => 'string', + ), + ), + ) + ); } /** @@ -490,6 +509,26 @@ function status_transitions( $new_status, $old_status, $post ) { } } +/** + * Given a post ID, parse out the block types and update the `wpop_contains_block_types` meta field. + * + * @param int $pattern_id Pattern ID. + */ +function update_contains_block_types_meta( $pattern_id ) { + $pattern = get_post( $pattern_id ); + $blocks = parse_blocks( $pattern->post_content ); + $all_blocks = _flatten_blocks( $blocks ); + + // Get the list of block names and convert it to a single string. + $block_names = wp_list_pluck( $all_blocks, 'blockName' ); + $block_names = array_filter( $block_names ); // Filter out null values (extra line breaks). + $block_names = array_unique( $block_names ); + sort( $block_names ); + $used_blocks = implode( ',', $block_names ); + + update_post_meta( $pattern_id, 'wpop_contains_block_types', $used_blocks ); +} + /** * Determines if the current user can edit the given pattern post. * @@ -635,6 +674,14 @@ function filter_patterns_collection_params( $query_params ) { 'type' => 'string', ); + $query_params['allowed_blocks'] = array( + 'description' => __( 'Filter the request to only return patterns with blocks on this list.', 'wporg-patterns' ), + 'type' => 'array', + 'items' => array( + 'type' => 'string', + ), + ); + return $query_params; } @@ -700,6 +747,16 @@ function filter_patterns_rest_query( $args, $request ) { ); } + $allowed_blocks = $request->get_param( 'allowed_blocks' ); + if ( $allowed_blocks ) { + // Only return a pattern if all contained blocks are in the allowed blocks list. + $args['meta_query']['allowed_blocks'] = array( + 'key' => 'wpop_contains_block_types', + 'compare' => 'REGEXP', + 'value' => '^((' . implode( '|', $allowed_blocks ) . '),?)+$', + ); + } + return $args; } diff --git a/public_html/wp-content/plugins/pattern-translations/pattern-translations.php b/public_html/wp-content/plugins/pattern-translations/pattern-translations.php index cca8ffc07..7de21dea1 100644 --- a/public_html/wp-content/plugins/pattern-translations/pattern-translations.php +++ b/public_html/wp-content/plugins/pattern-translations/pattern-translations.php @@ -47,10 +47,14 @@ function create_or_update_translated_pattern( Pattern $pattern ) { 'post_author' => $parent->post_author ?? 0, 'post_status' => $parent->post_status ?? 'pending', 'meta_input' => [ - 'wpop_description' => $pattern->description, - 'wpop_locale' => $pattern->locale, - 'wpop_viewport_width' => $parent->wpop_viewport_width, - 'wpop_is_translation' => true, + 'wpop_description' => $pattern->description, + 'wpop_locale' => $pattern->locale, + 'wpop_keywords' => $pattern->keywords, + 'wpop_viewport_width' => $parent->wpop_viewport_width, + 'wpop_block_types' => $parent->wpop_block_types, + 'wpop_contains_block_types' => $parent->wpop_contains_block_types, + 'wpop_wp_version' => $parent->wpop_wp_version, + 'wpop_is_translation' => true, ], ];