From 302a5405398dcc18e3a106ae2c1b280faada4eca Mon Sep 17 00:00:00 2001 From: Utkarsh Patel Date: Tue, 14 Jul 2026 14:01:45 +0530 Subject: [PATCH] Bump PHPStan to level 3 and fix type/annotation issues Raise the PHPStan analysis level from 2 to 3 and resolve the resulting issues, all safe PHPDoc/annotation corrections with no behavior change: - Correct return-type PHPDoc to match actual behavior: Assets:: generate_storage_signature (bool), Assets::build_item (array|null), Media::get_transformation (int|string|false), Media::cloudinary_url (string|null), Media::filter_downsize (array|false), Media:: get_context_options (string), Settings::save (string[]), Api::sign (string), Api::call (array|string|WP_Error), Page::form/notice and Sync::action (array|null), On_Off::sanitize_value (string). - Widen base Text::sanitize_value PHPDoc to mixed so the array/bool overrides (Checkbox, Cron, Crops, React, Tags_Input, On_Off) are covariant-compatible. - Fix settings/setting type confusion: correct Component\Settings interface param to Cloudinary\Settings, widen Settings_Component:: $settings and Delivery_Feature::$settings to Settings|Setting, align Gallery/Extensions/Global_Transformations settings property types. - Fix Setting::$parent (string slug, not self) and get_option_parent return (Setting|null). - Fix Sync::$managers to include Sync_Queue. - Fix Line_Stat $connect type (Cloudinary\Connect) and narrow at call site; allow numeric used_percent/limit. - Cast ini_get in Cron::$daemon_watcher_interval; default Api:: $pending_url to null; widen Url_Object::get_id to int|string|null. - Correct get_terms return-type PHPDoc and annotate video metadata to resolve offset access on WP stub arrays. --- php/class-assets.php | 4 ++-- php/class-cron.php | 2 +- php/class-delivery-feature.php | 3 +-- php/class-extensions.php | 2 +- php/class-media.php | 10 +++++----- php/class-settings-component.php | 3 ++- php/class-settings.php | 2 +- php/class-sync.php | 2 +- php/component/class-settings.php | 4 ++-- php/connect/class-api.php | 6 +++--- php/media/class-gallery.php | 2 +- php/media/class-global-transformations.php | 4 ++-- php/media/class-video.php | 10 ++++++++++ php/settings/class-setting.php | 4 ++-- php/ui/component/class-line-stat.php | 14 ++++++++++---- php/ui/component/class-on-off.php | 2 +- php/ui/component/class-page.php | 4 ++-- php/ui/component/class-sync.php | 2 +- php/ui/component/class-text.php | 4 ++-- php/url/class-url-object.php | 2 +- phpstan.neon.dist | 2 +- 21 files changed, 52 insertions(+), 36 deletions(-) diff --git a/php/class-assets.php b/php/class-assets.php index 749ae9f78..b81b6d14c 100644 --- a/php/class-assets.php +++ b/php/class-assets.php @@ -713,7 +713,7 @@ public function generate_file_signature( $asset_id ) { * * @param int $asset_id The attachment/asset ID. * - * @return string + * @return bool */ public function generate_storage_signature( $asset_id ) { return $this->get_asset_storage_folder( $asset_id ) === $this->media->get_public_id( $asset_id ); @@ -1199,7 +1199,7 @@ public function get_asset( $post_id, $type = 'object' ) { * * @param array $item The raw data for an asset. * - * @return array + * @return array|null */ public function build_item( $item ) { if ( empty( $item ) ) { diff --git a/php/class-cron.php b/php/class-cron.php index 9877c0b0b..15c816832 100644 --- a/php/class-cron.php +++ b/php/class-cron.php @@ -81,7 +81,7 @@ public function __construct() { // Ensure it's safe. if ( self::$daemon_watcher_interval > ini_get( 'max_execution_time' ) ) { - self::$daemon_watcher_interval = ini_get( 'max_execution_time' ); + self::$daemon_watcher_interval = (int) ini_get( 'max_execution_time' ); } $this->init_time = time(); diff --git a/php/class-delivery-feature.php b/php/class-delivery-feature.php index 3af79ff73..5d10d1b9b 100644 --- a/php/class-delivery-feature.php +++ b/php/class-delivery-feature.php @@ -8,7 +8,6 @@ namespace Cloudinary; use Cloudinary\Component\Assets; -use Cloudinary\Settings\Setting; /** * Class Delivery_Feature @@ -57,7 +56,7 @@ abstract class Delivery_Feature implements Assets { /** * Holds the settings. * - * @var Setting + * @var Settings|\Cloudinary\Settings\Setting */ protected $settings; diff --git a/php/class-extensions.php b/php/class-extensions.php index ed5a9c2c6..842feac87 100644 --- a/php/class-extensions.php +++ b/php/class-extensions.php @@ -24,7 +24,7 @@ class Extensions extends Settings_Component implements Setup { /** * Holds the core plugin settings. * - * @var Settings + * @var Settings|\Cloudinary\Settings\Setting */ protected $settings; diff --git a/php/class-media.php b/php/class-media.php index 5dd7e7090..3d4ff61d4 100644 --- a/php/class-media.php +++ b/php/class-media.php @@ -941,7 +941,7 @@ public function set_transformation( &$transformations, $type, $value, $index = f * @param array $transformations The transformation set to check. * @param string $type The type of transformation to check for. * - * @return bool + * @return int|string|false */ public function get_transformation( $transformations, $type ) { foreach ( $transformations as $index => $transformation ) { @@ -1372,7 +1372,7 @@ protected function get_cache_key( $args ) { * @param string|null $cloudinary_id Optional forced cloudinary ID. * @param bool $overwrite_transformations Flag url is a breakpoint URL to stop re-applying default transformations. * - * @return string The converted URL. + * @return string|null The converted URL. */ public function cloudinary_url( $attachment_id, $size = array(), $transformations = array(), $cloudinary_id = null, $overwrite_transformations = false ) { static $cache = array(); @@ -1777,11 +1777,11 @@ public function cloudinary_id( $attachment_id ) { /** * Filter the requested image and return image source. * - * @param null $image The null image value for short circuit check. + * @param array|false $image The image value for short circuit check. * @param int $attachment_id The ID of the attachment. * @param string|array $size The requested size of the image. * - * @return array The image array of size and url. + * @return array|false The image array of size and url. * @uses filter:image_downsize */ public function filter_downsize( $image, $attachment_id, $size ) { @@ -2781,7 +2781,7 @@ public function get_breakpoint_options( $attachment_id ) { * * @param int $attachment_id The ID of the attachment. * - * @return array + * @return string */ public function get_context_options( $attachment_id ) { $caption = get_post( $attachment_id )->post_excerpt; diff --git a/php/class-settings-component.php b/php/class-settings-component.php index 2561279c7..78409ff9b 100644 --- a/php/class-settings-component.php +++ b/php/class-settings-component.php @@ -9,6 +9,7 @@ use Cloudinary\Component; use Cloudinary\Settings as CoreSetting; +use Cloudinary\Settings\Setting; /** * Plugin Settings Component class. @@ -18,7 +19,7 @@ abstract class Settings_Component implements Component\Settings { /** * Holds the settings object for this Class. * - * @var CoreSetting + * @var CoreSetting|Setting */ protected $settings; diff --git a/php/class-settings.php b/php/class-settings.php index 4507ba0bb..817d7e337 100644 --- a/php/class-settings.php +++ b/php/class-settings.php @@ -590,7 +590,7 @@ public function remove_pending( $slug ) { /** * Save settings. * - * @return bool[]|\WP_Error[] + * @return string[] */ public function save() { $pending = array_keys( $this->get_pending() ); diff --git a/php/class-sync.php b/php/class-sync.php index a38e2b8ab..5ee820415 100644 --- a/php/class-sync.php +++ b/php/class-sync.php @@ -35,7 +35,7 @@ class Sync implements Setup, Assets { /** * Contains all the different sync components. * - * @var Delete_Sync[]|Push_Sync[]|Upload_Sync[]|Media[]|Unsync[]|Download_Sync[] + * @var Delete_Sync[]|Push_Sync[]|Upload_Sync[]|Media[]|Unsync[]|Download_Sync[]|Sync_Queue[] */ public $managers; diff --git a/php/component/class-settings.php b/php/component/class-settings.php index 6c12ce847..dae182e79 100644 --- a/php/component/class-settings.php +++ b/php/component/class-settings.php @@ -7,7 +7,7 @@ namespace Cloudinary\Component; -use Cloudinary\Settings\Setting; +use Cloudinary\Settings as CoreSettings; /** * Defines an object that requires settings. @@ -17,7 +17,7 @@ interface Settings { /** * Init Settings Object. * - * @param Setting $setting The core setting. + * @param CoreSettings $setting The core setting. */ public function init_settings( $setting ); } diff --git a/php/connect/class-api.php b/php/connect/class-api.php index 796762bf2..01a0aba09 100644 --- a/php/connect/class-api.php +++ b/php/connect/class-api.php @@ -156,7 +156,7 @@ class Api { * * @var string|null */ - private $pending_url = array(); + private $pending_url = null; /** * API constructor. @@ -801,7 +801,7 @@ public function __call( $name, $args ) { * * @param array $args Array of parameters to sign. * - * @return array|\WP_Error + * @return string */ public function sign( $args ) { @@ -988,7 +988,7 @@ protected static function get_hostname( $upload_prefix ) { * @param array $args The optional arguments to send. * @param string $method The call HTTP method. * - * @return array|\WP_Error + * @return array|string|\WP_Error */ private function call( $url, $args = array(), $method = 'get' ) { $args['method'] = strtoupper( $method ); diff --git a/php/media/class-gallery.php b/php/media/class-gallery.php index c7f8f236b..d8f82e1cc 100644 --- a/php/media/class-gallery.php +++ b/php/media/class-gallery.php @@ -48,7 +48,7 @@ class Gallery extends Settings_Component { /** * Holds the sync settings object. * - * @var Setting + * @var \Cloudinary\Settings|Setting */ public $settings; diff --git a/php/media/class-global-transformations.php b/php/media/class-global-transformations.php index 3f41e745a..de8ae5345 100644 --- a/php/media/class-global-transformations.php +++ b/php/media/class-global-transformations.php @@ -67,7 +67,7 @@ class Global_Transformations { /** * Holds the media settings. * - * @var Setting + * @var \Cloudinary\Settings */ protected $media_settings; @@ -360,7 +360,7 @@ public function render_ordering_box( $post ) { * * @param int $post_id The post ID. * - * @return array|false|int|\WP_Error|\WP_Term[] + * @return array */ public function get_terms( $post_id ) { // Get terms for this post on load. diff --git a/php/media/class-video.php b/php/media/class-video.php index 6c214b9f8..18d51dc8a 100644 --- a/php/media/class-video.php +++ b/php/media/class-video.php @@ -159,6 +159,11 @@ public function filter_video_shortcode( $html, $attr ) { // If not CLD video init, return default. if ( ! $this->player_enabled() ) { if ( empty( $attr['cloudinary'] ) ) { + /** + * The attachment metadata. + * + * @var array $video + */ $video = wp_get_attachment_metadata( $attr['id'] ); $url = $this->media->cloudinary_url( $attr['id'] ); $attr[ $video['fileformat'] ] = strtok( $url, '?' ); @@ -400,6 +405,11 @@ protected function build_video_embed( $source, $attributes = array(), $overwrite $params['source']['transformation'] = $transformations; } // Set the source_type. + /** + * The attachment metadata. + * + * @var array $video + */ $video = wp_get_attachment_metadata( $attachment_id ); if ( ! empty( $video['fileformat'] ) && 'off' === $streaming['adaptive_streaming'] ) { $params['source']['source_types'][] = $video['fileformat']; diff --git a/php/settings/class-setting.php b/php/settings/class-setting.php index ab943464b..f729f9154 100644 --- a/php/settings/class-setting.php +++ b/php/settings/class-setting.php @@ -64,7 +64,7 @@ class Setting { /** * Holds the parent. * - * @var self + * @var string */ protected $parent; @@ -388,7 +388,7 @@ public function get_option_name() { /** * Get the option parent. * - * @return Settings + * @return Setting|null */ public function get_option_parent() { $root = explode( $this->separator, $this->slug, 2 )[0]; diff --git a/php/ui/component/class-line-stat.php b/php/ui/component/class-line-stat.php index 3f4e33be4..24dfe0700 100644 --- a/php/ui/component/class-line-stat.php +++ b/php/ui/component/class-line-stat.php @@ -27,14 +27,14 @@ class Line_Stat extends Component { /** * Holds the used persentage. * - * @var string + * @var int|float|string */ protected $used_percent; /** * Holds the limit. * - * @var string + * @var int|float|string */ protected $limit; @@ -76,7 +76,7 @@ class Line_Stat extends Component { /** * Holds the connect instance. * - * @var Connect + * @var \Cloudinary\Connect */ protected $connect; @@ -118,7 +118,13 @@ protected function set_texts() { * Set the usage stats. */ protected function set_stats() { - $this->connect = get_plugin_instance()->get_component( 'connect' ); + /** + * The connect component. + * + * @var \Cloudinary\Connect $connect + */ + $connect = get_plugin_instance()->get_component( 'connect' ); + $this->connect = $connect; $this->limit = $this->connect->get_usage_stat( $this->setting->get_param( 'stat' ), 'limit' ); $this->used_percent = $this->connect->get_usage_stat( $this->setting->get_param( 'stat' ), 'used_percent' ); } diff --git a/php/ui/component/class-on-off.php b/php/ui/component/class-on-off.php index f68130720..90c745bd1 100644 --- a/php/ui/component/class-on-off.php +++ b/php/ui/component/class-on-off.php @@ -231,7 +231,7 @@ protected function is_readonly() { * * @param string $value The value to sanitize. * - * @return bool + * @return string */ public function sanitize_value( $value ) { $allowed = array( diff --git a/php/ui/component/class-page.php b/php/ui/component/class-page.php index 83e46161a..396c2aa28 100644 --- a/php/ui/component/class-page.php +++ b/php/ui/component/class-page.php @@ -47,7 +47,7 @@ protected function wrap( $struct ) { * * @param array $struct The array structure. * - * @return array + * @return array|null */ protected function form( $struct ) { if ( $this->setting->has_param( 'has_tabs' ) ) { @@ -72,7 +72,7 @@ protected function form( $struct ) { * * @param array $struct The array structure. * - * @return array + * @return array|null */ protected function notice( $struct ) { if ( Utils::get_active_setting() !== $this->setting ) { diff --git a/php/ui/component/class-sync.php b/php/ui/component/class-sync.php index e6386d83d..4abc4dd1d 100644 --- a/php/ui/component/class-sync.php +++ b/php/ui/component/class-sync.php @@ -67,7 +67,7 @@ protected function status( $struct ) { * * @param array $struct The array structure. * - * @return array + * @return array|null */ protected function action( $struct ) { diff --git a/php/ui/component/class-text.php b/php/ui/component/class-text.php index 73cf04679..679dbebf9 100644 --- a/php/ui/component/class-text.php +++ b/php/ui/component/class-text.php @@ -212,9 +212,9 @@ protected function get_id() { /** * Sanitize the value. * - * @param string $value The value to sanitize. + * @param mixed $value The value to sanitize. * - * @return string + * @return mixed */ public function sanitize_value( $value ) { if ( 0 === strlen( $value ) && $this->setting->has_param( 'default' ) ) { diff --git a/php/url/class-url-object.php b/php/url/class-url-object.php index 6e17ae4c9..58d63fcc2 100644 --- a/php/url/class-url-object.php +++ b/php/url/class-url-object.php @@ -117,7 +117,7 @@ abstract public function url( $size = null ); /** * Get the ID. * - * @return int|null + * @return int|string|null */ abstract public function get_id(); } diff --git a/phpstan.neon.dist b/phpstan.neon.dist index d585b56fe..65109885a 100644 --- a/phpstan.neon.dist +++ b/phpstan.neon.dist @@ -14,7 +14,7 @@ parameters: - identifier: return.void message: '#^Action callback returns .+ but should not return anything\.$#' - level: 2 + level: 3 paths: - php - cloudinary.php