From 9ebfe6a6d51b37b2fc0725d874b9a0bb1584084c Mon Sep 17 00:00:00 2001 From: Pascal Birchler Date: Mon, 27 Nov 2023 14:42:26 +0100 Subject: [PATCH 1/5] PHPStan: re-enable `bleedingEdge` option --- .../Injector/SimpleInjector.php | 15 +----- includes/Integrations/AMP.php | 2 +- includes/Integrations/Jetpack.php | 2 +- includes/Integrations/Site_Kit.php | 2 +- includes/KSES.php | 2 +- includes/Media/Media_Source_Taxonomy.php | 2 +- includes/REST_API/Embed_Controller.php | 7 +-- includes/REST_API/Font_Controller.php | 36 +++++-------- includes/REST_API/Hotlinking_Controller.php | 8 +-- includes/REST_API/Link_Controller.php | 12 ++--- includes/REST_API/Products_Controller.php | 51 +++---------------- includes/REST_API/Status_Check_Controller.php | 7 +-- .../REST_API/Stories_Autosaves_Controller.php | 6 +-- includes/REST_API/Stories_Base_Controller.php | 14 ++--- includes/REST_API/Stories_Controller.php | 14 ++--- includes/REST_API/Stories_Lock_Controller.php | 16 ++---- .../REST_API/Stories_Media_Controller.php | 19 ++----- .../Stories_Taxonomies_Controller.php | 7 +-- includes/Tracking.php | 4 +- includes/User/Capabilities.php | 8 ++- .../templates/frontend/single-web-story.php | 2 + phpstan.neon.dist | 6 +-- .../LazilyInstantiatedServiceTest.php | 8 --- .../Infrastructure/ServiceBasedPluginTest.php | 13 ----- .../Infrastructure/SimpleInjectorTest.php | 11 ---- tests/phpunit/integration/tests/KSES.php | 5 +- 26 files changed, 68 insertions(+), 211 deletions(-) diff --git a/includes/Infrastructure/Injector/SimpleInjector.php b/includes/Infrastructure/Injector/SimpleInjector.php index 4f1b04ee4216..efe669ee4f70 100644 --- a/includes/Infrastructure/Injector/SimpleInjector.php +++ b/includes/Infrastructure/Injector/SimpleInjector.php @@ -37,12 +37,6 @@ * @template T */ final class SimpleInjector implements Injector { - - /** - * Special-case index key for handling globally defined named arguments. - */ - public const GLOBAL_ARGUMENTS = '__global__'; - /** * Mappings. * @@ -70,9 +64,7 @@ final class SimpleInjector implements Injector { * * @var array> */ - private array $argument_mappings = [ - self::GLOBAL_ARGUMENTS => [], - ]; + private array $argument_mappings = []; /** * Instantiator. @@ -429,11 +421,6 @@ private function resolve_argument_by_name( return $value; } - // No argument found for the class, check if we have a global value. - if ( \array_key_exists( $name, $this->argument_mappings[ self::GLOBAL_ARGUMENTS ] ) ) { - return $this->argument_mappings[ self::GLOBAL_ARGUMENTS ][ $name ]; - } - // No provided argument found, check if it has a default value. try { if ( $parameter->isDefaultValueAvailable() ) { diff --git a/includes/Integrations/AMP.php b/includes/Integrations/AMP.php index 026e22edd37c..da241e237228 100644 --- a/includes/Integrations/AMP.php +++ b/includes/Integrations/AMP.php @@ -140,7 +140,7 @@ public static function get_requirements(): array { * @param array|mixed $options Options. * @return array|mixed Filtered options. * - * @phpstan-param AMPOptions $options + * @phpstan-param AMPOptions|mixed $options * * @template T * diff --git a/includes/Integrations/Jetpack.php b/includes/Integrations/Jetpack.php index 92fb679f17af..d4fae74e3762 100644 --- a/includes/Integrations/Jetpack.php +++ b/includes/Integrations/Jetpack.php @@ -225,7 +225,7 @@ public function filter_ajax_query_attachments_args( $args ) { * @param WP_Post $attachment Attachment object. * @return array|mixed * - * @phpstan-param AttachmentData $data + * @phpstan-param AttachmentData|mixed $data * @phpstan-return AttachmentData|mixed * * @template T diff --git a/includes/Integrations/Site_Kit.php b/includes/Integrations/Site_Kit.php index 837f94c99434..d807e0306b0f 100644 --- a/includes/Integrations/Site_Kit.php +++ b/includes/Integrations/Site_Kit.php @@ -98,7 +98,7 @@ public function register(): void { * @param array|mixed $gtag_opt Array of gtag configuration options. * @return array|mixed Modified configuration options. * - * @phpstan-param GtagOpt $gtag_opt + * @phpstan-param GtagOpt|mixed $gtag_opt */ public function filter_site_kit_gtag_opt( $gtag_opt ) { if ( diff --git a/includes/KSES.php b/includes/KSES.php index 7d902f7f4045..ab78a9a7ef16 100644 --- a/includes/KSES.php +++ b/includes/KSES.php @@ -115,7 +115,7 @@ public static function get_requirements(): array { * originally passed to wp_insert_post(). * @return array|mixed Filtered post data. * - * @phpstan-param PostData $data + * @phpstan-param PostData|mixed $data * @phpstan-param PostData $unsanitized_postarr * * @template T diff --git a/includes/Media/Media_Source_Taxonomy.php b/includes/Media/Media_Source_Taxonomy.php index 2386d1d17d22..5ba473c7466e 100644 --- a/includes/Media/Media_Source_Taxonomy.php +++ b/includes/Media/Media_Source_Taxonomy.php @@ -172,7 +172,7 @@ public function rest_api_init(): void { * * @since 1.0.0 * - * @param array|mixed $response Array of prepared attachment data. + * @param array|mixed $response Array of prepared attachment data. * @return array|mixed $response Filtered attachment data. * * @template T diff --git a/includes/REST_API/Embed_Controller.php b/includes/REST_API/Embed_Controller.php index 87e9a64c02d0..c9202608d71e 100644 --- a/includes/REST_API/Embed_Controller.php +++ b/includes/REST_API/Embed_Controller.php @@ -251,6 +251,8 @@ public function get_proxy_item( $request ) { * @param array|false $embed Embed value, default to false is not set. * @param WP_REST_Request $request Request object. * @return WP_REST_Response|WP_Error Response object. + * + * @phpstan-param WP_REST_Request $request */ public function prepare_item_for_response( $embed, $request ) { $fields = $this->get_fields_for_response( $request ); @@ -267,11 +269,6 @@ public function prepare_item_for_response( $embed, $request ) { } } - /** - * Request context. - * - * @var string $context - */ $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; $data = $this->add_additional_fields_to_object( $data, $request ); $data = $this->filter_response_by_context( $data, $context ); diff --git a/includes/REST_API/Font_Controller.php b/includes/REST_API/Font_Controller.php index 9e6f838c8500..05f04137583a 100644 --- a/includes/REST_API/Font_Controller.php +++ b/includes/REST_API/Font_Controller.php @@ -127,6 +127,8 @@ public function register_routes(): void { * * @param WP_REST_Request $request Full details about the request. * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure. + * + * @phpstan-param WP_REST_Request $request */ public function get_items( $request ) { /** @@ -145,13 +147,7 @@ public function get_items( $request ) { // For custom fonts the searching will be done in WP_Query already. if ( isset( $registered['search'], $request['search'] ) && ! empty( $request['search'] ) ) { - /** - * Requested URL. - * - * @var string $search - */ - $search = $request['search']; - $fonts = array_values( + $fonts = array_values( array_filter( $fonts, /** @@ -160,7 +156,7 @@ public function get_items( $request ) { * @param array{family: string} $font * @return bool */ - static fn( array $font ) => false !== stripos( $font['family'], $search ) + static fn( array $font ) => false !== stripos( $font['family'], $request['search'] ) ) ); } @@ -172,13 +168,7 @@ public function get_items( $request ) { // Filter before doing any sorting. if ( isset( $registered['include'], $request['include'] ) && ! empty( $request['include'] ) ) { - /** - * Include list. - * - * @var array{string} $include_list - */ - $include_list = $request['include']; - $include_list = array_map( 'strtolower', $include_list ); + $include_list = array_map( 'strtolower', $request['include'] ); $fonts = array_values( array_filter( @@ -202,8 +192,8 @@ public function get_items( $request ) { /** * Font A and Font B. * - * @param Font $a - * @param Font $b + * @phpstan-param Font $a + * @phpstan-param Font $b * @return int */ static fn( array $a, array $b ): int => strnatcasecmp( $a['family'], $b['family'] ) @@ -263,6 +253,8 @@ public function delete_item( $request ) { * @param WP_Post $item Post object. * @param WP_REST_Request $request Request object. * @return WP_REST_Response Response object. + * + * @phpstan-param WP_REST_Request $request */ public function prepare_item_for_response( $item, $request ): WP_REST_Response { // Restores the more descriptive, specific name for use within this method. @@ -302,11 +294,6 @@ public function prepare_item_for_response( $item, $request ): WP_REST_Response { } } - /** - * Request context. - * - * @var string $context - */ $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; $data = $this->add_additional_fields_to_object( $data, $request ); $data = $this->filter_response_by_context( $data, $context ); @@ -687,6 +674,11 @@ protected function prepare_item_for_database( $request ) { * @return bool Whether a font with this exact name already exists. */ private function font_exists( string $font_family ): bool { + /** + * A custom request to perform the lookup. + * + * @phpstan-var WP_REST_Request}> $request + */ $request = new WP_REST_Request( WP_REST_Server::READABLE, $this->namespace . diff --git a/includes/REST_API/Hotlinking_Controller.php b/includes/REST_API/Hotlinking_Controller.php index 7e9d8337dfc2..ba1a55379ce7 100644 --- a/includes/REST_API/Hotlinking_Controller.php +++ b/includes/REST_API/Hotlinking_Controller.php @@ -404,7 +404,8 @@ public function proxy_url( WP_REST_Request $request ) { * @param WP_REST_Request $request Request object. * @return WP_REST_Response|WP_Error Response object. * - * @phpstan-param LinkData $link + * @phpstan-param LinkData $link + * @phpstan-param WP_REST_Request $request */ public function prepare_item_for_response( $link, $request ) { $fields = $this->get_fields_for_response( $request ); @@ -430,11 +431,6 @@ public function prepare_item_for_response( $link, $request ) { return $error; } - /** - * Request context. - * - * @var string $context - */ $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; $data = $this->add_additional_fields_to_object( $data, $request ); $data = $this->filter_response_by_context( $data, $context ); diff --git a/includes/REST_API/Link_Controller.php b/includes/REST_API/Link_Controller.php index 18a63f26acda..df7201c596a2 100644 --- a/includes/REST_API/Link_Controller.php +++ b/includes/REST_API/Link_Controller.php @@ -354,9 +354,12 @@ public function parse_link( $request ) { * * @since 1.10.0 * - * @param array{title: string, image: string, description: string} $link Link value, default to false is not set. - * @param WP_REST_Request $request Request object. + * @param array $link Link value, default to false is not set. + * @param WP_REST_Request $request Request object. * @return WP_REST_Response|WP_Error Response object. + * + * @phpstan-param array{title: string, image: string, description: string} $link + * @phpstan-param WP_REST_Request $request */ public function prepare_item_for_response( $link, $request ) { $fields = $this->get_fields_for_response( $request ); @@ -371,11 +374,6 @@ public function prepare_item_for_response( $link, $request ) { } } - /** - * Request context. - * - * @var string $context - */ $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; $data = $this->add_additional_fields_to_object( $data, $request ); $data = $this->filter_response_by_context( $data, $context ); diff --git a/includes/REST_API/Products_Controller.php b/includes/REST_API/Products_Controller.php index 6f5d504d1b0f..9a790bad930c 100644 --- a/includes/REST_API/Products_Controller.php +++ b/includes/REST_API/Products_Controller.php @@ -169,6 +169,8 @@ public function get_items_permissions_check( $request ) { * * @param WP_REST_Request $request Full details about the request. * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure. + * + * @phpstan-param WP_REST_Request $request */ public function get_items( $request ) { /** @@ -187,40 +189,11 @@ public function get_items( $request ) { return new WP_Error( 'rest_shopping_provider_not_found', __( 'Unable to find shopping integration.', 'web-stories' ), [ 'status' => 400 ] ); } - /** - * Request context. - * - * @var string $search_term - */ $search_term = ! empty( $request['search'] ) ? $request['search'] : ''; - - /** - * Request context. - * - * @var string $orderby - */ - $orderby = ! empty( $request['orderby'] ) ? $request['orderby'] : 'date'; - - /** - * Request context. - * - * @var int $page - */ - $page = ! empty( $request['page'] ) ? $request['page'] : 1; - - /** - * Request context. - * - * @var int $per_page - */ - $per_page = ! empty( $request['per_page'] ) ? $request['per_page'] : 100; - - /** - * Request context. - * - * @var string $order - */ - $order = ! empty( $request['order'] ) ? $request['order'] : 'desc'; + $orderby = ! empty( $request['orderby'] ) ? $request['orderby'] : 'date'; + $page = ! empty( $request['page'] ) ? $request['page'] : 1; + $per_page = ! empty( $request['per_page'] ) ? $request['per_page'] : 100; + $order = ! empty( $request['order'] ) ? $request['order'] : 'desc'; $query_result = $query->get_search( $search_term, $page, $per_page, $orderby, $order ); if ( is_wp_error( $query_result ) ) { @@ -243,11 +216,6 @@ public function get_items( $request ) { $response->header( 'X-WP-HasNextPage', $query_result['has_next_page'] ? 'true' : 'false' ); if ( $request['_web_stories_envelope'] ) { - /** - * Embed directive. - * - * @var string|string[] $embed - */ $embed = $request['_embed'] ?? false; $embed = $embed ? rest_parse_embed_param( $embed ) : false; $response = rest_get_server()->envelope_response( $response, $embed ); @@ -266,6 +234,8 @@ public function get_items( $request ) { * @param Product $item Project object. * @param WP_REST_Request $request Request object. * @return WP_REST_Response Response object. + * + * @phpstan-param WP_REST_Request $request */ public function prepare_item_for_response( $item, $request ): WP_REST_Response { // phpcs:ignore SlevomatCodingStandard.Complexity.Cognitive.ComplexityTooHigh $product = $item; @@ -336,11 +306,6 @@ public function prepare_item_for_response( $item, $request ): WP_REST_Response { } } - /** - * Request context. - * - * @var string $context - */ $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; $data = $this->add_additional_fields_to_object( $data, $request ); $data = $this->filter_response_by_context( $data, $context ); diff --git a/includes/REST_API/Status_Check_Controller.php b/includes/REST_API/Status_Check_Controller.php index 5ec9ca477dbe..aa8dee20aa6c 100644 --- a/includes/REST_API/Status_Check_Controller.php +++ b/includes/REST_API/Status_Check_Controller.php @@ -138,6 +138,8 @@ public function status_check( $request ) { * @param array{success: bool} $item Status array. * @param WP_REST_Request $request Request object. * @return WP_REST_Response|WP_Error Response object. + * + * @phpstan-param WP_REST_Request $request */ public function prepare_item_for_response( $item, $request ) { $fields = $this->get_fields_for_response( $request ); @@ -149,11 +151,6 @@ public function prepare_item_for_response( $item, $request ) { $data['success'] = rest_sanitize_value_from_schema( $item['success'], $schema['properties']['success'] ); } - /** - * Request context. - * - * @var string $context - */ $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; $data = $this->add_additional_fields_to_object( $data, $request ); $data = $this->filter_response_by_context( $data, $context ); diff --git a/includes/REST_API/Stories_Autosaves_Controller.php b/includes/REST_API/Stories_Autosaves_Controller.php index 0d02b563c60b..3f82bbfed69c 100644 --- a/includes/REST_API/Stories_Autosaves_Controller.php +++ b/includes/REST_API/Stories_Autosaves_Controller.php @@ -168,6 +168,7 @@ public function register_routes(): void { * @param WP_Post $post Post object. * @param WP_REST_Request $request Request object. * @return WP_REST_Response Response object. + * @phpstan-param WP_REST_Request $request */ public function prepare_item_for_response( $post, $request ): WP_REST_Response { $response = parent::prepare_item_for_response( $post, $request ); @@ -186,11 +187,6 @@ public function prepare_item_for_response( $post, $request ): WP_REST_Response { $data['story_data'] = rest_sanitize_value_from_schema( $post_story_data, $schema['properties']['story_data'] ); } - /** - * Request context. - * - * @var string $context - */ $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; $data = $this->filter_response_by_context( $data, $context ); $links = $response->get_links(); diff --git a/includes/REST_API/Stories_Base_Controller.php b/includes/REST_API/Stories_Base_Controller.php index 1d8b0ea07545..472bb49659e9 100644 --- a/includes/REST_API/Stories_Base_Controller.php +++ b/includes/REST_API/Stories_Base_Controller.php @@ -113,6 +113,8 @@ public function __construct( $post_type ) { * @param WP_Post $post Post object. * @param WP_REST_Request $request Request object. * @return WP_REST_Response Response object. + * + * @phpstan-param WP_REST_Request $request */ public function prepare_item_for_response( $post, $request ): WP_REST_Response { $response = parent::prepare_item_for_response( $post, $request ); @@ -137,11 +139,6 @@ public function prepare_item_for_response( $post, $request ): WP_REST_Response { $data['story_data'] = post_password_required( $post ) ? (object) [] : rest_sanitize_value_from_schema( $post_story_data, $schema['properties']['story_data'] ); } - /** - * Request context. - * - * @var string $context - */ $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; $data = $this->filter_response_by_context( $data, $context ); $links = $response->get_links(); @@ -167,13 +164,10 @@ public function prepare_item_for_response( $post, $request ): WP_REST_Response { * * @param WP_REST_Request $request Full details about the request. * @return WP_REST_Response|WP_Error Response object on success, WP_Error object on failure. + * + * @phpstan-param WP_REST_Request $request */ public function create_item( $request ) { - /** - * Original post ID. - * - * @var int $original_id - */ $original_id = ! empty( $request['original_id'] ) ? $request['original_id'] : null; if ( ! $original_id ) { return parent::create_item( $request ); diff --git a/includes/REST_API/Stories_Controller.php b/includes/REST_API/Stories_Controller.php index cd54d69aa3f8..779c36258a8f 100644 --- a/includes/REST_API/Stories_Controller.php +++ b/includes/REST_API/Stories_Controller.php @@ -79,13 +79,10 @@ class Stories_Controller extends Stories_Base_Controller { * @param WP_Post $post Post object. * @param WP_REST_Request $request Request object. * @return WP_REST_Response Response object. + * + * @phpstan-param WP_REST_Request $request */ public function prepare_item_for_response( $post, $request ): WP_REST_Response { // phpcs:ignore SlevomatCodingStandard.Complexity.Cognitive.ComplexityTooHigh - /** - * Request context. - * - * @var string $context - */ $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; if ( 'auto-draft' === $post->post_status && wp_validate_boolean( $request['web_stories_demo'] ) ) { @@ -349,6 +346,8 @@ public function filter_query( $args ): array { * * @param WP_REST_Request $request Full details about the request. * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure. + * + * @phpstan-param WP_REST_Request $request */ public function get_items( $request ) { add_filter( "rest_{$this->post_type}_query", [ $this, 'filter_query' ], 100, 1 ); @@ -373,11 +372,6 @@ public function get_items( $request ) { } if ( $request['_web_stories_envelope'] ) { - /** - * Embed directive. - * - * @var string|string[] $embed - */ $embed = $request['_embed']; $embed = $embed ? rest_parse_embed_param( $embed ) : false; $response = rest_get_server()->envelope_response( $response, $embed ); diff --git a/includes/REST_API/Stories_Lock_Controller.php b/includes/REST_API/Stories_Lock_Controller.php index 6a6de0c61782..2da3d827bed1 100644 --- a/includes/REST_API/Stories_Lock_Controller.php +++ b/includes/REST_API/Stories_Lock_Controller.php @@ -269,6 +269,8 @@ public function delete_item_permissions_check( $request ) { * @param array{time?: int, user?: int}|false $item Lock value, default to false is not set. * @param WP_REST_Request $request Request object. * @return WP_REST_Response|WP_Error Response object. + * + * @phpstan-param WP_REST_Request $request */ public function prepare_item_for_response( $item, $request ) { // phpcs:ignore SlevomatCodingStandard.Complexity.Cognitive.ComplexityTooHigh $fields = $this->get_fields_for_response( $request ); @@ -324,11 +326,6 @@ public function prepare_item_for_response( $item, $request ) { // phpcs:ignore S } } - /** - * Request context. - * - * @var string $context - */ $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; $data = $this->add_additional_fields_to_object( $data, $request ); $data = $this->filter_response_by_context( $data, $context ); @@ -340,15 +337,8 @@ public function prepare_item_for_response( $item, $request ) { // phpcs:ignore S */ $response = rest_ensure_response( $data ); - /** - * Post ID. - * - * @var int $post_id - */ - $post_id = $request['id']; - if ( rest_is_field_included( '_links', $fields ) || rest_is_field_included( '_embedded', $fields ) ) { - $response->add_links( $this->prepare_links( $item, $post_id ) ); + $response->add_links( $this->prepare_links( $item, $request['id'] ) ); } $post_type = $this->story_post_type->get_slug(); diff --git a/includes/REST_API/Stories_Media_Controller.php b/includes/REST_API/Stories_Media_Controller.php index c45da099254c..1dadd383f641 100644 --- a/includes/REST_API/Stories_Media_Controller.php +++ b/includes/REST_API/Stories_Media_Controller.php @@ -113,16 +113,13 @@ public static function get_registration_action_priority(): int { * * @param WP_REST_Request $request Full details about the request. * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure. + * + * @phpstan-param WP_REST_Request $request */ public function get_items( $request ) { $response = parent::get_items( $request ); if ( $request['_web_stories_envelope'] && ! is_wp_error( $response ) ) { - /** - * Embed directive. - * - * @var string|string[] $embed - */ $embed = $request['_embed'] ?? false; $embed = $embed ? rest_parse_embed_param( $embed ) : false; $response = rest_get_server()->envelope_response( $response, $embed ); @@ -139,23 +136,15 @@ public function get_items( $request ) { * * @param WP_REST_Request $request Full details about the request. * @return WP_REST_Response|WP_Error Response object on success, WP_Error object on failure. + * + * @phpstan-param WP_REST_Request $request */ public function create_item( $request ) { // WP_REST_Attachments_Controller doesn't allow setting an attachment as the parent post. // Hence we are working around this here. - /** - * Parent post. - * - * @var int $parent_post - */ $parent_post = ! empty( $request['post'] ) ? $request['post'] : null; - /** - * Original post ID. - * - * @var int $original_id - */ $original_id = ! empty( $request['original_id'] ) ? $request['original_id'] : null; unset( $request['post'] ); diff --git a/includes/REST_API/Stories_Taxonomies_Controller.php b/includes/REST_API/Stories_Taxonomies_Controller.php index 01b939aabec8..056423f59d33 100644 --- a/includes/REST_API/Stories_Taxonomies_Controller.php +++ b/includes/REST_API/Stories_Taxonomies_Controller.php @@ -64,17 +64,14 @@ public function __construct() { * * @param WP_REST_Request $request Full details about the request. * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure. + * + * @phpstan-param WP_REST_Request $request */ public function get_items( $request ) { // Retrieve the list of registered collection query parameters. $registered = $this->get_collection_params(); if ( isset( $registered['type'] ) && ! empty( $request['type'] ) ) { - /** - * Object type. - * - * @var string Object type. - */ $type = $request['type']; $taxonomies = get_object_taxonomies( $type, 'objects' ); diff --git a/includes/Tracking.php b/includes/Tracking.php index 6184c09bb6ea..b68a938ea1db 100644 --- a/includes/Tracking.php +++ b/includes/Tracking.php @@ -201,8 +201,8 @@ private function get_user_properties(): array { * @var null|WP_User $current_user */ $current_user = wp_get_current_user(); - $roles = $current_user instanceof WP_User ? $current_user->roles : []; - $role = ! empty( $roles ) && \is_array( $roles ) ? array_shift( $roles ) : ''; + $roles = $current_user instanceof WP_User ? array_values( $current_user->roles ) : []; + $role = ! empty( $roles ) ? array_shift( $roles ) : ''; $experiments = implode( ',', $this->experiments->get_enabled_experiments() ); $active_plugins = []; diff --git a/includes/User/Capabilities.php b/includes/User/Capabilities.php index abd348d9301c..b702972f440d 100644 --- a/includes/User/Capabilities.php +++ b/includes/User/Capabilities.php @@ -185,12 +185,10 @@ public function remove_caps_from_roles(): void { static fn( $value ) => 'read' !== $value ); $all_roles = wp_roles(); - $roles = array_values( (array) $all_roles->role_objects ); + $roles = array_values( $all_roles->role_objects ); foreach ( $roles as $role ) { - if ( $role instanceof WP_Role ) { - foreach ( $all_capabilities as $cap ) { - $role->remove_cap( $cap ); - } + foreach ( $all_capabilities as $cap ) { + $role->remove_cap( $cap ); } } diff --git a/includes/templates/frontend/single-web-story.php b/includes/templates/frontend/single-web-story.php index eb0e5a72e7bc..7ed61e5072f1 100644 --- a/includes/templates/frontend/single-web-story.php +++ b/includes/templates/frontend/single-web-story.php @@ -38,6 +38,8 @@ // wp-admin/revision.php page. if ( isset( $_GET['rev_id'], $_GET['_wpnonce'] ) && + is_string( $_GET['_wpnonce'] ) && + is_string( $_GET['rev_id'] ) && wp_verify_nonce( sanitize_text_field( (string) wp_unslash( $_GET['_wpnonce'] ) ), 'web_stories_revision_for_' . $current_post->ID diff --git a/phpstan.neon.dist b/phpstan.neon.dist index beb6b975af24..786dddbd1abf 100644 --- a/phpstan.neon.dist +++ b/phpstan.neon.dist @@ -8,10 +8,8 @@ services: tags: - phpstan.broker.dynamicStaticMethodReturnTypeExtension -# Re-enable once @var usage for WP_REST_Request is not needed anymore. -# See https://phpstan.org/blog/phpstan-1-10-comes-with-lie-detector -#includes: -# - vendor/phpstan/phpstan/conf/bleedingEdge.neon +includes: + - vendor/phpstan/phpstan/conf/bleedingEdge.neon parameters: level: 9 diff --git a/tests/phpunit/integration/tests/Infrastructure/LazilyInstantiatedServiceTest.php b/tests/phpunit/integration/tests/Infrastructure/LazilyInstantiatedServiceTest.php index 766e90d1e983..4d0b650bfd96 100644 --- a/tests/phpunit/integration/tests/Infrastructure/LazilyInstantiatedServiceTest.php +++ b/tests/phpunit/integration/tests/Infrastructure/LazilyInstantiatedServiceTest.php @@ -5,19 +5,11 @@ namespace Google\Web_Stories\Tests\Integration\Infrastructure; use Google\Web_Stories\Exception\InvalidService; -use Google\Web_Stories\Infrastructure\Service; use Google\Web_Stories\Infrastructure\ServiceContainer\LazilyInstantiatedService; use Google\Web_Stories\Tests\Integration\TestCase; use stdClass; final class LazilyInstantiatedServiceTest extends TestCase { - public function test_it_can_return_the_actual_service_it_represents(): void { - $callable = fn() => $this->createMock( Service::class ); - $lazy_service = new LazilyInstantiatedService( $callable ); - - $this->assertInstanceOf( Service::class, $lazy_service->instantiate() ); - } - public function test_it_throws_when_instantiating_an_invalid_service(): void { $callable = static fn() => new stdClass(); $lazy_service = new LazilyInstantiatedService( $callable ); diff --git a/tests/phpunit/integration/tests/Infrastructure/ServiceBasedPluginTest.php b/tests/phpunit/integration/tests/Infrastructure/ServiceBasedPluginTest.php index cf9a3de4ea4c..379e90198ebf 100644 --- a/tests/phpunit/integration/tests/Infrastructure/ServiceBasedPluginTest.php +++ b/tests/phpunit/integration/tests/Infrastructure/ServiceBasedPluginTest.php @@ -4,9 +4,7 @@ namespace Google\Web_Stories\Tests\Integration\Infrastructure; -use Google\Web_Stories\Infrastructure\Injector; use Google\Web_Stories\Infrastructure\ServiceBasedPlugin; -use Google\Web_Stories\Infrastructure\ServiceContainer; use Google\Web_Stories\Infrastructure\ServiceContainer\SimpleServiceContainer; use Google\Web_Stories\Tests\Integration\Fixture\DummyService; use Google\Web_Stories\Tests\Integration\Fixture\DummyServiceBasedPlugin; @@ -18,16 +16,6 @@ * @coversDefaultClass \Google\Web_Stories\Infrastructure\ServiceBasedPlugin */ final class ServiceBasedPluginTest extends TestCase { - public function test_it_can_return_its_container(): void { - $plugin = $this->getMockBuilder( ServiceBasedPlugin::class ) - ->enableOriginalConstructor() - ->getMock(); - - $container = $plugin->get_container(); - - $this->assertInstanceOf( ServiceContainer::class, $container ); - } - public function test_it_can_be_registered(): void { $plugin = $this->getMockBuilder( ServiceBasedPlugin::class ) ->onlyMethods( [ 'register_services' ] ) @@ -52,7 +40,6 @@ public function test_it_always_registers_an_injector_by_default(): void { $this->assertCount( 1, $container ); $this->assertTrue( $container->has( 'injector' ) ); - $this->assertInstanceof( Injector::class, $container->get( 'injector' ) ); } public function test_it_registers_default_services(): void { diff --git a/tests/phpunit/integration/tests/Infrastructure/SimpleInjectorTest.php b/tests/phpunit/integration/tests/Infrastructure/SimpleInjectorTest.php index 1e2c485f11f9..de6d0ec2f7e5 100644 --- a/tests/phpunit/integration/tests/Infrastructure/SimpleInjectorTest.php +++ b/tests/phpunit/integration/tests/Infrastructure/SimpleInjectorTest.php @@ -138,26 +138,15 @@ static function ( $class_name ) { } public function test_arguments_can_be_bound(): void { - /** - * @var class-string $global_arguments - */ - $global_arguments = SimpleInjector::GLOBAL_ARGUMENTS; - $object = ( new SimpleInjector() ) ->bind_argument( Fixture\DummyClassWithNamedArguments::class, 'argument_a', 42 ) - ->bind_argument( - $global_arguments, - 'argument_b', - 'Mr Alderson' - ) ->make( Fixture\DummyClassWithNamedArguments::class ); $this->assertEquals( 42, $object->get_argument_a() ); - $this->assertEquals( 'Mr Alderson', $object->get_argument_b() ); } public function test_callable_arguments_are_lazily_resolved(): void { diff --git a/tests/phpunit/integration/tests/KSES.php b/tests/phpunit/integration/tests/KSES.php index a13a208caca2..0ca575301899 100644 --- a/tests/phpunit/integration/tests/KSES.php +++ b/tests/phpunit/integration/tests/KSES.php @@ -406,11 +406,10 @@ public function test_filter_kses_allowed_html_uses_deep_merge(): void { $result = $this->instance->filter_kses_allowed_html( $allowed_tags ); - $this->assertArrayHasKey( 'img', $result ); - $this->assertArrayHasKey( 'width', $result['img'] ); + $this->assertTrue( $result['img']['width'] ); $this->assertArrayHasKey( 'intrinsicsize', $result['img'] ); $this->assertArrayHasKey( 'testing', $result ); - $this->assertArrayHasKey( 'width', $result['testing'] ); + $this->assertTrue( $result['testing']['width'] ); } /** From a172ef6fc25055936b2ba95a6496946b3cbf2337 Mon Sep 17 00:00:00 2001 From: Pascal Birchler Date: Fri, 22 Mar 2024 15:08:41 +0100 Subject: [PATCH 2/5] A few more type fixes --- includes/REST_API/Hotlinking_Controller.php | 60 +++++++----------- includes/REST_API/Products_Controller.php | 2 +- includes/REST_API/Stories_Base_Controller.php | 61 +------------------ includes/REST_API/Stories_Controller.php | 61 ++++++++++++++++++- 4 files changed, 84 insertions(+), 100 deletions(-) diff --git a/includes/REST_API/Hotlinking_Controller.php b/includes/REST_API/Hotlinking_Controller.php index ba1a55379ce7..811fdf7e9688 100644 --- a/includes/REST_API/Hotlinking_Controller.php +++ b/includes/REST_API/Hotlinking_Controller.php @@ -78,6 +78,26 @@ * path?: string, * query?: string * } + * + * @phpstan-type RequestOptions array{ + * method?: string, + * timeout?: float, + * redirection?: int, + * httpversion?: string, + * user-agent?: string, + * reject_unsafe_urls?: bool, + * blocking?: bool, + * headers?: string|array, + * cookies?: array, + * body?: string|string[], + * compress?: bool, + * decompress?: bool, + * sslverify?: bool, + * sslcertificates?: string, + * stream?: bool, + * filename?: string, + * limit_response_size?: int, + * } */ class Hotlinking_Controller extends REST_Controller implements HasRequirements { public const PROXY_HEADERS_ALLOWLIST = [ @@ -661,25 +681,7 @@ public function stream_headers( $handle, $header ): int { * @param string $url Request URL. * @param array $args Request args. * - * @phpstan-param array{ - * method?: string, - * timeout?: float, - * redirection?: int, - * httpversion?: string, - * user-agent?: string, - * reject_unsafe_urls?: bool, - * blocking?: bool, - * headers?: string|array, - * cookies?: array, - * body?: string|array, - * compress?: bool, - * decompress?: bool, - * sslverify?: bool, - * sslcertificates?: string, - * stream?: bool, - * filename?: string, - * limit_response_size?: int, - * } $args + * @phpstan-param RequestOptions $args */ private function proxy_url_curl( string $url, array $args ): void { add_action( 'http_api_curl', [ $this, 'modify_curl_configuration' ] ); @@ -702,25 +704,7 @@ private function proxy_url_curl( string $url, array $args ): void { * @param string $url Request URL. * @param array $args Request args. * - * @phpstan-param array{ - * method?: string, - * timeout?: float, - * redirection?: int, - * httpversion?: string, - * user-agent?: string, - * reject_unsafe_urls?: bool, - * blocking?: bool, - * headers?: string|array, - * cookies?: array, - * body?: string|array, - * compress?: bool, - * decompress?: bool, - * sslverify?: bool, - * sslcertificates?: string, - * stream?: bool, - * filename?: string, - * limit_response_size?: int, - * } $args + * @phpstan-param RequestOptions $args */ private function proxy_url_fallback( string $url, array $args ): void { $response = wp_safe_remote_get( $url, $args ); diff --git a/includes/REST_API/Products_Controller.php b/includes/REST_API/Products_Controller.php index 9a790bad930c..fc85d66a140d 100644 --- a/includes/REST_API/Products_Controller.php +++ b/includes/REST_API/Products_Controller.php @@ -235,7 +235,7 @@ public function get_items( $request ) { * @param WP_REST_Request $request Request object. * @return WP_REST_Response Response object. * - * @phpstan-param WP_REST_Request $request + * @phpstan-param WP_REST_Request $request */ public function prepare_item_for_response( $item, $request ): WP_REST_Response { // phpcs:ignore SlevomatCodingStandard.Complexity.Cognitive.ComplexityTooHigh $product = $item; diff --git a/includes/REST_API/Stories_Base_Controller.php b/includes/REST_API/Stories_Base_Controller.php index 472bb49659e9..e0516c502872 100644 --- a/includes/REST_API/Stories_Base_Controller.php +++ b/includes/REST_API/Stories_Base_Controller.php @@ -114,7 +114,7 @@ public function __construct( $post_type ) { * @param WP_REST_Request $request Request object. * @return WP_REST_Response Response object. * - * @phpstan-param WP_REST_Request $request + * @phpstan-param WP_REST_Request $request */ public function prepare_item_for_response( $post, $request ): WP_REST_Response { $response = parent::prepare_item_for_response( $post, $request ); @@ -155,65 +155,6 @@ public function prepare_item_for_response( $post, $request ): WP_REST_Response { return apply_filters( "rest_prepare_{$this->post_type}", $response, $post, $request ); } - /** - * Creates a single story. - * - * Override the existing method so we can set parent id. - * - * @since 1.11.0 - * - * @param WP_REST_Request $request Full details about the request. - * @return WP_REST_Response|WP_Error Response object on success, WP_Error object on failure. - * - * @phpstan-param WP_REST_Request $request - */ - public function create_item( $request ) { - $original_id = ! empty( $request['original_id'] ) ? $request['original_id'] : null; - if ( ! $original_id ) { - return parent::create_item( $request ); - } - - $original_post = $this->get_post( $original_id ); - if ( is_wp_error( $original_post ) ) { - return $original_post; - } - - if ( ! $this->check_update_permission( $original_post ) ) { - return new \WP_Error( - 'rest_cannot_create', - __( 'Sorry, you are not allowed to duplicate this story.', 'web-stories' ), - [ 'status' => rest_authorization_required_code() ] - ); - } - - $request->set_param( 'content', $original_post->post_content ); - $request->set_param( 'excerpt', $original_post->post_excerpt ); - - $title = sprintf( - /* translators: %s: story title. */ - __( '%s (Copy)', 'web-stories' ), - $original_post->post_title - ); - $request->set_param( 'title', $title ); - - $story_data = json_decode( $original_post->post_content_filtered, true ); - if ( $story_data ) { - $request->set_param( 'story_data', $story_data ); - } - - $thumbnail_id = get_post_thumbnail_id( $original_post ); - if ( $thumbnail_id ) { - $request->set_param( 'featured_media', $thumbnail_id ); - } - - $meta = $this->get_registered_meta( $original_post ); - if ( $meta ) { - $request->set_param( 'meta', $meta ); - } - - return parent::create_item( $request ); - } - /** * Retrieves the story's schema, conforming to JSON Schema. * diff --git a/includes/REST_API/Stories_Controller.php b/includes/REST_API/Stories_Controller.php index 779c36258a8f..9a7c9d666bb4 100644 --- a/includes/REST_API/Stories_Controller.php +++ b/includes/REST_API/Stories_Controller.php @@ -80,7 +80,7 @@ class Stories_Controller extends Stories_Base_Controller { * @param WP_REST_Request $request Request object. * @return WP_REST_Response Response object. * - * @phpstan-param WP_REST_Request $request + * @phpstan-param WP_REST_Request $request */ public function prepare_item_for_response( $post, $request ): WP_REST_Response { // phpcs:ignore SlevomatCodingStandard.Complexity.Cognitive.ComplexityTooHigh $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; @@ -171,6 +171,65 @@ public function prepare_item_for_response( $post, $request ): WP_REST_Response { return apply_filters( "rest_prepare_{$this->post_type}", $response, $post, $request ); } + /** + * Creates a single story. + * + * Override the existing method so we can set parent id. + * + * @since 1.11.0 + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_REST_Response|WP_Error Response object on success, WP_Error object on failure. + * + * @phpstan-param WP_REST_Request $request + */ + public function create_item( $request ) { + $original_id = ! empty( $request['original_id'] ) ? $request['original_id'] : null; + if ( ! $original_id ) { + return parent::create_item( $request ); + } + + $original_post = $this->get_post( $original_id ); + if ( is_wp_error( $original_post ) ) { + return $original_post; + } + + if ( ! $this->check_update_permission( $original_post ) ) { + return new \WP_Error( + 'rest_cannot_create', + __( 'Sorry, you are not allowed to duplicate this story.', 'web-stories' ), + [ 'status' => rest_authorization_required_code() ] + ); + } + + $request->set_param( 'content', $original_post->post_content ); + $request->set_param( 'excerpt', $original_post->post_excerpt ); + + $title = sprintf( + /* translators: %s: story title. */ + __( '%s (Copy)', 'web-stories' ), + $original_post->post_title + ); + $request->set_param( 'title', $title ); + + $story_data = json_decode( $original_post->post_content_filtered, true ); + if ( $story_data ) { + $request->set_param( 'story_data', $story_data ); + } + + $thumbnail_id = get_post_thumbnail_id( $original_post ); + if ( $thumbnail_id ) { + $request->set_param( 'featured_media', $thumbnail_id ); + } + + $meta = $this->get_registered_meta( $original_post ); + if ( $meta ) { + $request->set_param( 'meta', $meta ); + } + + return parent::create_item( $request ); + } + /** * Updates a single post. * From 6521d5066beaf3ac6e874386333ca10f31afef6e Mon Sep 17 00:00:00 2001 From: Pascal Birchler Date: Tue, 25 Jun 2024 15:32:01 +0200 Subject: [PATCH 3/5] More type fixes --- includes/Infrastructure/ServiceBasedPlugin.php | 10 ++++++++-- includes/Integrations/Site_Kit.php | 2 ++ includes/KSES.php | 12 +++++++++--- includes/Media/Types.php | 2 +- includes/Plugin.php | 4 ++-- .../tests/REST_API/Stories_Controller.php | 1 + 6 files changed, 23 insertions(+), 8 deletions(-) diff --git a/includes/Infrastructure/ServiceBasedPlugin.php b/includes/Infrastructure/ServiceBasedPlugin.php index 1e1454e201ef..351ffcb8bb3c 100644 --- a/includes/Infrastructure/ServiceBasedPlugin.php +++ b/includes/Infrastructure/ServiceBasedPlugin.php @@ -324,7 +324,13 @@ public function register_services(): void { while ( null !== key( $services ) ) { $id = $this->maybe_resolve( key( $services ) ); - $class = $this->maybe_resolve( current( $services ) ); + $curr = current( $services ); + + if ( ! $curr ) { + continue; + } + + $class = $this->maybe_resolve( $curr ); // Delay registering the service until all requirements are met. if ( @@ -547,7 +553,7 @@ protected function collect_missing_requirements( string $class_name, array $serv * @since 1.6.0 * * @param array $services Services to validate. - * @return string[] Validated array of service mappings. + * @return array> Validated array of service mappings. */ protected function validate_services( array $services ): array { // Make a copy so we can safely mutate while iterating. diff --git a/includes/Integrations/Site_Kit.php b/includes/Integrations/Site_Kit.php index b0d5e4037fd6..888328bf3d15 100644 --- a/includes/Integrations/Site_Kit.php +++ b/includes/Integrations/Site_Kit.php @@ -133,7 +133,9 @@ function (): void { public function filter_site_kit_gtag_opt( $gtag_opt ) { if ( ! \is_array( $gtag_opt ) || + ! \is_array( $gtag_opt['vars'] ) || ! isset( $gtag_opt['vars']['gtag_id'] ) || + ! is_string( $gtag_opt['vars']['gtag_id'] ) || ! $this->context->is_web_story() ) { return $gtag_opt; diff --git a/includes/KSES.php b/includes/KSES.php index ec5489444fe3..4c9ba21e37cc 100644 --- a/includes/KSES.php +++ b/includes/KSES.php @@ -120,7 +120,7 @@ public static function get_requirements(): array { * @return array|mixed Filtered post data. * * @phpstan-param PostData|mixed $data - * @phpstan-param PostData $unsanitized_postarr + * @phpstan-param PostData|mixed $unsanitized_postarr * * @template T * @@ -135,11 +135,17 @@ public function filter_insert_post_data( $data, $postarr, $unsanitized_postarr ) return $data; } - if ( ! $this->is_allowed_post_type( $data['post_type'], $data['post_parent'] ) ) { + if ( + ! \is_string( $data['post_type'] ) || + ! $this->is_allowed_post_type( $data['post_type'], $data['post_parent'] ) + ) { return $data; } - if ( isset( $unsanitized_postarr['post_content_filtered'] ) ) { + if ( + isset( $unsanitized_postarr['post_content_filtered'] ) && + \is_string( $unsanitized_postarr['post_content_filtered'] ) + ) { $data['post_content_filtered'] = $this->filter_story_data( $unsanitized_postarr['post_content_filtered'] ); } diff --git a/includes/Media/Types.php b/includes/Media/Types.php index 93af00491dda..c75b7c2429ae 100644 --- a/includes/Media/Types.php +++ b/includes/Media/Types.php @@ -103,7 +103,7 @@ public function get_allowed_mime_types(): array { * @var string $media_type */ foreach ( array_keys( $default_allowed_mime_types ) as $media_type ) { - if ( ! \is_array( $allowed_mime_types[ $media_type ] ) || empty( $allowed_mime_types[ $media_type ] ) ) { + if ( ! isset( $allowed_mime_types[ $media_type ] ) || empty( $allowed_mime_types[ $media_type ] ) ) { $allowed_mime_types[ $media_type ] = $default_allowed_mime_types[ $media_type ]; } diff --git a/includes/Plugin.php b/includes/Plugin.php index 4a1e89d87ae5..57213feb1a1d 100644 --- a/includes/Plugin.php +++ b/includes/Plugin.php @@ -150,8 +150,8 @@ class Plugin extends ServiceBasedPlugin { * * @since 1.6.0 * - * @return array Associative array of identifiers mapped to fully - * qualified class names. + * @return array Associative array of identifiers mapped to fully + * qualified class names. */ protected function get_service_classes(): array { return self::SERVICES; diff --git a/tests/phpunit/integration/tests/REST_API/Stories_Controller.php b/tests/phpunit/integration/tests/REST_API/Stories_Controller.php index 0d4db072a3f6..4a4117f75940 100644 --- a/tests/phpunit/integration/tests/REST_API/Stories_Controller.php +++ b/tests/phpunit/integration/tests/REST_API/Stories_Controller.php @@ -1217,6 +1217,7 @@ public function test_update_item_as_author_should_not_strip_markup(): void { $this->assertIsArray( $new_data ); $this->assertIsArray( $new_data['content'] ); + $this->assertIsString( $new_data['content']['raw'] ); $this->assertSame( $sanitized_content, trim( $new_data['content']['raw'] ) ); $this->assertSame( $unsanitized_story_data, $new_data['story_data'] ); } From 65c41e59e147a12251a5aaf0e07cecfa81d5fe7f Mon Sep 17 00:00:00 2001 From: Pascal Birchler Date: Tue, 25 Jun 2024 17:13:13 +0200 Subject: [PATCH 4/5] More type fixes --- includes/Admin/Customizer.php | 4 +++- includes/Infrastructure/ServiceBasedPlugin.php | 10 +++++++--- includes/Integrations/Site_Kit.php | 2 +- includes/KSES.php | 2 +- includes/Media/Media_Source_Taxonomy.php | 3 +++ 5 files changed, 15 insertions(+), 6 deletions(-) diff --git a/includes/Admin/Customizer.php b/includes/Admin/Customizer.php index 98a582a5df1a..69f1a7f8ea38 100644 --- a/includes/Admin/Customizer.php +++ b/includes/Admin/Customizer.php @@ -726,7 +726,9 @@ private function parse_args( array $args, array $defaults = [] ): array { * * @var array|bool|int|string>>> $def */ - $def = $parsed_args[ $key ]; + $def = $parsed_args[ $key ]; + + // @phpstan-ignore argument.type (TODO: improve type for recursion) $parsed_args[ $key ] = $this->parse_args( $value, $def ); } else { $parsed_args[ $key ] = $value; diff --git a/includes/Infrastructure/ServiceBasedPlugin.php b/includes/Infrastructure/ServiceBasedPlugin.php index 351ffcb8bb3c..4eb0d75b66ee 100644 --- a/includes/Infrastructure/ServiceBasedPlugin.php +++ b/includes/Infrastructure/ServiceBasedPlugin.php @@ -401,7 +401,7 @@ protected function get_registration_action_priority( string $class_name, array & /** * Missing requirement. * - * @phpstan-var class-string $missing_requirement + * @phpstan-var class-string $missing_requirement */ $requirement_priority = $this->get_registration_action_priority( $missing_requirement, $services ); @@ -570,11 +570,14 @@ protected function validate_services( array $services ): array { // Verify that the FQCN is valid and points to an existing class. // If not, skip this service. - if ( empty( $fqcn ) || ! \is_string( $fqcn ) || ! class_exists( $fqcn ) ) { + if ( empty( $fqcn ) || ! class_exists( $fqcn ) ) { unset( $services[ $identifier ] ); } } + /** + * @phpstan-var array> $services + */ return $services; } @@ -692,6 +695,7 @@ protected function instantiate_service( $class_name ): Service { // The service needs to be registered, so instantiate right away. $service = $this->injector->make( $class_name ); + // @phpstan-ignore instanceof.alwaysTrue if ( ! $service instanceof Service ) { throw InvalidService::from_service( $service ); // phpcs:ignore WordPress.Security.EscapeOutput.ExceptionNotEscaped } @@ -916,7 +920,7 @@ protected function get_delegations(): array { * @phpstan-return class-string Resolved or unchanged value. */ protected function maybe_resolve( $value ): string { - if ( \is_callable( $value ) && ! ( \is_string( $value ) && \function_exists( $value ) ) ) { + if ( ! ( \is_string( $value ) && \function_exists( $value ) ) && \is_callable( $value ) ) { $value = $value( $this->injector, $this->service_container ); } diff --git a/includes/Integrations/Site_Kit.php b/includes/Integrations/Site_Kit.php index 888328bf3d15..2ed0592f93e3 100644 --- a/includes/Integrations/Site_Kit.php +++ b/includes/Integrations/Site_Kit.php @@ -135,7 +135,7 @@ public function filter_site_kit_gtag_opt( $gtag_opt ) { ! \is_array( $gtag_opt ) || ! \is_array( $gtag_opt['vars'] ) || ! isset( $gtag_opt['vars']['gtag_id'] ) || - ! is_string( $gtag_opt['vars']['gtag_id'] ) || + ! \is_string( $gtag_opt['vars']['gtag_id'] ) || ! $this->context->is_web_story() ) { return $gtag_opt; diff --git a/includes/KSES.php b/includes/KSES.php index 4c9ba21e37cc..abdc39a52d97 100644 --- a/includes/KSES.php +++ b/includes/KSES.php @@ -136,7 +136,7 @@ public function filter_insert_post_data( $data, $postarr, $unsanitized_postarr ) } if ( - ! \is_string( $data['post_type'] ) || + ! \is_string( $data['post_type'] ) || ! $this->is_allowed_post_type( $data['post_type'], $data['post_parent'] ) ) { return $data; diff --git a/includes/Media/Media_Source_Taxonomy.php b/includes/Media/Media_Source_Taxonomy.php index 5ba473c7466e..e1c84aac1cdb 100644 --- a/includes/Media/Media_Source_Taxonomy.php +++ b/includes/Media/Media_Source_Taxonomy.php @@ -184,6 +184,7 @@ public function wp_prepare_attachment_for_js( $response ) { return $response; } + // @phpstan-ignore argument.type (TODO: improve type) $response[ self::MEDIA_SOURCE_KEY ] = $this->get_callback_media_source( $response ); return $response; @@ -249,6 +250,7 @@ public function filter_ajax_query_attachments_args( $args ) { return $args; } + // @phpstan-ignore argument.type (TODO: improve type) $args['tax_query'] = $this->get_exclude_tax_query( $args ); // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_tax_query return $args; @@ -290,6 +292,7 @@ public function filter_rest_generated_media_attachments( $args ) { return $args; } + // @phpstan-ignore argument.type (TODO: improve type) $args['tax_query'] = $this->get_exclude_tax_query( $args ); // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_tax_query return $args; From d3bd83eac4fc063a2ef18d2d92567e0df5c2a5d5 Mon Sep 17 00:00:00 2001 From: Pascal Birchler Date: Tue, 25 Jun 2024 18:12:21 +0200 Subject: [PATCH 5/5] Lint fixes --- includes/Infrastructure/ServiceBasedPlugin.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/includes/Infrastructure/ServiceBasedPlugin.php b/includes/Infrastructure/ServiceBasedPlugin.php index 4eb0d75b66ee..1542912a4374 100644 --- a/includes/Infrastructure/ServiceBasedPlugin.php +++ b/includes/Infrastructure/ServiceBasedPlugin.php @@ -576,6 +576,8 @@ protected function validate_services( array $services ): array { } /** + * Validated services. + * * @phpstan-var array> $services */ return $services;