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
21 changes: 21 additions & 0 deletions features/post-block.feature
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,27 @@ Feature: Manage blocks in post content
"""
And the return code should be 1

@less-than-wp-5.0
Scenario: Checking for a specific block requires WordPress 5.0
Given a WP install
When I run `wp post create --post_title="Block Post" --post_content="<!-- wp:paragraph --><p>Hello</p><!-- /wp:paragraph -->" --porcelain`
Then save STDOUT as {POST_ID}

# has-blocks goes through the bundled WP_Block_Processor polyfill, so it keeps working.
When I run `wp post has-blocks {POST_ID}`
Then STDOUT should contain:
"""
Success: Post {POST_ID} contains blocks.
"""

# has-block relies on the has_block() function that WordPress only added in 5.0.
When I try `wp post has-block {POST_ID} core/paragraph`
Then STDERR should contain:
"""
Error: Requires WordPress 5.0 or greater.
"""
And the return code should be 1

@require-wp-5.0
Scenario: Parse blocks in a post
Given a WP install
Expand Down
92 changes: 92 additions & 0 deletions phpstan.neon.dist
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,95 @@ parameters:
- identifier: missingType.property
- identifier: missingType.parameter
- identifier: missingType.return


# johnbillion/wp-compat checks every WordPress symbol against the WordPress 4.9
# baseline that wp-cli-tests configures. It only recognizes function_exists() and
# method_exists() guards, so it cannot see the `before_invoke` version checks in
# entity-command.php or the polyfills in src/Compat/, and reports those as errors.
#
# Every entry below matches on the message as well as the identifier, so that a call
# to something introduced later than the version a command is gated on still gets
# reported rather than swallowed by a file-wide ignore.

# `WP_Block_Processor` and its dependencies are polyfilled in src/Compat/ and loaded
# on demand through `BlockProcessorLoader::load()`, so they are available on every
# supported WordPress version, not just 6.9+.
-
identifier: WPCompat.methodNotAvailable
message: '#^WP_Block_Processor::(allocate_and_return_parsed_attributes|extract_full_block_and_advance|get_block_type|get_delimiter_type|get_depth|get_span|next_block)\(\) is only available since WordPress version 6\.9\.0\.$#'
path: src/Block_Processor_Helper.php

# `wp font collection|face|family` aborts on WordPress < 6.5 via `before_invoke`.
-
identifier: WPCompat.methodNotAvailable
message: '#^(WP_Font_Collection::get_data|WP_Font_Library::(get_font_collection|get_font_collections|get_instance))\(\) is only available since WordPress version 6\.5\.0\.$#'
paths:
- src/Font_Collection_Command.php
- src/Font_Family_Command.php

# `wp user application-password` aborts on WordPress < 5.6 via `before_invoke`.
-
identifier: WPCompat.methodNotAvailable
message: '#^WP_Application_Passwords::(create_new_application_password|delete_all_application_passwords|delete_application_password|get_user_application_password|get_user_application_passwords|record_application_password_usage|update_application_password)\(\) is only available since WordPress version 5\.6\.0\.$#'
path: src/User_Application_Password_Command.php

# The single WordPress 5.7 method is additionally behind a `wp_version_compare()`
# check in `application_name_exists_for_user()`, which reimplements it for 5.6.
-
identifier: WPCompat.methodNotAvailable
message: '#^WP_Application_Passwords::application_name_exists_for_user\(\) is only available since WordPress version 5\.7\.0\.$#'
path: src/User_Application_Password_Command.php

# `wp user privacy-request` aborts on WordPress < 4.9.6 via `before_invoke`.
-
identifier: WPCompat.functionNotAvailable
message: '#^(_wp_privacy_completed_request|wp_create_user_request|wp_get_user_request_data|wp_privacy_exports_dir|wp_privacy_generate_personal_data_export_file|wp_send_user_request)\(\) is only available since WordPress version 4\.9\.6\.$#'
path: src/User_Privacy_Request_Command.php

# `wp site meta` aborts via `before_invoke` unless `is_site_meta_supported()`
# exists, which is the WordPress 5.1 function that introduced site meta support
# along with the `*_site_meta()` functions used here.
-
identifier: WPCompat.functionNotAvailable
message: '#^(add_site_meta|delete_site_meta|get_site_meta|update_site_meta)\(\) is only available since WordPress version 5\.1\.0\.$#'
path: src/Site_Meta_Command.php

# `wp post block` aborts on WordPress < 5.0 via `before_invoke`. `serialize_blocks()`
# is WordPress 5.3.1+ and is guarded separately in the mutating subcommands, so it
# must keep being reported if that guard ever goes away.
-
identifier: WPCompat.functionNotAvailable
message: '#^(has_blocks|parse_blocks|render_block)\(\) is only available since WordPress version 5\.0\.0\.$#'
path: src/Post_Block_Command.php

# Only the uppercase `'ID'` alias for the `$field` parameter of `get_term_by()`
# is WordPress 5.5+. These call sites pass `'id'`, `'term_id'` or `'slug'`, all
# supported since WordPress 2.3.
-
identifier: WPCompat.parameterNotAvailable.gettermby.field
paths:
- src/Menu_Item_Command.php
- src/Term_Command.php
- src/WP_CLI/CommandWithTerms.php

# WordPress 6.0 only formalized the already documented `...$args` parameter of
# `apply_filters()` by adding it to the function signature. Additional arguments
# were collected through `func_get_args()` before that.
-
identifier: WPCompat.parameterNotAvailable.applyfilters.args
path: src/Post_Block_Command.php

# Same for `wpdb::prepare()`, where WordPress 5.3 formalized the already
# documented `...$args` parameter. Passing a single array of values is even
# handled explicitly by `wpdb::prepare()` itself.
-
identifier: WPCompat.parameterNotAvailable.wpdbprepare.args
path: src/Site_Command.php

# The `$force_cache` parameter of `wp_load_alloptions()` is WordPress 5.3.1+, but
# older versions simply ignore the extra argument. The cache refresh in
# `wp option set-autoload` degrades to a no-op there instead of failing.
-
identifier: WPCompat.parameterNotAvailable.wploadalloptions.forcecache
path: src/Option_Command.php
28 changes: 28 additions & 0 deletions src/Post_Block_Command.php
Original file line number Diff line number Diff line change
Expand Up @@ -224,6 +224,10 @@ public function get( $args, $assoc_args ) {
* @subcommand update
*/
public function update( $args, $assoc_args ) {
if ( ! function_exists( 'serialize_blocks' ) ) {
WP_CLI::error( 'Requires WordPress 5.3.1 or greater.' );
}

$post = $this->fetcher->get_check( $args[0] );
$index = (int) $args[1];
$blocks = parse_blocks( $post->post_content );
Expand Down Expand Up @@ -340,6 +344,10 @@ public function update( $args, $assoc_args ) {
* @subcommand move
*/
public function move( $args, $assoc_args ) {
if ( ! function_exists( 'serialize_blocks' ) ) {
WP_CLI::error( 'Requires WordPress 5.3.1 or greater.' );
}

$post = $this->fetcher->get_check( $args[0] );
$from_index = (int) $args[1];
$to_index = (int) $args[2];
Expand Down Expand Up @@ -607,6 +615,10 @@ function ( $block ) {
* @subcommand import
*/
public function import( $args, $assoc_args ) {
if ( ! function_exists( 'serialize_blocks' ) ) {
WP_CLI::error( 'Requires WordPress 5.3.1 or greater.' );
}

$post = $this->fetcher->get_check( $args[0] );
$file = Utils\get_flag_value( $assoc_args, 'file', null );
$position = Utils\get_flag_value( $assoc_args, 'position', 'end' );
Expand Down Expand Up @@ -914,6 +926,10 @@ public function count( $args, $assoc_args ) {
* @subcommand clone
*/
public function clone_block( $args, $assoc_args ) {
if ( ! function_exists( 'serialize_blocks' ) ) {
WP_CLI::error( 'Requires WordPress 5.3.1 or greater.' );
}

$post = $this->fetcher->get_check( $args[0] );
$source_index = (int) $args[1];
$position = Utils\get_flag_value( $assoc_args, 'position', 'after' );
Expand Down Expand Up @@ -1393,6 +1409,10 @@ public function list_( $args, $assoc_args ) {
* @subcommand insert
*/
public function insert( $args, $assoc_args ) {
if ( ! function_exists( 'serialize_blocks' ) ) {
WP_CLI::error( 'Requires WordPress 5.3.1 or greater.' );
}

$post = $this->fetcher->get_check( $args[0] );
$block_name = $args[1];
$content = Utils\get_flag_value( $assoc_args, 'content', '' );
Expand Down Expand Up @@ -1492,6 +1512,10 @@ public function insert( $args, $assoc_args ) {
* @subcommand remove
*/
public function remove( $args, $assoc_args ) {
if ( ! function_exists( 'serialize_blocks' ) ) {
WP_CLI::error( 'Requires WordPress 5.3.1 or greater.' );
}

$post = $this->fetcher->get_check( $args[0] );
$block_name = isset( $args[1] ) ? $args[1] : null;
$indices = Utils\get_flag_value( $assoc_args, 'index', null );
Expand Down Expand Up @@ -1637,6 +1661,10 @@ function ( $idx ) use ( $index_map ) {
* @subcommand replace
*/
public function replace( $args, $assoc_args ) {
if ( ! function_exists( 'serialize_blocks' ) ) {
WP_CLI::error( 'Requires WordPress 5.3.1 or greater.' );
}

$post = $this->fetcher->get_check( $args[0] );
$old_block_name = $args[1];
$new_block_name = $args[2];
Expand Down
4 changes: 4 additions & 0 deletions src/Post_Command.php
Original file line number Diff line number Diff line change
Expand Up @@ -1430,6 +1430,10 @@ public function has_blocks( $args, $assoc_args ) {
* @subcommand has-block
*/
public function has_block( $args, $assoc_args ) {
if ( ! function_exists( 'has_block' ) ) {
WP_CLI::error( 'Requires WordPress 5.0 or greater.' );
}

$post = $this->fetcher->get_check( $args[0] );
$block_name = $args[1];

Expand Down