diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index e4046c760..6ad41d067 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -43,6 +43,41 @@ jobs:
- name: Run build
run: npm run build
+ phpstan:
+ name: PHPStan
+ runs-on: ubuntu-latest
+ steps:
+ - name: Checkout repository
+ uses: actions/checkout@v4
+
+ - name: Setup PHP
+ uses: shivammathur/setup-php@v2
+ with:
+ php-version: '8.3'
+
+ - name: Cache Composer
+ uses: actions/cache@v4
+ with:
+ path: ~/.composer/cache
+ key: ${{ runner.os }}-composer-phpstan-${{ hashFiles('**/composer.lock') }}
+ restore-keys: |
+ ${{ runner.os }}-composer-phpstan-
+
+ - name: Install Composer dependencies
+ run: composer install --no-interaction --no-progress
+
+ - name: Cache PHPStan result cache
+ uses: actions/cache@v4
+ with:
+ path: .phpstan-cache
+ key: ${{ runner.os }}-phpstan-${{ hashFiles('**/composer.lock', 'phpstan.neon.dist') }}-${{ github.sha }}
+ restore-keys: |
+ ${{ runner.os }}-phpstan-${{ hashFiles('**/composer.lock', 'phpstan.neon.dist') }}-
+ ${{ runner.os }}-phpstan-
+
+ - name: Run PHPStan
+ run: composer phpstan
+
e2e:
name: E2E (Playwright)
runs-on: ubuntu-latest
diff --git a/.gitignore b/.gitignore
index 0a408a57f..219524cb7 100644
--- a/.gitignore
+++ b/.gitignore
@@ -58,3 +58,6 @@ package/dist
# AI generated files
.claude/
+
+# PHPStan result cache
+/.phpstan-cache/
diff --git a/composer.json b/composer.json
index bf0f95ba6..e7531d730 100644
--- a/composer.json
+++ b/composer.json
@@ -11,7 +11,11 @@
"phpcompatibility/phpcompatibility-wp": "dev-master",
"phpcompatibility/php-compatibility": "dev-develop as 9.99.99",
"automattic/vipwpcs": "^3.0",
- "wp-coding-standards/wpcs": "^3.0"
+ "wp-coding-standards/wpcs": "^3.0",
+ "phpstan/phpstan": "^2.0",
+ "szepeviktor/phpstan-wordpress": "^2.0",
+ "php-stubs/wp-cli-stubs": "^2.10",
+ "php-stubs/woocommerce-stubs": "^9.0"
},
"config": {
"platform": {
@@ -27,6 +31,9 @@
],
"fix": [
"phpcbf"
+ ],
+ "phpstan": [
+ "phpstan analyse --memory-limit=-1"
]
},
"minimum-stability": "dev"
diff --git a/composer.lock b/composer.lock
index ba8e58578..3803b2de2 100644
--- a/composer.lock
+++ b/composer.lock
@@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
- "content-hash": "7dec3f7732c4f100acf0b8d51d11218b",
+ "content-hash": "b8cd5a14604ce418e38204b454e4447a",
"packages": [],
"packages-dev": [
{
@@ -136,6 +136,146 @@
},
"time": "2022-02-04T12:51:07+00:00"
},
+ {
+ "name": "php-stubs/woocommerce-stubs",
+ "version": "v9.9.5",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/php-stubs/woocommerce-stubs.git",
+ "reference": "3f4d4e14afe6150569bd96cf14e8a17a84812447"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/php-stubs/woocommerce-stubs/zipball/3f4d4e14afe6150569bd96cf14e8a17a84812447",
+ "reference": "3f4d4e14afe6150569bd96cf14e8a17a84812447",
+ "shasum": ""
+ },
+ "require": {
+ "php-stubs/wordpress-stubs": "^5.3 || ^6.0"
+ },
+ "require-dev": {
+ "php": "~7.1 || ~8.0",
+ "php-stubs/generator": "^0.8.0"
+ },
+ "suggest": {
+ "symfony/polyfill-php73": "Symfony polyfill backporting some PHP 7.3+ features to lower PHP versions",
+ "szepeviktor/phpstan-wordpress": "WordPress extensions for PHPStan"
+ },
+ "type": "library",
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "description": "WooCommerce function and class declaration stubs for static analysis.",
+ "homepage": "https://github.com/php-stubs/woocommerce-stubs",
+ "keywords": [
+ "PHPStan",
+ "static analysis",
+ "woocommerce",
+ "wordpress"
+ ],
+ "support": {
+ "issues": "https://github.com/php-stubs/woocommerce-stubs/issues",
+ "source": "https://github.com/php-stubs/woocommerce-stubs/tree/v9.9.5"
+ },
+ "time": "2025-07-14T17:12:48+00:00"
+ },
+ {
+ "name": "php-stubs/wordpress-stubs",
+ "version": "v6.9.4",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/php-stubs/wordpress-stubs.git",
+ "reference": "90a9412826b9944f93b10bf41d795b5fe68abcd5"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/php-stubs/wordpress-stubs/zipball/90a9412826b9944f93b10bf41d795b5fe68abcd5",
+ "reference": "90a9412826b9944f93b10bf41d795b5fe68abcd5",
+ "shasum": ""
+ },
+ "conflict": {
+ "phpdocumentor/reflection-docblock": "5.6.1"
+ },
+ "require-dev": {
+ "dealerdirect/phpcodesniffer-composer-installer": "^1.0",
+ "nikic/php-parser": "^5.5",
+ "php": "^7.4 || ^8.0",
+ "php-stubs/generator": "^0.8.6",
+ "phpdocumentor/reflection-docblock": "^6.0",
+ "phpstan/phpstan": "^2.1",
+ "phpunit/phpunit": "^9.5",
+ "symfony/polyfill-php80": "*",
+ "szepeviktor/phpcs-psr-12-neutron-hybrid-ruleset": "^1.1.1",
+ "wp-coding-standards/wpcs": "3.1.0 as 2.3.0"
+ },
+ "suggest": {
+ "paragonie/sodium_compat": "Pure PHP implementation of libsodium",
+ "symfony/polyfill-php80": "Symfony polyfill backporting some PHP 8.0+ features to lower PHP versions",
+ "szepeviktor/phpstan-wordpress": "WordPress extensions for PHPStan"
+ },
+ "type": "library",
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "description": "WordPress function and class declaration stubs for static analysis.",
+ "homepage": "https://github.com/php-stubs/wordpress-stubs",
+ "keywords": [
+ "PHPStan",
+ "static analysis",
+ "wordpress"
+ ],
+ "support": {
+ "issues": "https://github.com/php-stubs/wordpress-stubs/issues",
+ "source": "https://github.com/php-stubs/wordpress-stubs/tree/v6.9.4"
+ },
+ "time": "2026-05-01T20:36:01+00:00"
+ },
+ {
+ "name": "php-stubs/wp-cli-stubs",
+ "version": "v2.12.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/php-stubs/wp-cli-stubs.git",
+ "reference": "af16401e299a3fd2229bd0fa9a037638a4174a9d"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/php-stubs/wp-cli-stubs/zipball/af16401e299a3fd2229bd0fa9a037638a4174a9d",
+ "reference": "af16401e299a3fd2229bd0fa9a037638a4174a9d",
+ "shasum": ""
+ },
+ "require": {
+ "php-stubs/wordpress-stubs": "^4.7 || ^5.0 || ^6.0"
+ },
+ "require-dev": {
+ "php": "~7.3 || ~8.0",
+ "php-stubs/generator": "^0.8.0"
+ },
+ "suggest": {
+ "symfony/polyfill-php73": "Symfony polyfill backporting some PHP 7.3+ features to lower PHP versions",
+ "szepeviktor/phpstan-wordpress": "WordPress extensions for PHPStan"
+ },
+ "type": "library",
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "description": "WP-CLI function and class declaration stubs for static analysis.",
+ "homepage": "https://github.com/php-stubs/wp-cli-stubs",
+ "keywords": [
+ "PHPStan",
+ "static analysis",
+ "wordpress",
+ "wp-cli"
+ ],
+ "support": {
+ "issues": "https://github.com/php-stubs/wp-cli-stubs/issues",
+ "source": "https://github.com/php-stubs/wp-cli-stubs/tree/v2.12.0"
+ },
+ "time": "2025-06-10T09:58:05+00:00"
+ },
{
"name": "phpcompatibility/php-compatibility",
"version": "dev-develop",
@@ -477,6 +617,71 @@
},
"time": "2023-06-26T10:35:06+00:00"
},
+ {
+ "name": "phpstan/phpstan",
+ "version": "2.2.x-dev",
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/phpstan/phpstan/zipball/c4cda3fb3d5fe1615d1b53edee13525600e39868",
+ "reference": "c4cda3fb3d5fe1615d1b53edee13525600e39868",
+ "shasum": ""
+ },
+ "require": {
+ "php": "^7.4|^8.0"
+ },
+ "conflict": {
+ "phpstan/phpstan-shim": "*"
+ },
+ "default-branch": true,
+ "bin": [
+ "phpstan",
+ "phpstan.phar"
+ ],
+ "type": "library",
+ "autoload": {
+ "files": [
+ "bootstrap.php"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Ondřej Mirtes"
+ },
+ {
+ "name": "Markus Staab"
+ },
+ {
+ "name": "Vincent Langlet"
+ }
+ ],
+ "description": "PHPStan - PHP Static Analysis Tool",
+ "keywords": [
+ "dev",
+ "static analysis"
+ ],
+ "support": {
+ "docs": "https://phpstan.org/user-guide/getting-started",
+ "forum": "https://github.com/phpstan/phpstan/discussions",
+ "issues": "https://github.com/phpstan/phpstan/issues",
+ "security": "https://github.com/phpstan/phpstan/security/policy",
+ "source": "https://github.com/phpstan/phpstan-src"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/ondrejmirtes",
+ "type": "github"
+ },
+ {
+ "url": "https://github.com/phpstan",
+ "type": "github"
+ }
+ ],
+ "time": "2026-06-17T15:28:08+00:00"
+ },
{
"name": "sirbrillig/phpcs-variable-analysis",
"version": "2.x-dev",
@@ -617,6 +822,70 @@
],
"time": "2024-01-24T01:41:07+00:00"
},
+ {
+ "name": "szepeviktor/phpstan-wordpress",
+ "version": "2.x-dev",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/szepeviktor/phpstan-wordpress.git",
+ "reference": "84577e2ea1e4c2a95537fe5ea2ac8e18f4ceab1a"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/szepeviktor/phpstan-wordpress/zipball/84577e2ea1e4c2a95537fe5ea2ac8e18f4ceab1a",
+ "reference": "84577e2ea1e4c2a95537fe5ea2ac8e18f4ceab1a",
+ "shasum": ""
+ },
+ "require": {
+ "php": "^7.4 || ^8.0",
+ "php-stubs/wordpress-stubs": ">=6.6.2",
+ "phpstan/phpstan": "^2.0"
+ },
+ "require-dev": {
+ "composer/composer": "^2.1.14",
+ "composer/semver": "^3.4",
+ "dealerdirect/phpcodesniffer-composer-installer": "^1.0",
+ "php-parallel-lint/php-parallel-lint": "^1.1",
+ "phpstan/phpstan-strict-rules": "^2.0",
+ "phpunit/phpunit": "^9.0",
+ "szepeviktor/phpcs-psr-12-neutron-hybrid-ruleset": "^1.0",
+ "wp-coding-standards/wpcs": "3.1.0 as 2.3.0"
+ },
+ "suggest": {
+ "swissspidy/phpstan-no-private": "Detect usage of internal core functions, classes and methods"
+ },
+ "default-branch": true,
+ "type": "phpstan-extension",
+ "extra": {
+ "phpstan": {
+ "includes": [
+ "extension.neon"
+ ]
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "SzepeViktor\\PHPStan\\WordPress\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "description": "WordPress extensions for PHPStan",
+ "keywords": [
+ "PHPStan",
+ "code analyse",
+ "code analysis",
+ "static analysis",
+ "wordpress"
+ ],
+ "support": {
+ "issues": "https://github.com/szepeviktor/phpstan-wordpress/issues",
+ "source": "https://github.com/szepeviktor/phpstan-wordpress/tree/2.x"
+ },
+ "time": "2026-05-22T16:22:09+00:00"
+ },
{
"name": "wp-coding-standards/wpcs",
"version": "3.0.1",
@@ -694,17 +963,17 @@
],
"minimum-stability": "dev",
"stability-flags": {
- "phpcompatibility/phpcompatibility-wp": 20,
- "phpcompatibility/php-compatibility": 20
+ "phpcompatibility/php-compatibility": 20,
+ "phpcompatibility/phpcompatibility-wp": 20
},
"prefer-stable": false,
"prefer-lowest": false,
"platform": {
"ext-json": "*"
},
- "platform-dev": [],
+ "platform-dev": {},
"platform-overrides": {
- "php": "5.6.20"
+ "php": "7.4"
},
- "plugin-api-version": "2.6.0"
+ "plugin-api-version": "2.9.0"
}
diff --git a/php/cache/class-cache-point.php b/php/cache/class-cache-point.php
index dcdd85907..91abc3777 100644
--- a/php/cache/class-cache-point.php
+++ b/php/cache/class-cache-point.php
@@ -107,9 +107,9 @@ public function __construct( Cache $cache ) {
* @hook cloudinary_on_demand_sync_limit
* @default 100
*
- * @param $value {int} The default number of static assets.
+ * @param int $value The default number of static assets.
*
- * @return {int}
+ * @return int
*/
$this->sync_limit = apply_filters( 'cloudinary_on_demand_sync_limit', 100 );
$this->register_post_type();
@@ -118,7 +118,7 @@ public function __construct( Cache $cache ) {
add_filter( 'get_post_metadata', array( $this, 'get_meta' ), 10, 3 );
add_filter( 'delete_post_metadata', array( $this, 'delete_meta' ), 10, 4 );
add_action( 'shutdown', array( $this, 'meta_updates' ) );
- add_action( 'wp_resource_hints', array( $this, 'dns_prefetch' ), 10, 2 );
+ add_filter( 'wp_resource_hints', array( $this, 'dns_prefetch' ), 10, 2 );
}
/**
diff --git a/php/cache/class-file-system.php b/php/cache/class-file-system.php
index 0baaf610a..44e06d17b 100644
--- a/php/cache/class-file-system.php
+++ b/php/cache/class-file-system.php
@@ -172,6 +172,8 @@ public function get_file_src_root( $file_url ) {
);
}
}
+
+ return array();
}
/**
diff --git a/php/class-assets.php b/php/class-assets.php
index ce4e1beea..afdd8e79f 100644
--- a/php/class-assets.php
+++ b/php/class-assets.php
@@ -158,8 +158,8 @@ protected function register_hooks() {
add_filter( 'cloudinary_set_usable_asset', array( $this, 'check_usable_asset' ) );
// Actions.
add_action( 'cloudinary_ready', array( $this, 'setup' ) );
- add_action( 'cloudinary_thread_queue_details_query', array( $this, 'connect_post_type' ) );
- add_action( 'cloudinary_build_queue_query', array( $this, 'connect_post_type' ) );
+ add_filter( 'cloudinary_thread_queue_details_query', array( $this, 'connect_post_type' ) );
+ add_filter( 'cloudinary_build_queue_query', array( $this, 'connect_post_type' ) );
add_action( 'cloudinary_string_replace', array( $this, 'add_url_replacements' ), 20 );
add_action( 'shutdown', array( $this, 'meta_updates' ) );
add_action( 'admin_bar_menu', array( $this, 'admin_bar_cache' ), 100 );
diff --git a/php/class-cache.php b/php/class-cache.php
index 52d4d8c1d..bb89c51e1 100644
--- a/php/class-cache.php
+++ b/php/class-cache.php
@@ -227,7 +227,7 @@ protected function register_hooks() {
add_action( 'admin_init', array( $this, 'admin_rewrite' ), 0 );
}
add_filter( 'cloudinary_api_rest_endpoints', array( $this, 'rest_endpoints' ) );
- add_action( 'http_request_args', array( $this, 'prevent_caching_internal_requests' ), 10, 5 ); // phpcs:ignore WordPressVIPMinimum.Hooks.RestrictedHooks.http_request_args
+ add_filter( 'http_request_args', array( $this, 'prevent_caching_internal_requests' ), 10, 2 ); // phpcs:ignore WordPressVIPMinimum.Hooks.RestrictedHooks.http_request_args
}
/**
@@ -261,9 +261,9 @@ public function bypass_cache() {
* @hook cloudinary_bypass_cache
* @default false
*
- * @param $bypass {bool} True to bypass, false to not.
+ * @param bool $bypass True to bypass, false to not.
*
- * @return {bool}
+ * @return bool
*/
return apply_filters( 'cloudinary_bypass_cache', ! is_null( $bypass ) );
}
@@ -486,9 +486,9 @@ protected function get_inline_types() {
* @hook cloudinary_plugin_asset_cache_inline_types
* @default array()
*
- * @param $inline_types {array} The types of files to be encoded inline.
+ * @param array $inline_types The types of files to be encoded inline.
*
- * @return {array}
+ * @return array
*/
return apply_filters( 'cloudinary_plugin_asset_cache_inline_types', $inline_types );
}
@@ -577,9 +577,9 @@ protected function get_filetype_filters() {
* @hook cloudinary_plugin_asset_cache_filters
* @default array()
*
- * @param $default_filters {array} The types of files to be filtered.
+ * @param array $default_filters The types of files to be filtered.
*
- * @return {array}
+ * @return array
*/
return apply_filters( 'cloudinary_plugin_asset_cache_filters', $default_filters );
}
diff --git a/php/class-delivery-feature.php b/php/class-delivery-feature.php
index 3f2b8468d..3af79ff73 100644
--- a/php/class-delivery-feature.php
+++ b/php/class-delivery-feature.php
@@ -203,7 +203,7 @@ public function filter_is_active() {
* @hook cloudinary_is_{$class_name}_active
* @since 3.0.4
*
- * @param $is_active {bool} Flag if active.
+ * @param bool $is_active Flag if active.
*/
return apply_filters( "cloudinary_is_{$class_name}_active", $is_active );
}
diff --git a/php/class-delivery.php b/php/class-delivery.php
index ec0c577d6..9d01c0e6b 100644
--- a/php/class-delivery.php
+++ b/php/class-delivery.php
@@ -411,10 +411,10 @@ public function is_deliverable( $attachment_id ) {
*
* @hook cloudinary_is_deliverable
*
- * @param $is {bool} The default value.
- * @param $attachment_id {int} The attachment ID.
+ * @param bool $is The default value.
+ * @param int $attachment_id The attachment ID.
*
- * @return {bool}
+ * @return bool
*/
return apply_filters( 'cloudinary_is_deliverable', $is, $attachment_id );
}
@@ -706,7 +706,7 @@ protected function setup_hooks() {
add_filter( 'cloudinary_current_post_id', array( $this, 'get_current_post_id' ) );
add_filter( 'the_content', array( $this, 'add_post_id' ) );
- add_action( 'wp_resource_hints', array( $this, 'dns_prefetch' ), 10, 2 );
+ add_filter( 'wp_resource_hints', array( $this, 'dns_prefetch' ), 10, 2 );
$metadata = Utils::METADATA;
@@ -741,9 +741,9 @@ public function dns_prefetch( $urls, $relation_type ) {
* @since 3.2.12
* @default array ( 'dns-prefetch', 'preconnect' )
*
- * @param $types {array} The types of resource hints to use.
+ * @param array $types The types of resource hints to use.
*
- * @return {array} The modified resource hints to use.
+ * @return array The modified resource hints to use.
*/
$resource_hints = apply_filters( 'cloudinary_dns_prefetch_types', array( 'dns-prefetch', 'preconnect' ) );
@@ -845,7 +845,7 @@ protected function init_delivery() {
* @hook cloudinary_init_delivery
* @since 2.7.5
*
- * @param $delivery {Delivery} The delivery object.
+ * @param Delivery $delivery The delivery object.
*/
do_action( 'cloudinary_init_delivery', $this );
}
@@ -936,9 +936,9 @@ public function find_attachment_size_urls() {
* @hook cloudinary_contextualized_post_id
* @since 3.2.0
*
- * @param $post_id {int} The post ID.
+ * @param int $post_id The post ID.
*
- * @return {int}
+ * @return int
*/
$post_id = apply_filters( 'cloudinary_contextualized_post_id', $result->post_id );
@@ -1079,10 +1079,10 @@ function ( $tag ) use ( $content ) {
* @hook cloudinary_delivery_get_id
* @since 2.7.6
*
- * @param $attachment_id {int} The attachment ID.
- * @param $tag_element {array} The tag element.
+ * @param int $attachment_id The attachment ID.
+ * @param array $tag_element The tag element.
*
- * @return {int|false}
+ * @return int|false
*/
$set['id'] = apply_filters( 'cloudinary_delivery_get_id', $set['id'], $set );
if ( empty( $set['id'] ) ) {
@@ -1218,8 +1218,8 @@ protected function standardize_tag( $tag_element ) {
* @since 3.2.4
* @default {false}
*
- * @param $skip {bool} True to unset attributes.
- * @param $tag_element {array} The tag element.
+ * @param bool $skip True to unset attributes.
+ * @param array $tag_element The tag element.
*
* @retun {bool}
*/
@@ -1316,8 +1316,8 @@ protected function standardize_tag( $tag_element ) {
* @since 3.2.4
* @default {false}
*
- * @param $unset {bool} True to unset attributes.
- * @param $tag_element {array} The tag element.
+ * @param bool $unset True to unset attributes.
+ * @param array $tag_element The tag element.
*
* @retun {bool}
*/
@@ -1328,7 +1328,6 @@ protected function standardize_tag( $tag_element ) {
$tag_element['atts']['width'],
$tag_element['atts']['height'],
$tag_element['atts']['data-crop'],
- $tag_element['atts']['srcset'],
$tag_element['atts']['data-responsive']
);
@@ -1366,9 +1365,9 @@ protected function standardize_tag( $tag_element ) {
* @hook cloudinary_edit_asset_permalink
* @since 3.2.0
*
- * @param $permalink {string} The permalink.
+ * @param string $permalink The permalink.
*
- * @return {string}
+ * @return string
*/
$permalink = apply_filters( 'cloudinary_edit_asset_permalink', add_query_arg( 'asset', $tag_element['id'], $base_url ) );
@@ -1383,9 +1382,9 @@ protected function standardize_tag( $tag_element ) {
* @hook cloudinary_bypass_seo_url
* @since 3.1.5
*
- * @param $bypass_seo_url {bool} Whether to bypass SEO URLs.
+ * @param bool $bypass_seo_url Whether to bypass SEO URLs.
*
- * @return {bool}
+ * @return bool
*/
$bypass_seo_url = apply_filters( 'cloudinary_bypass_seo_url', false );
@@ -1421,9 +1420,9 @@ public function rebuild_tag( $tag_element ) {
* @since 3.0.0
* @default {true}
*
- * @param $apply {bool} True to apply, false to skip.
+ * @param bool $apply True to apply, false to skip.
*
- * @return {bool}
+ * @return bool
*/
if ( apply_filters( 'cloudinary_apply_breakpoints', true ) ) {
$meta = wp_get_attachment_metadata( $tag_element['id'] );
@@ -1452,9 +1451,9 @@ public function rebuild_tag( $tag_element ) {
* @hook cloudinary_pre_image_tag | cloudinary_pre_video_tag
* @since 2.7.5
*
- * @param $tag_element {array} The tag_element (tag + attributes array).
+ * @param array $tag_element The tag_element (tag + attributes array).
*
- * @return {array}
+ * @return array
*/
$tag_element = apply_filters( "cloudinary_pre_{$tag_element['type']}_tag", $tag_element );
@@ -1473,10 +1472,10 @@ public function rebuild_tag( $tag_element ) {
* @hook cloudinary_image_tag | cloudinary_video_tag
* @since 3.0.0
*
- * @param $replace {string} The new HTML tag.
- * @param $tag_element {array} The tag_element (tag + attributes array).
+ * @param string $replace The new HTML tag.
+ * @param array $tag_element The tag_element (tag + attributes array).
*
- * @return {array}
+ * @return array
*/
return apply_filters( "cloudinary_{$tag_element['type']}_tag", $replace, $tag_element );
}
@@ -1497,10 +1496,10 @@ public function parse_element( $element, $content = '' ) {
* @since 3.2.6
* @default {false}
*
- * @param $skip {bool} True to skip parsing.
- * @param $element {string} The element to parse.
+ * @param bool $skip True to skip parsing.
+ * @param string $element The element to parse.
*
- * @return {bool}
+ * @return bool
*/
if ( apply_filters( 'cloudinary_skip_parse_element', false, $element ) ) {
return null;
@@ -1517,7 +1516,7 @@ public function parse_element( $element, $content = '' ) {
* @since 3.1.3
* @default {false}
*
- * @param $enabeld {bool} Is the Crop and Gravity control enabled?
+ * @param bool $enabeld Is the Crop and Gravity control enabled?
*
* @retrun {bool}
*/
@@ -1693,9 +1692,9 @@ public function parse_element( $element, $content = '' ) {
* @hook cloudinary_parse_element
* @since 3.0.9
*
- * @param $tag_element {array} The tag element.
+ * @param array $tag_element The tag element.
*
- * @return {array} The tag element.
+ * @return array The tag element.
*/
$tag_element = apply_filters( 'cloudinary_parse_element', $tag_element );
@@ -1756,10 +1755,10 @@ protected function is_content_dir( $url ) {
* @hook cloudinary_is_content_dir
* @since 2.7.6
*
- * @param $is_local {bool} If the url is a local asset.
- * @param $url {string} The url.
+ * @param bool $is_local If the url is a local asset.
+ * @param string $url The url.
*
- * @return {bool}
+ * @return bool
*/
return apply_filters( 'cloudinary_is_content_dir', $is_local, $url );
}
@@ -1788,9 +1787,9 @@ protected function is_allowed_type( $ext ) {
* @hook cloudinary_allowed_extensions
* @since 3.0.0
*
- * @param $allowed_types {array} Array of allowed file extensions.
+ * @param array $allowed_types Array of allowed file extensions.
*
- * @return {array}
+ * @return array
*/
$allowed_types = apply_filters( 'cloudinary_allowed_extensions', $allowed_types );
}
@@ -1839,9 +1838,9 @@ protected function set_usability( $item, $auto_sync = null ) {
* @hook cloudinary_set_usable_asset
* @since 3.0.2
*
- * @param $item {array} The found asset array.
+ * @param object $item The found asset object.
*
- * @return {array}
+ * @return object
*/
$item = apply_filters( 'cloudinary_set_usable_asset', $item );
@@ -1851,9 +1850,9 @@ protected function set_usability( $item, $auto_sync = null ) {
* @hook cloudinary_content_url
* @since 3.1.6
*
- * @param $url {string} The default content_url.
+ * @param string $url The default content_url.
*
- * @return {string}
+ * @return string
*/
$content_url = apply_filters( 'cloudinary_content_url', content_url() );
@@ -1870,11 +1869,11 @@ protected function set_usability( $item, $auto_sync = null ) {
* @hook cloudinary_delivery_searchable_url
* @since 3.1.6
*
- * @param $url {string} The URL to be searched for and prepared to be delivered by Cloudinary.
- * @param $item {array} The found asset array.
- * @param $content_url {string} The content URL.
+ * @param string $url The URL to be searched for and prepared to be delivered by Cloudinary.
+ * @param object $item The found asset object.
+ * @param string $content_url The content URL.
*
- * @return {string}
+ * @return string
*/
$url = apply_filters( 'cloudinary_delivery_searchable_url', $url, $item, $content_url );
diff --git a/php/class-extensions.php b/php/class-extensions.php
index 488f27ccc..ed5a9c2c6 100644
--- a/php/class-extensions.php
+++ b/php/class-extensions.php
@@ -174,8 +174,8 @@ public function register_extensions() {
* @hook cloudinary_register_extensions
* @since 3.0.0
*
- * @param $extensions {array) The list of extensions to register.
- * @param $plugin {Plugin} The core plugin object.
+ * @param array $extensions The list of extensions to register.
+ * @param Plugin $plugin The core plugin object.
*/
$extensions = apply_filters( 'cloudinary_register_extensions', $extensions, $this->plugin );
foreach ( $extensions as $slug => $extension ) {
diff --git a/php/class-media.php b/php/class-media.php
index 2bd521279..e9eb695bd 100644
--- a/php/class-media.php
+++ b/php/class-media.php
@@ -177,13 +177,13 @@ public function init_hook() {
* @hook cloudinary_media_filters
* @since 3.0.0
*
- * @param $filters {array} The default filters.
+ * @param array $filters The default filters.
*/
$this->cloudinary_filters = apply_filters(
'cloudinary_media_filters',
array(
- SYNC::META_KEYS['sync_error'] => __( 'Error', 'cloudinary' ),
- SYNC::META_KEYS['unsynced'] => __( 'Unsynced', 'cloudinary' ),
+ Sync::META_KEYS['sync_error'] => __( 'Error', 'cloudinary' ),
+ Sync::META_KEYS['unsynced'] => __( 'Unsynced', 'cloudinary' ),
)
);
}
@@ -323,10 +323,10 @@ public function is_media( $attachment_id ) {
* @since 2.7.6
* @default false
*
- * @param $is_media {bool} Flag if is media.
- * @param $attachment_id {int} The attachment ID.
+ * @param bool $is_media Flag if is media.
+ * @param int $attachment_id The attachment ID.
*
- * @return {bool}
+ * @return bool
*/
return apply_filters( 'cloudinary_is_media', $is_media, $attachment_id );
}
@@ -423,10 +423,10 @@ public function is_uploadable_media( $attachment_id ) {
* @hook cloudinary_is_uploadable_media
* @since 2.7.7
*
- * @param $is_local {bool} The attachment ID.
- * @param $media_host {string} The html tag.
+ * @param bool $is_local The attachment ID.
+ * @param string $media_host The html tag.
*
- * @return {bool}
+ * @return bool
*/
return apply_filters( 'cloudinary_is_uploadable_media', $is_uploadable, $media_host );
}
@@ -1018,7 +1018,7 @@ public function get_crop_transformations( $attachment_id, $size ) {
* @since 3.1.3
* @default {false}
*
- * @param $enabeld {bool} Is the Crop and Gravity control enabled?
+ * @param bool $enabeld Is the Crop and Gravity control enabled?
*
* @retrun {bool}
*/
@@ -1436,7 +1436,7 @@ public function cloudinary_url( $attachment_id, $size = array(), $transformation
// Early bail for admin AJAX requests.
- if ( defined( 'DOING_AJAX' ) && DOING_AJAX && is_admin() ) {
+ if ( wp_doing_ajax() && is_admin() ) {
$cache[ $key ] = $url;
return $cache[ $key ];
@@ -1475,10 +1475,10 @@ public function local_url( $attachment_id ) {
* @hook cloudinary_local_url
* @since 3.0.0
*
- * @param $url {string|false} The local URL
- * @param $attachment_id {int} The attachment ID.
+ * @param string|false $url The local URL
+ * @param int $attachment_id The attachment ID.
*
- * @return {string|false}
+ * @return string|false
*/
return apply_filters( 'cloudinary_local_url', $urls[ $attachment_id ], $attachment_id );
}
@@ -1530,10 +1530,10 @@ public function raw_cloudinary_url( $attachment_id ) {
* @hook cloudinary_raw_url
* @since 3.0.0
*
- * @param $url {string|false} The local URL
- * @param $attachment_id {int} The attachment ID.
+ * @param string|false $url The local URL
+ * @param int $attachment_id The attachment ID.
*
- * @return {string|false}
+ * @return string|false
*/
return apply_filters( 'cloudinary_raw_url', $url, $attachment_id );
}
@@ -2036,11 +2036,11 @@ public function editor_assets() {
* @hook cloudinary_max_files_import
* @since 3.1.3
*
- * @param $max_files {int} The maximum number of files that can be imported from Cloudinary.
+ * @param int $max_files The maximum number of files that can be imported from Cloudinary.
*
* @default 20
*
- * @return {int}
+ * @return int
*
* @example
* is_main_query() ) {
$request = Utils::get_sanitized_text( 'cloudinary-filter' );
- if ( SYNC::META_KEYS['sync_error'] === $request ) {
+ if ( Sync::META_KEYS['sync_error'] === $request ) {
$meta_query = $query->get( 'meta_query' );
if ( ! is_array( $meta_query ) ) {
$meta_query = array();
@@ -3082,7 +3082,7 @@ public function apply_media_library_filters( $query ) {
$query->set( 'meta_query', $meta_query );
}
- if ( SYNC::META_KEYS['unsynced'] === $request ) {
+ if ( Sync::META_KEYS['unsynced'] === $request ) {
global $wpdb;
$wpdb->cld_table = Utils::get_relationship_table();
$result = $wpdb->get_col( "SELECT post_id FROM $wpdb->cld_table WHERE public_id IS NULL" ); // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching
diff --git a/php/class-plugin.php b/php/class-plugin.php
index 8fc848758..d734e1251 100644
--- a/php/class-plugin.php
+++ b/php/class-plugin.php
@@ -212,7 +212,7 @@ public function setup_settings() {
* @hook cloudinary_connected
* @since 3.0.0
*
- * @param $plugin {Plugin} The core plugin object.
+ * @param Plugin $plugin The core plugin object.
*/
do_action( 'cloudinary_connected', $this );
}
@@ -222,7 +222,7 @@ public function setup_settings() {
* @hook cloudinary_init_settings
* @since 2.7.5
*
- * @param $plugin {Plugin} The core plugin object.
+ * @param Plugin $plugin The core plugin object.
*/
do_action( 'cloudinary_init_settings', $this );
@@ -464,7 +464,7 @@ public function setup() {
* @hook cloudinary_ready
* @since 3.0.0
*
- * @param $plugin {Plugin} The core plugin object.
+ * @param Plugin $plugin The core plugin object.
*/
do_action( 'cloudinary_ready', $this );
}
diff --git a/php/class-settings.php b/php/class-settings.php
index 9948400a1..eee38f218 100644
--- a/php/class-settings.php
+++ b/php/class-settings.php
@@ -366,8 +366,8 @@ public function get_value( ...$slugs ) {
*
* @hook cloudinary_setting_get_value
*
- * @param $value {mixed} The setting value.
- * @param $slug {string} The setting slug.
+ * @param mixed $value The setting value.
+ * @param string $slug The setting slug.
*/
$return[ $slug ] = apply_filters( 'cloudinary_setting_get_value', $value, $slug );
}
@@ -530,11 +530,11 @@ public function set_pending( $slug, $new_value, $current_value = null ) {
* @hook cloudinary_settings_save_setting
* @since 2.7.6
*
- * @param $new_value {int} The new setting value.
- * @param $current_value {string} The setting current value.
- * @param $setting {Setting} The setting object.
+ * @param int $new_value The new setting value.
+ * @param string $current_value The setting current value.
+ * @param Setting $setting The setting object.
*
- * @return {mixed}
+ * @return mixed
*/
$new_value = apply_filters( "cloudinary_settings_save_setting_{$slug}", $new_value, $current_value, $setting );
$new_value = apply_filters( 'cloudinary_settings_save_setting', $new_value, $current_value, $setting );
diff --git a/php/class-string-replace.php b/php/class-string-replace.php
index 5b099d628..0e8667dfe 100644
--- a/php/class-string-replace.php
+++ b/php/class-string-replace.php
@@ -81,7 +81,7 @@ protected function admin_filters() {
* Add Public Filters.
*/
protected function public_filters() {
- add_action( 'template_include', array( $this, 'init_debug' ), PHP_INT_MAX );
+ add_filter( 'template_include', array( $this, 'init_debug' ), PHP_INT_MAX );
if ( ! defined( 'REST_REQUEST' ) || ! REST_REQUEST ) { // Not needed on REST API.
add_action( 'parse_request', array( $this, 'init' ), - 1000 ); // Not crazy low, but low enough to catch most cases, but not too low that it may break AMP.
}
@@ -275,8 +275,8 @@ protected function prime_replacements( $content, $context = 'view' ) {
* @hook cloudinary_string_replace
* @since 3.0.3 Added the `$context` argument.
*
- * @param $content {string} The html of the page.
- * @param $context {string} The render context.
+ * @param string $content The html of the page.
+ * @param string $context The render context.
*/
do_action( 'cloudinary_string_replace', $content, $context );
}
diff --git a/php/class-svg.php b/php/class-svg.php
index acb912ade..415f382a4 100644
--- a/php/class-svg.php
+++ b/php/class-svg.php
@@ -245,7 +245,7 @@ public function setup_hooks() {
// Add filters.
add_filter( 'upload_mimes', array( $this, 'add_svg_mime' ) ); // phpcs:ignore WordPressVIPMinimum.Hooks.RestrictedHooks.upload_mimes
add_filter( 'ext2type', array( $this, 'add_svg_ext_type' ) );
- add_filter( 'wp_check_filetype_and_ext', array( $this, 'check_svg_type' ), 10, 4 );
+ add_filter( 'wp_check_filetype_and_ext', array( $this, 'check_svg_type' ), 10, 3 );
add_filter( 'cloudinary_allowed_extensions', array( $this, 'allow_svg_for_cloudinary' ) );
add_filter( 'cloudinary_upload_options', array( $this, 'remove_svg_eagers' ), 10, 2 );
add_filter( 'cloudinary_upload_args', array( $this, 'upload_args' ), 10, 2 );
diff --git a/php/class-sync.php b/php/class-sync.php
index b5e3522fd..fbf39a698 100644
--- a/php/class-sync.php
+++ b/php/class-sync.php
@@ -332,7 +332,9 @@ public function can_sync( $attachment_id, $type = 'file' ) {
* Filter to allow changing if an asset is allowed to be synced.
* Return a WP Error with reason why it can't be synced.
*
- * @param int $attachment_id The attachment post ID.
+ * @param bool|\WP_Error $can Whether the asset can be synced.
+ * @param int $attachment_id The attachment post ID.
+ * @param string $type The sync type.
*
* @return bool|\WP_Error
*/
@@ -386,10 +388,10 @@ public function get_signature( $attachment_id, $cached = true ) {
*
* @hook cloudinary_get_signature
*
- * @param $return {array} The attachment signature.
- * @param $attachment_id {int} The attachment ID.
+ * @param array $return The attachment signature.
+ * @param int $attachment_id The attachment ID.
*
- * @return {array}
+ * @return array
*/
$return = apply_filters( 'cloudinary_get_signature', $return, $attachment_id );
@@ -674,7 +676,7 @@ public function setup_sync_base_struct() {
/**
* Do action for setting up sync types.
*
- * @param \Cloudinary\Sync $this The sync object.
+ * @param \Cloudinary\Sync $sync The sync object.
*/
do_action( 'cloudinary_register_sync_types', $this );
}
@@ -772,10 +774,10 @@ public function get_asset_state( $attachment_id ) {
*
* @hook cloudinary_asset_state
*
- * @param $state {int} The attachment state.
- * @param $attachment_id {int} The attachment ID.
+ * @param int $state The attachment state.
+ * @param int $attachment_id The attachment ID.
*
- * @return {array}
+ * @return array
*/
return apply_filters( 'cloudinary_asset_state', $state, $attachment_id );
}
@@ -806,11 +808,11 @@ public function sync_base( $attachment_id ) {
*
* @hook cloudinary_sync_base
*
- * @param $signatures {array} The attachments required signatures.
- * @param $post {WP_Post} The attachment post.
- * @param $sync {Sync} The sync object instance.
+ * @param array $signatures The attachments required signatures.
+ * @param WP_Post $post The attachment post.
+ * @param Sync $sync The sync object instance.
*
- * @return {array}
+ * @return array
*/
$return = apply_filters( 'cloudinary_sync_base', $return, get_post( $attachment_id ), $this );
@@ -1220,7 +1222,7 @@ public function setup() {
add_filter( 'cloudinary_setting_get_value', array( $this, 'filter_get_cloudinary_folder' ), 10, 2 );
add_filter( 'cloudinary_get_signature', array( $this, 'get_signature_syncable_type' ), 10, 2 );
- add_action( 'admin_init', array( $this, 'maybe_cleanup_errored' ), 10, 2 );
+ add_action( 'admin_init', array( $this, 'maybe_cleanup_errored' ) );
add_action( 'rest_api_init', array( $this, 'rest_api_is_synced_field' ) );
}
diff --git a/php/class-utils.php b/php/class-utils.php
index d733479a8..293552f61 100644
--- a/php/class-utils.php
+++ b/php/class-utils.php
@@ -217,12 +217,12 @@ public static function user_can( $task, $capability = 'manage_options', $context
* 2
* );
*
- * @param $capability {string} The capability.
- * @param $context {string} The context for the task.
- * @param $args {mixed} The optional arguments.
+ * @param string $capability The capability.
+ * @param string $context The context for the task.
+ * @param mixed $args The optional arguments.
*
* @default 'manage_options'
- * @return {string}
+ * @return string
*/
$capability = apply_filters( "cloudinary_task_capability_{$task}", $capability, $context, ...$args );
@@ -248,12 +248,12 @@ public static function user_can( $task, $capability = 'manage_options', $context
* 3
* );
*
- * @param $capability {string} The current capability for the task.
- * @param $task {string} The task.
- * @param $context {string} The context for the task.
- * @param $args {mixed} The optional arguments.
+ * @param string $capability The current capability for the task.
+ * @param string $task The task.
+ * @param string $context The context for the task.
+ * @param mixed $args The optional arguments.
*
- * @return {string}
+ * @return string
*/
$capability = apply_filters( 'cloudinary_task_capability', $capability, $task, $context, ...$args );
// phpcs:enable WordPress.WhiteSpace.DisallowInlineTabs.NonIndentTabsUsed
@@ -400,9 +400,9 @@ protected static function get_upgrade_sequence() {
* @hook cloudinary_upgrade_sequence
* @since 3.0.1
*
- * @param $upgrade_sequence {array} The default sequence.
+ * @param array $upgrade_sequence The default sequence.
*
- * @return {array}
+ * @return array
*/
return apply_filters( 'cloudinary_upgrade_sequence', $upgrade_sequence );
}
@@ -634,7 +634,7 @@ public static function is_frontend_ajax() {
$admin_base = admin_url();
$is_admin = $referer ? 0 === strpos( $referer, $admin_base ) : false;
// Check if this is a frontend ajax request.
- $is_frontend_ajax = ! $is_admin && defined( 'DOING_AJAX' ) && DOING_AJAX;
+ $is_frontend_ajax = ! $is_admin && wp_doing_ajax();
// If it's not an obvious WP ajax request, check if it's a custom frontend ajax request.
if ( ! $is_frontend_ajax && ! $is_admin ) {
// Catch the content type of the $_SERVER['CONTENT_TYPE'] variable.
@@ -883,9 +883,9 @@ public static function maybe_get_third_party_changes( $attributes, $tag ) {
* @hook cloudinary_ignored_data_keywords
* @since 3.0.8
*
- * @param $lazy_keys {array} The built-in ignore data-* keywords.
+ * @param array $lazy_keys The built-in ignore data-* keywords.
*
- * @return {array}
+ * @return array
*/
$filtered_keys = apply_filters( 'cloudinary_ignored_data_keywords', $lazy_keys );
@@ -895,9 +895,9 @@ public static function maybe_get_third_party_changes( $attributes, $tag ) {
* @hook cloudinary_ignored_class_keywords
* @since 3.0.8
*
- * @param $lazy_classes {array} The built-in ignore class keywords.
+ * @param array $lazy_classes The built-in ignore class keywords.
*
- * @return {array}
+ * @return array
*/
$filtered_classes = apply_filters( 'cloudinary_ignored_class_keywords', $lazy_classes );
}
@@ -1083,8 +1083,8 @@ public static function query_relations( $public_ids, $urls = array() ) {
*
* @hook cloudinary_media_context_query
* @since 3.2.0
- * @param $media_context_query {string} The default media context query.
- * @return {string}
+ * @param string $media_context_query The default media context query.
+ * @return string
*/
$media_context_query = apply_filters( 'cloudinary_media_context_query', 'media_context = %s' );
@@ -1243,10 +1243,10 @@ public static function get_media_context( $attachment_id = null ) {
* @since 3.1.9
* @default {'default'}
*
- * @param $media_context {string} The media context.
- * @param $attachment_id {int|null} The attachment ID.
+ * @param string $media_context The media context.
+ * @param int|null $attachment_id The attachment ID.
*
- * @return {string}
+ * @return string
*/
$context = apply_filters( 'cloudinary_media_context', 'default', $attachment_id );
@@ -1267,8 +1267,8 @@ public static function get_media_context_things( $media_context_things = array(
*
* @hook cloudinary_media_context_things
* @since 3.2.0
- * @param $media_context_things {array} The default media context things.
- * @return {array}
+ * @param array $media_context_things The default media context things.
+ * @return array
*/
$media_context_things = apply_filters( 'cloudinary_media_context_things', $media_context_things );
@@ -1296,11 +1296,11 @@ public static function home_url( $path = '', $scheme = null ) {
* @hook cloudinary_home_url
* @since 3.2.0
*
- * @param $home_url {string} The home url.
- * @param $path {string} The path to be appended to the home URL.
- * @param $scheme {string} The scheme to give the home URL context. Accepts 'http', 'https', or 'relative'.
+ * @param string $home_url The home url.
+ * @param string $path The path to be appended to the home URL.
+ * @param string $scheme The scheme to give the home URL context. Accepts 'http', 'https', or 'relative'.
*
- * @return {string}
+ * @return string
*/
return apply_filters( 'cloudinary_home_url', $home_url, $path, $scheme );
}
@@ -1326,11 +1326,11 @@ public static function site_url( $path = '', $scheme = null ) {
* @hook cloudinary_site_url
* @since 3.2.2
*
- * @param $site_url {string} The site URL.
- * @param $path {string} The path to be appended to the site URL.
- * @param $scheme {string} The scheme to give the site URL context. Accepts 'http', 'https', or 'relative'.
+ * @param string $site_url The site URL.
+ * @param string $path The path to be appended to the site URL.
+ * @param string $scheme The scheme to give the site URL context. Accepts 'http', 'https', or 'relative'.
*
- * @return {string}
+ * @return string
*/
return apply_filters( 'cloudinary_site_url', $site_url, $path, $scheme );
}
@@ -1352,11 +1352,11 @@ public static function rest_url( $path = '', $scheme = null ) {
* @hook cloudinary_rest_url
* @since 3.2.2
*
- * @param $rest_url {string} The rest url.
- * @param $path {string} The path to be appended to the rest URL.
- * @param $scheme {string} The scheme to give the rest URL context. Accepts 'http', 'https', or 'relative'.
+ * @param string $rest_url The rest url.
+ * @param string $path The path to be appended to the rest URL.
+ * @param string $scheme The scheme to give the rest URL context. Accepts 'http', 'https', or 'relative'.
*
- * @return {string}
+ * @return string
*/
return apply_filters( 'cloudinary_rest_url', $rest_url, $path, $scheme );
}
@@ -1593,9 +1593,9 @@ public static function sanitize_svg( $svg_content ) {
* @hook cloudinary_allowed_svg_tags
* @since 3.2.15
*
- * @param $allowed_tags {array} The allowed SVG tags and their attributes.
+ * @param array $allowed_tags The allowed SVG tags and their attributes.
*
- * @return {array}
+ * @return array
*/
$allowed_tags = apply_filters( 'cloudinary_allowed_svg_tags', $allowed_tags );
diff --git a/php/connect/class-api.php b/php/connect/class-api.php
index f50701b99..dc5939270 100644
--- a/php/connect/class-api.php
+++ b/php/connect/class-api.php
@@ -209,9 +209,9 @@ public function url( $resource, $function = null, $endpoint = false ) { // phpcs
* @hook cloudinary_bypass_seo_url
* @since 3.1.5
*
- * @param $bypass_seo_url {bool} Whether to bypass SEO URLs.
+ * @param bool $bypass_seo_url Whether to bypass SEO URLs.
*
- * @return {bool}
+ * @return bool
*/
$bypass_seo_url = apply_filters( 'cloudinary_bypass_seo_url', false );
@@ -294,10 +294,10 @@ function ( $item ) use ( $transformation_index ) {
* @hook cloudinary_upload_eager_formats
* @since 3.1.6
*
- * @param $formats {array} The default formats.
- * @param $type {string} The asset type.
+ * @param array $formats The default formats.
+ * @param string $type The asset type.
*
- * @return {array}
+ * @return array
*/
$formats = apply_filters( 'cloudinary_upload_eager_formats', $formats, $type );
@@ -517,10 +517,10 @@ public function upload( $attachment_id, $args, $headers = array(), $try_remote =
* @since 3.1.8
* @default true
*
- * @param $use_original {bool} The default value.
- * @param $attachment_id {int} The attachment ID.
+ * @param bool $use_original The default value.
+ * @param int $attachment_id The attachment ID.
*
- * @return {bool}
+ * @return bool
*/
$use_original = apply_filters( 'cloudinary_use_original_image', true, $attachment_id );
if ( $use_original && function_exists( 'wp_get_original_image_url' ) && wp_attachment_is_image( $attachment_id ) ) {
@@ -598,8 +598,8 @@ public function upload( $attachment_id, $args, $headers = array(), $try_remote =
* @hook cloudinary_upload_args
* @since 3.0.1
*
- * @param $call_args {array} The default args.
- * @param $attachment_id {int} The attachment ID.
+ * @param array $call_args The default args.
+ * @param int $attachment_id The attachment ID.
*/
$call_args = apply_filters( 'cloudinary_upload_args', $call_args, $attachment_id );
@@ -632,8 +632,8 @@ public function upload( $attachment_id, $args, $headers = array(), $try_remote =
* @hook cloudinary_uploaded_asset
* @since 3.0.1
*
- * @param $attachment_id {int} The attachment ID.
- * @param $result {array|WP_Error} The upload result.
+ * @param int $attachment_id The attachment ID.
+ * @param array|WP_Error $result The upload result.
*/
do_action( 'cloudinary_uploaded_asset', $attachment_id, $result );
@@ -897,9 +897,9 @@ public function get_public_id( $attachment_id, $args = array(), $original_public
* @hook cloudinary_bypass_seo_url
* @since 3.1.5
*
- * @param $bypass_seo_url {bool} Whether to bypass SEO URLs.
+ * @param bool $bypass_seo_url Whether to bypass SEO URLs.
*
- * @return {bool}
+ * @return bool
*/
$bypass_seo_url = apply_filters( 'cloudinary_bypass_seo_url', false );
@@ -929,11 +929,11 @@ public function get_public_id( $attachment_id, $args = array(), $original_public
* @hook cloudinary_seo_public_id
* @since 3.1.5
*
- * @param $sufix {string} The public_id suffix.
- * @param $relationship {Relationship} The relationship.
- * @param $attachment_id {int} The attachment ID.
+ * @param string $sufix The public_id suffix.
+ * @param Relationship $relationship The relationship.
+ * @param int $attachment_id The attachment ID.
*
- * @return {string}
+ * @return string
*/
$suffix = apply_filters( 'cloudinary_seo_public_id', "{$filename}.{$relationship->format}", $relationship, $attachment_id );
diff --git a/php/delivery/class-lazy-load.php b/php/delivery/class-lazy-load.php
index e50225ce3..ed52219e4 100644
--- a/php/delivery/class-lazy-load.php
+++ b/php/delivery/class-lazy-load.php
@@ -94,9 +94,9 @@ public function bypass_lazy_load( $bypass, $tag_element ) {
* @hook cloudinary_lazy_load_bypass_classes
* @since 3.0.9
*
- * @param $classes {array} Classes that bypass the Lazy Load.
+ * @param array $classes Classes that bypass the Lazy Load.
*
- * @return {bool}
+ * @return bool
*
* @example
* is_enabled() || Utils::is_amp() || apply_filters( 'cloudinary_lazy_load_bypass', false, $tag_element ) ) {
$tag_element = $this->apply_breakpoints( $tag_element );
diff --git a/php/media/class-global-transformations.php b/php/media/class-global-transformations.php
index aaaf64158..75f93534c 100644
--- a/php/media/class-global-transformations.php
+++ b/php/media/class-global-transformations.php
@@ -596,7 +596,7 @@ public function get_current_post() {
* @hook cloudinary_current_post_id
* @default null
*
- * @return {WP_Post|null}
+ * @return WP_Post|null
*/
$post_id = apply_filters( 'cloudinary_current_post_id', null );
@@ -717,7 +717,7 @@ function ( $taxonomy ) use ( $global ) {
// Add ordering metaboxes and featured overwrite.
add_action( 'add_meta_boxes', array( $this, 'taxonomy_ordering' ), 10, 2 );
add_action( 'save_post', array( $this, 'save_taxonomy_ordering' ), 10, 1 );
- add_action( 'save_post', array( $this, 'save_overwrite_transformations_featured_image' ), 10, 3 );
+ add_action( 'save_post', array( $this, 'save_overwrite_transformations_featured_image' ), 10, 1 );
add_filter( 'admin_post_thumbnail_html', array( $this, 'classic_overwrite_transformations_featured_image' ), 10, 3 );
// Filter and action the custom column.
diff --git a/php/media/class-upgrade.php b/php/media/class-upgrade.php
index 6b2a86479..2db0b1015 100644
--- a/php/media/class-upgrade.php
+++ b/php/media/class-upgrade.php
@@ -64,8 +64,8 @@ public function convert_cloudinary_version( $attachment_id ) {
* @hook cloudinary_upgrade_asset
* @since 3.0.5
*
- * @param $attachment_id {int} The attachment ID.
- * @param $version {string} The current plugin version.
+ * @param int $attachment_id The attachment ID.
+ * @param string $version The current plugin version.
*/
do_action( 'cloudinary_upgrade_asset', $attachment_id, $this->media->plugin->version );
@@ -201,9 +201,18 @@ public function get_fetch_public_id( $path, $attachment_id ) {
*/
public function migrate_legacy_meta( $attachment_id ) {
+ /**
+ * The raw attachment metadata, which may contain plugin-specific keys
+ * beyond WordPress core's documented shape.
+ *
+ * @var array $old_meta
+ */
$old_meta = wp_get_attachment_metadata( $attachment_id, true );
- $v2_meta = get_post_meta( $attachment_id, Sync::META_KEYS['cloudinary_legacy'], true );
- $v3_meta = array();
+ if ( ! is_array( $old_meta ) ) {
+ $old_meta = array();
+ }
+ $v2_meta = get_post_meta( $attachment_id, Sync::META_KEYS['cloudinary_legacy'], true );
+ $v3_meta = array();
// Direct from old meta to v3, create v2 to chain the upgrade path.
if ( isset( $old_meta[ Sync::META_KEYS['cloudinary_legacy'] ] ) && empty( $v2_meta ) ) {
diff --git a/php/media/class-video.php b/php/media/class-video.php
index 01b01cb16..57ab0c2ef 100644
--- a/php/media/class-video.php
+++ b/php/media/class-video.php
@@ -694,7 +694,7 @@ static function ( $return, $tag, $attr, $m ) { // phpcs:ignore Universal.NamingC
return $return;
},
10,
- 5
+ 4
);
}
diff --git a/php/sync/class-sync-queue.php b/php/sync/class-sync-queue.php
index 220b9b7c5..1725171a6 100644
--- a/php/sync/class-sync-queue.php
+++ b/php/sync/class-sync-queue.php
@@ -109,9 +109,9 @@ public function setup( $sync ) {
*
* @hook cloudinary_queue_threads
*
- * @param $count {int} The number of manual sync threads to use.
+ * @param int $count The number of manual sync threads to use.
*
- * @return {int}
+ * @return int
*/
$queue_threads_count = apply_filters( 'cloudinary_queue_threads', 2 );
for ( $i = 0; $i < $queue_threads_count; ++$i ) {
@@ -123,9 +123,9 @@ public function setup( $sync ) {
*
* @hook cloudinary_autosync_threads
*
- * @param $count {int} The number of autosync threads to use.
+ * @param int $count The number of autosync threads to use.
*
- * @return {int}
+ * @return int
*/
$autosync_thread_count = apply_filters( 'cloudinary_autosync_threads', 2 );
for ( $i = 0; $i < $autosync_thread_count; ++$i ) {
@@ -474,9 +474,9 @@ public function build_queue() {
* @hook cloudinary_build_queue_query
* @since 2.7.6
*
- * @param $args {array} The arguments for the query.
+ * @param array $args The arguments for the query.
*
- * @return {array}
+ * @return array
*/
$args = apply_filters( 'cloudinary_build_queue_query', $args );
@@ -740,10 +740,10 @@ protected function get_thread_queue_details( $thread ) {
* @hook cloudinary_thread_queue_details_query
* @since 2.7.6
*
- * @param $args {array} The arguments for the query.
- * @param $thread {string} The thread name.
+ * @param array $args The arguments for the query.
+ * @param string $thread The thread name.
*
- * @return {array}
+ * @return array
*/
$args = apply_filters( 'cloudinary_thread_queue_details_query', $args, $thread );
diff --git a/php/sync/class-unsync.php b/php/sync/class-unsync.php
index 3150b6c55..c903ae307 100644
--- a/php/sync/class-unsync.php
+++ b/php/sync/class-unsync.php
@@ -254,7 +254,7 @@ public function unsync_attachment( $attachment_id ) {
* @hook cloudinary_unsync_asset
* @since 3.0.0
*
- * @param $attachment_id {int} The attachment ID.
+ * @param int $attachment_id The attachment ID.
*/
do_action( 'cloudinary_unsync_asset', $attachment_id );
}
diff --git a/php/ui/class-component.php b/php/ui/class-component.php
index fe8918db6..28514b39c 100644
--- a/php/ui/class-component.php
+++ b/php/ui/class-component.php
@@ -15,6 +15,10 @@
* Abstract Component.
*
* @package Cloudinary\UI
+ *
+ * @method array wrap( array $struct ) Filter the wrap part structure.
+ * @method array header( array $struct ) Filter the header part structure.
+ * @method array hr( array $struct ) Filter the hr part structure.
*/
abstract class Component {
@@ -325,7 +329,7 @@ protected function is_enabled() {
*
* @param bool $echo Flag to echo output or return it.
*
- * @return string
+ * @return string|null
*/
public function render( $echo = false ) { // phpcs:ignore Universal.NamingConventions.NoReservedKeywordParameterNames.echoFound
// Setup the component.
@@ -353,6 +357,8 @@ public function render( $echo = false ) { // phpcs:ignore Universal.NamingConven
return $return;
}
echo $return; // phpcs:ignore WordPress.Security.EscapeOutput
+
+ return null;
}
/**
diff --git a/php/ui/component/class-cache-status.php b/php/ui/component/class-cache-status.php
index ba449b2da..317a0f6ff 100644
--- a/php/ui/component/class-cache-status.php
+++ b/php/ui/component/class-cache-status.php
@@ -16,7 +16,7 @@
*
* @package Cloudinary\UI
*/
-class Cache_Status extends media_status {
+class Cache_Status extends Media_Status {
/** Holds the cache point instance.
*
diff --git a/php/ui/component/class-crops.php b/php/ui/component/class-crops.php
index d3f2e2c41..80878a2c4 100644
--- a/php/ui/component/class-crops.php
+++ b/php/ui/component/class-crops.php
@@ -19,9 +19,9 @@
class Crops extends Select {
/**
- * Holds the demo file name.
+ * Holds the demo file names.
*
- * @var string
+ * @var array
*/
protected $demo_files = array(
'docs/addons/objectdetection/dirt-road-1851258_1280.jpg',
@@ -124,9 +124,9 @@ protected function input( $struct ) {
* @hook cloudinary_registered_sizes
* @since 3.1.3
*
- * @param $demo_files {array} array of demo files.
+ * @param array $demo_files array of demo files.
*
- * @return {array}
+ * @return array
*/
$examples = apply_filters( 'cloudinary_demo_crop_files', $this->demo_files );
diff --git a/phpcs.xml.dist b/phpcs.xml.dist
index eb91779b3..21063c4c4 100644
--- a/phpcs.xml.dist
+++ b/phpcs.xml.dist
@@ -58,5 +58,7 @@
/js/
/node_modules/
/vendor/
+
+ /tests/phpstan/stubs/
*.js
diff --git a/phpstan.neon.dist b/phpstan.neon.dist
new file mode 100644
index 000000000..c4bf7ab4e
--- /dev/null
+++ b/phpstan.neon.dist
@@ -0,0 +1,33 @@
+includes:
+ - vendor/szepeviktor/phpstan-wordpress/extension.neon
+
+parameters:
+ # Persist the result cache in a known project-relative path so CI can cache
+ # it between runs for faster analysis.
+ tmpDir: .phpstan-cache
+ # The HookCallbackRule "action callback should not return anything" check is
+ # too strict for dual-purpose methods that are both called directly (return
+ # value used) and registered on a real action (return value harmlessly
+ # discarded). Genuine filter-vs-action bugs are caught during review. The
+ # rule's argument-count checks (arguments.count) remain active.
+ ignoreErrors:
+ -
+ identifier: return.void
+ message: '#^Action callback returns .+ but should not return anything\.$#'
+ level: 0
+ paths:
+ - php
+ - cloudinary.php
+ scanFiles:
+ - instance.php
+ - vendor/php-stubs/wp-cli-stubs/wp-cli-stubs.php
+ - vendor/php-stubs/wp-cli-stubs/wp-cli-commands-stubs.php
+ - vendor/php-stubs/woocommerce-stubs/woocommerce-stubs.php
+ - tests/phpstan/stubs/wpml.php
+ - tests/phpstan/stubs/wpcom-vip.php
+ excludePaths:
+ - build/*
+ - node_modules/*
+ - vendor/*
+ # Extends WPCOM_VIP_CLI_Command, only available on the WordPress VIP platform.
+ - php/class-cli-vip.php
diff --git a/tests/phpstan/stubs/wpcom-vip.php b/tests/phpstan/stubs/wpcom-vip.php
new file mode 100644
index 000000000..8e48f1962
--- /dev/null
+++ b/tests/phpstan/stubs/wpcom-vip.php
@@ -0,0 +1,17 @@
+