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", diff --git a/src/Modules/Featured_plugins.php b/src/Modules/Featured_plugins.php index e321d290..bf3315c1 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; @@ -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 ); } ); diff --git a/tests/featured-plugins-test.php b/tests/featured-plugins-test.php index 6a5e1fcb..cf61fd93 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,63 @@ 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 ) ); + + + // 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 ) ); + } + }