From 94e9274d32bda46fe675be4160be8bfceb034278 Mon Sep 17 00:00:00 2001 From: "themeisle[bot]" Date: Fri, 29 Mar 2024 10:39:36 +0000 Subject: [PATCH 1/5] chore(release): 3.3.16 [skip ci] ##### [Version 3.3.16](https://github.com/Codeinwp/themeisle-sdk/compare/v3.3.15...v3.3.16) (2024-03-29) ### Improvements - Formbricks on multiple products. - List Pro Products in featured tab. --- CHANGELOG.md | 6 ++++++ composer.json | 2 +- load.php | 2 +- package.json | 2 +- 4 files changed, 9 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index dbe38cb7..8a1b0b49 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,9 @@ +##### [Version 3.3.16](https://github.com/Codeinwp/themeisle-sdk/compare/v3.3.15...v3.3.16) (2024-03-29) + +### Improvements +- Formbricks on multiple products. +- List Pro Products in featured tab. + ##### [Version 3.3.15](https://github.com/Codeinwp/themeisle-sdk/compare/v3.3.14...v3.3.15) (2024-03-26) ### Improvements diff --git a/composer.json b/composer.json index a32427eb..6890c4ae 100644 --- a/composer.json +++ b/composer.json @@ -14,7 +14,7 @@ "homepage": "https://themeisle.com" } ], - "version": "3.3.15", + "version": "3.3.16", "require-dev": { "codeinwp/phpcs-ruleset": "dev-main" }, diff --git a/load.php b/load.php index cdbe0c66..07ce7591 100644 --- a/load.php +++ b/load.php @@ -14,7 +14,7 @@ return; } // Current SDK version and path. -$themeisle_sdk_version = '3.3.15'; +$themeisle_sdk_version = '3.3.16'; $themeisle_sdk_path = dirname( __FILE__ ); global $themeisle_sdk_max_version; diff --git a/package.json b/package.json index c5a66172..2936ce1c 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "themeisle-sdk", "description": "Themeisle SDK", - "version": "3.3.15", + "version": "3.3.16", "scripts": { "dev": "npm run start", "start:promos": "wp-scripts start assets/js/src/index.js --output-path=assets/js/build/promos", From 41c8ee7e27b8f067f46a65cd0092f5972d6b9e25 Mon Sep 17 00:00:00 2001 From: Bogdan Preda Date: Sat, 30 Mar 2024 15:18:23 +0200 Subject: [PATCH 2/5] fix: ensure response is expected type Closes: Codeinwp/neve-pro-addon#2787 --- src/Modules/Featured_plugins.php | 2 +- tests/featured-plugins-test.php | 104 +++++++++++++++++++++++++++++++ 2 files changed, 105 insertions(+), 1 deletion(-) diff --git a/src/Modules/Featured_plugins.php b/src/Modules/Featured_plugins.php index e321d290..b846bdf4 100644 --- a/src/Modules/Featured_plugins.php +++ b/src/Modules/Featured_plugins.php @@ -95,7 +95,7 @@ public function filter_plugin_api_results( $res, $action, $args ) { $featured = $this->query_plugins_by_author( $args ); - $plugins = array_merge( $featured, $res->plugins ); + $plugins = array_merge( $featured, (array) $res->plugins ); $plugins = array_slice( $plugins, 0, $res->info['results'] ); $res->plugins = $plugins; diff --git a/tests/featured-plugins-test.php b/tests/featured-plugins-test.php index 6a5e1fcb..0d181604 100644 --- a/tests/featured-plugins-test.php +++ b/tests/featured-plugins-test.php @@ -5,6 +5,77 @@ * @package ThemeIsleSDK */ + +/** + * Mock the plugins_api function. + * + * @param string $action The API function being performed. + * @param array|object $args Plugin API arguments. + * + * @return object + */ +function plugins_api( $action, $args ) { + return mock_plugin_api_results(); +} + +/** + * Mock the plugin API results. + * + * @return object + */ +function mock_plugin_api_results() { + $featured_plugin = array( + 'name' => 'Featured Plugin', + 'slug' => 'featured-plugin', + 'version' => '7.2.0', + 'author' => 'PHPUnit Featured Plugin', + 'author_profile' => 'https://example.com/featured-plugin', + 'requires' => '6.3', + 'tested' => '6.5', + 'requires_php' => '7.0', + 'requires_plugins' => array(), + 'rating' => 80, + 'ratings' => array( + 5 => 3, + 4 => 0, + 3 => 0, + 2 => 0, + 1 => 1, + ), + 'num_ratings' => 4, + 'support_threads' => 1, + 'support_threads_resolved' => 0, + 'active_installs' => 6000, + 'downloaded' => 316410, + 'last_updated' => '2024-03-11 9:17pm GMT', + 'added' => '2021-02-11', + 'homepage' => '', + 'short_description' => 'Short Desc', + 'description' => 'Long Desc', + 'download_link' => 'https://example.com/plugin/featured-plugin.7.2.0.zip', + 'tags' => array( + 'auto-update' => 'auto-update', + 'failure' => 'failure', + 'feature-plugin' => 'feature-plugin', + 'update' => 'update', + ), + 'donate_link' => '', + 'icons' => array( + '1x' => 'https://example.com/featured-plugin/assets/icon.svg?rev=2787335', + 'svg' => 'https://example.com/featured-plugin/assets/icon.svg?rev=2787335', + ), + ); + + $results = array( $featured_plugin ); + + $api_result = new stdClass(); + $api_result->info = new stdClass(); + $api_result->plugins = $results; + $api_result->info = array( 'results' => 1 ); + + return $api_result; +} + /** * Test Featured Plugins loading. */ @@ -93,4 +164,37 @@ public function test_plugins_api_will_not_add_filter_if_marked_as_registered() { $this->assertTrue( (bool) has_filter( 'plugins_api_result', [ $module, 'filter_plugin_api_results' ] ) ); } + /** + * Test that even if a previous filter mutates the result type properties, the plugin API filter still works. + */ + public function test_plugins_api_result_filter() { + wp_set_current_user( self::$admin_id ); + $plugin = dirname( __FILE__ ) . '/sample_products/sample_pro_plugin/plugin_file.php'; + $plugin_product = new \ThemeisleSDK\Product( $plugin ); + + $module = new \ThemeisleSDK\Modules\Featured_Plugins(); + $module->load( $plugin_product ); + + $api_result = plugins_api( 'query_plugins', array() ); + $args = new stdClass(); + $args->page = 1; + $args->per_page = 36; + $args->browse = 'featured'; + $args->wp_version = '6.4'; + + $filtered_api_result = apply_filters( 'plugins_api_result', $api_result, 'query_plugins', $args ); + $this->assertEquals( 1, count( $filtered_api_result->plugins ) ); + + // Mutate the plugins property to be an object. + add_filter( 'plugins_api_result', function( $results, $action, $args ) { + $results->plugins = (object) $results->plugins; + return $results; + }, 9, 3 ); + + // This should also pass if the result type properties are mutated. + $filtered_api_result = apply_filters( 'plugins_api_result', $api_result, 'query_plugins', $args ); + $this->assertEquals( 1, count( $filtered_api_result->plugins ) ); + + } + } From 51a6dcc17d521779b9b721887c06022772b32c39 Mon Sep 17 00:00:00 2001 From: Bogdan Preda Date: Sat, 30 Mar 2024 15:25:12 +0200 Subject: [PATCH 3/5] chore: enforce array when filtering --- src/Modules/Featured_plugins.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Modules/Featured_plugins.php b/src/Modules/Featured_plugins.php index b846bdf4..bf3315c1 100644 --- a/src/Modules/Featured_plugins.php +++ b/src/Modules/Featured_plugins.php @@ -155,7 +155,8 @@ private function get_plugins_filtered_from_author( $args, $filter_slugs = [], $a $filtered = array_filter( $api->plugins, function( $plugin ) use ( $filter_slugs ) { - return in_array( $plugin['slug'], $filter_slugs ); + $array_plugin = (array) $plugin; + return in_array( $array_plugin['slug'], $filter_slugs ); } ); From 9315b785c41e59083b448cd3d2b14efdc1a9f499 Mon Sep 17 00:00:00 2001 From: Bogdan Preda Date: Sat, 30 Mar 2024 15:26:15 +0200 Subject: [PATCH 4/5] chore: code style --- tests/featured-plugins-test.php | 93 +++++++++++++++++---------------- 1 file changed, 49 insertions(+), 44 deletions(-) diff --git a/tests/featured-plugins-test.php b/tests/featured-plugins-test.php index 0d181604..70d09fdf 100644 --- a/tests/featured-plugins-test.php +++ b/tests/featured-plugins-test.php @@ -9,8 +9,8 @@ /** * Mock the plugins_api function. * - * @param string $action The API function being performed. - * @param array|object $args Plugin API arguments. + * @param string $action The API function being performed. + * @param array|object $args Plugin API arguments. * * @return object */ @@ -25,53 +25,53 @@ function plugins_api( $action, $args ) { */ function mock_plugin_api_results() { $featured_plugin = array( - 'name' => 'Featured Plugin', - 'slug' => 'featured-plugin', - 'version' => '7.2.0', - 'author' => 'PHPUnit Featured Plugin', - 'author_profile' => 'https://example.com/featured-plugin', - 'requires' => '6.3', - 'tested' => '6.5', - 'requires_php' => '7.0', - 'requires_plugins' => array(), - 'rating' => 80, - 'ratings' => array( + 'name' => 'Featured Plugin', + 'slug' => 'featured-plugin', + 'version' => '7.2.0', + 'author' => 'PHPUnit Featured Plugin', + 'author_profile' => 'https://example.com/featured-plugin', + 'requires' => '6.3', + 'tested' => '6.5', + 'requires_php' => '7.0', + 'requires_plugins' => array(), + 'rating' => 80, + 'ratings' => array( 5 => 3, 4 => 0, 3 => 0, 2 => 0, 1 => 1, ), - 'num_ratings' => 4, - 'support_threads' => 1, + 'num_ratings' => 4, + 'support_threads' => 1, 'support_threads_resolved' => 0, - 'active_installs' => 6000, - 'downloaded' => 316410, - 'last_updated' => '2024-03-11 9:17pm GMT', - 'added' => '2021-02-11', - 'homepage' => '', - 'short_description' => 'Short Desc', - 'description' => 'Long Desc', - 'download_link' => 'https://example.com/plugin/featured-plugin.7.2.0.zip', - 'tags' => array( - 'auto-update' => 'auto-update', - 'failure' => 'failure', + 'active_installs' => 6000, + 'downloaded' => 316410, + 'last_updated' => '2024-03-11 9:17pm GMT', + 'added' => '2021-02-11', + 'homepage' => '', + 'short_description' => 'Short Desc', + 'description' => 'Long Desc', + 'download_link' => 'https://example.com/plugin/featured-plugin.7.2.0.zip', + 'tags' => array( + 'auto-update' => 'auto-update', + 'failure' => 'failure', 'feature-plugin' => 'feature-plugin', - 'update' => 'update', + 'update' => 'update', ), - 'donate_link' => '', - 'icons' => array( - '1x' => 'https://example.com/featured-plugin/assets/icon.svg?rev=2787335', + 'donate_link' => '', + 'icons' => array( + '1x' => 'https://example.com/featured-plugin/assets/icon.svg?rev=2787335', 'svg' => 'https://example.com/featured-plugin/assets/icon.svg?rev=2787335', ), ); $results = array( $featured_plugin ); - $api_result = new stdClass(); - $api_result->info = new stdClass(); - $api_result->plugins = $results; - $api_result->info = array( 'results' => 1 ); + $api_result = new stdClass(); + $api_result->info = new stdClass(); + $api_result->plugins = $results; + $api_result->info = array( 'results' => 1 ); return $api_result; } @@ -175,21 +175,26 @@ public function test_plugins_api_result_filter() { $module = new \ThemeisleSDK\Modules\Featured_Plugins(); $module->load( $plugin_product ); - $api_result = plugins_api( 'query_plugins', array() ); - $args = new stdClass(); - $args->page = 1; - $args->per_page = 36; - $args->browse = 'featured'; - $args->wp_version = '6.4'; + $api_result = plugins_api( 'query_plugins', array() ); + $args = new stdClass(); + $args->page = 1; + $args->per_page = 36; + $args->browse = 'featured'; + $args->wp_version = '6.4'; $filtered_api_result = apply_filters( 'plugins_api_result', $api_result, 'query_plugins', $args ); $this->assertEquals( 1, count( $filtered_api_result->plugins ) ); // Mutate the plugins property to be an object. - add_filter( 'plugins_api_result', function( $results, $action, $args ) { - $results->plugins = (object) $results->plugins; - return $results; - }, 9, 3 ); + add_filter( + 'plugins_api_result', + function( $results, $action, $args ) { + $results->plugins = (object) $results->plugins; + return $results; + }, + 9, + 3 + ); // This should also pass if the result type properties are mutated. $filtered_api_result = apply_filters( 'plugins_api_result', $api_result, 'query_plugins', $args ); From 02a8c4e744e9281182f399c6ca948fbe16a48e4c Mon Sep 17 00:00:00 2001 From: Bogdan Preda Date: Sat, 30 Mar 2024 19:11:44 +0200 Subject: [PATCH 5/5] chore: test also element from plugins list as object --- tests/featured-plugins-test.php | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/tests/featured-plugins-test.php b/tests/featured-plugins-test.php index 70d09fdf..cf61fd93 100644 --- a/tests/featured-plugins-test.php +++ b/tests/featured-plugins-test.php @@ -193,13 +193,34 @@ function( $results, $action, $args ) { return $results; }, 9, - 3 + 3 ); // This should also pass if the result type properties are mutated. $filtered_api_result = apply_filters( 'plugins_api_result', $api_result, 'query_plugins', $args ); $this->assertEquals( 1, count( $filtered_api_result->plugins ) ); + + // Mutate a plugin from list to be an object. + add_filter( + 'plugins_api_result', + function( $results, $action, $args ) { + $plugin = $results->plugins[0]; + $plugin['name'] = 'Optimole'; + $plugin['slug'] = 'optimole-wp'; + $plugins = $results->plugins; + $plugins[] = (object) $plugin; + $results->plugins = $plugins; + + return $results; + }, + 11, + 3 + ); + + // This should also pass if the plugin array contains a object within the list. + $filtered_api_result = apply_filters( 'plugins_api_result', $api_result, 'query_plugins', $args ); + $this->assertEquals( 2, count( $filtered_api_result->plugins ) ); } }