From 3413a8e08dbef5fddac98d8fa7d12ea843869f23 Mon Sep 17 00:00:00 2001 From: Michael Lee Date: Tue, 15 Oct 2024 10:02:49 +0100 Subject: [PATCH 01/49] Initial commit --- composer.json | 20 ++ src/Controller/PluginFamily.php | 226 +++++++++++++++++++++++ src/Controller/PluginFamilyInterface.php | 21 +++ src/Model/PluginFamily.php | 145 +++++++++++++++ src/Model/wp_media_plugins.php | 66 +++++++ 5 files changed, 478 insertions(+) create mode 100644 composer.json create mode 100644 src/Controller/PluginFamily.php create mode 100644 src/Controller/PluginFamilyInterface.php create mode 100644 src/Model/PluginFamily.php create mode 100644 src/Model/wp_media_plugins.php diff --git a/composer.json b/composer.json new file mode 100644 index 0000000..29b71f9 --- /dev/null +++ b/composer.json @@ -0,0 +1,20 @@ +{ + "name": "wp-media/wp-media-plugin-family", + "description": "Organizes and displays WP Media plugin family across other members.", + "license": "GPL-3.0-or-later", + "authors": [ + { + "name": "WP Media", + "email": "contact@wp-media.me", + "homepage": "https://wp-media.me" + } + ], + "config": { + "sort-packages": true + }, + "autoload": { + "psr-4": { + "WPMediaPluginFamily\\": "src/" + } + } +} \ No newline at end of file diff --git a/src/Controller/PluginFamily.php b/src/Controller/PluginFamily.php new file mode 100644 index 0000000..c1c1ffc --- /dev/null +++ b/src/Controller/PluginFamily.php @@ -0,0 +1,226 @@ + 'install_activate', + ]; + } + + /** + * Process to install and activate plugin. + * + * @return void + */ + public function install_activate() { + if ( ! $this->is_allowed() ) { + wp_die( + 'Plugin Installation is not allowed.', + '', + [ 'back_link' => true ] + ); + } + + // Install plugin. + $this->install(); + + // Activate plugin + $result = activate_plugin( $this->get_plugin(), '', is_multisite() ); + + if ( is_wp_error( $result ) ) { + $this->set_error( $result ); + } + + wp_safe_redirect( wp_get_referer() ); + exit; + } + + /** + * Install plugin. + * + * @return void + */ + private function install() { + if ( $this->is_installed() ) { + return; + } + + require_once ABSPATH . 'wp-admin/includes/class-wp-upgrader.php'; + + $upgrader = new \Plugin_Upgrader( new \Automatic_Upgrader_Skin() ); + $result = $upgrader->install( $this->get_download_url() ); + + if ( is_wp_error( $result ) ) { + $this->set_error( $result ); + } + + clearstatcache(); + } + + /** + * Check if plugin is installed. + * + * @return boolean + */ + private function is_installed(): bool { + return file_exists( WP_PLUGIN_DIR . '/'. $this->get_plugin() ); + } + + /** + * Check if installation is allowed. + * + * @return boolean + */ + private function is_allowed(): bool { + if ( ! wp_verify_nonce( $_GET['_wpnonce'], 'plugin_family_install_' . $this->get_slug() ) ) { + return false; + } + + if ( ! current_user_can( is_multisite() ? 'manage_network_plugins' : 'install_plugins' ) ) { + return false; + } + + return true; + } + + /** + * Get plugin slug. + * + * @return string + */ + private function get_slug(): string { + return dirname( sanitize_text_field( urldecode( $_GET['plugin_to_install'] ) ) ); + } + + /** + * Get plugin identifier. + * + * @return void + */ + private function get_plugin() { + return sanitize_text_field( urldecode( $_GET['plugin_to_install'] ) ) . '.php'; + } + + /** + * Get plugin download url. + * + * @return void + */ + private function get_download_url() { + require_once ABSPATH . 'wp-admin/includes/plugin-install.php'; + + $data = [ + 'slug' => $this->get_slug(), + 'fields' => [ + 'download_link' => true, + 'short_description' => false, + 'sections' => false, + 'rating' => false, + 'ratings' => false, + 'downloaded' => false, + 'last_updated' => false, + 'added' => false, + 'tags' => false, + 'homepage' => false, + 'donate_link' => false, + ] + ]; + + // Get Plugin Infos. + $plugin_info = plugins_api( 'plugin_information', $data ); + + if ( is_wp_error( $plugin_info ) ) { + $this->set_error( $plugin_info ); + } + + return $plugin_info->download_link; + } + + /** + * Maybe display error notice. + * + * @return void + */ + public function display_error_notice() { + $errors = get_transient( $this->error_transient ); + + if ( ! $errors ) { + return; + } + + if ( ! is_wp_error( $errors ) ) { + delete_transient( $this->error_transient ); + return; + } + + $errors = $errors->get_error_messages(); + + if ( ! $errors ) { + $errors[] = 'Installation process failed'; + } + + echo '

' . implode( '
', $errors ) . '

'; + + // Remove transient after displaying notice. + delete_transient( $this->error_transient ); + } + + /** + * Store an error message in a transient then redirect. + * + * @param object $error A WP_Error object. + * @return void + */ + private function set_error( $error ) { + set_transient( $this->error_transient, $error, 30 ); + + wp_safe_redirect( wp_get_referer() ); + exit; + } +} \ No newline at end of file diff --git a/src/Controller/PluginFamilyInterface.php b/src/Controller/PluginFamilyInterface.php new file mode 100644 index 0000000..753ea76 --- /dev/null +++ b/src/Controller/PluginFamilyInterface.php @@ -0,0 +1,21 @@ +filter_plugins_by_activation( $plugins, $main_plugin ); + } + + /** + * Filter plugins family data by activation status and returns both categorized and uncategorized format. + * + * @param array $plugins Array of family plugins. + * @param string $main_plugin Main plugin installed. + * + * @return array + */ + public function filter_plugins_by_activation( array $plugins, string $main_plugin ): array { + if ( ! is_array( $plugins ) || empty( $plugins ) ) { + return []; + } + + list( $active_plugins, $inactive_plugins ) = [ [], [] ]; + + foreach ( $plugins as $cat => $cat_data ) { + foreach ( $cat_data['plugins'] as $plugin => $data ) { + + $plugin_path = $plugin . '.php'; + $plugin_slug = dirname( $plugin ); + $main_plugin_slug = dirname( $main_plugin ); + + /** + * Check for activated plugins and pop them out of the array + * to re-add them back using array_merge to be displayed after + * plugins that are not installed or not activated. + */ + if ( is_plugin_active( $plugin_path ) ) { + // set cta data of active plugins. + $plugins[ $cat ]['plugins'][ $plugin ]['cta'] = [ + 'text' => 'Activated', + 'url' => '#', + ]; + + // Send active plugin to new array. + $active_plugins[ $plugin ] = $plugins[ $cat ]['plugins'][ $plugin ]; + + // Remove active plugin from current category. + unset( $cat_data['plugins'][ $plugin ] ); + + // Send active plugin to the end of array in current category. + $cat_data['plugins'][ $plugin ] = $plugins[ $cat ]['plugins'][ $plugin ]; + + // Remove category with active plugin from current array. + unset( $plugins[ $cat ] ); + + // Send category with active plugins to the end of array. + $plugins[ $cat ] = $cat_data; + continue; + } + + $install_activate_url = admin_url( 'admin-post.php' ); + + $args = [ + 'action' => 'plugin_family_install_' . $plugin_slug, + '_wpnonce' => wp_create_nonce( 'plugin_family_install_' . $plugin_slug ), + 'plugin_to_install' => urlencode( $plugin ), + ]; + + if ( 'imagify-plugin' === $plugin_slug ) { + $args = [ + 'action' => 'install_imagify_from_partner_' . $main_plugin_slug, + '_wpnonce' => wp_create_nonce( 'install_imagify_from_partner' ), + '_wp_http_referer' => rawurlencode( $this->get_current_url() ), + ]; + } + + $install_activate_url = add_query_arg( $args, $install_activate_url ); + + // Set Installation link + $plugins[ $cat ]['plugins'][ $plugin ]['cta'] = [ + 'text' => 'Install', + 'url' => $install_activate_url, + ]; + + // Create unique CTA data for WP Rocket. + if ( 'wp-rocket/wp-rocket' === $plugin ) { + $plugins[ $cat ]['plugins'][ $plugin ]['cta'] = [ + 'text' => 'Get it Now', + 'url' => 'https://wp-rocket.me/?utm_source=imagify-coupon&utm_medium=plugin&utm_campaign=imagify', + ]; + } + + // Set activation text. + if ( file_exists( WP_PLUGIN_DIR . '/'. $plugin_path ) ) { + $plugins[ $cat ]['plugins'][ $plugin ]['cta']['text'] = 'Activate'; + } + + // Send inactive plugins to new array. + $inactive_plugins[ $plugin ] = $plugins[ $cat ]['plugins'][ $plugin ]; + } + + // Remove main plugin from categorized array. + if ( isset( $plugins[ $cat ]['plugins'][ $main_plugin ] ) ) { + unset( $plugins[ $cat ]['plugins'][ $main_plugin ] ); + } + } + + $uncategorized = array_merge( $inactive_plugins, $active_plugins ); + // Remove main plugin from uncategorized array. + unset( $uncategorized[ $main_plugin ] ); + + return [ + 'categorized' => $plugins, + 'uncategorized' => $uncategorized, + ]; + } + + /** + * Get the current URL. + * Gotten from Imagify_Partner Package. + * + * @return string + */ + private function get_current_url(): string { + $port = (int) $_SERVER['SERVER_PORT']; + $port = 80 !== $port && 443 !== $port ? ( ':' . $port ) : ''; + $url = ! empty( $GLOBALS['HTTP_SERVER_VARS']['REQUEST_URI'] ) ? $GLOBALS['HTTP_SERVER_VARS']['REQUEST_URI'] : ( ! empty( $_SERVER['REQUEST_URI'] ) ? $_SERVER['REQUEST_URI'] : '' ); + + return 'http' . ( is_ssl() ? 's' : '' ) . '://' . $_SERVER['HTTP_HOST'] . $port . $url; + } +} diff --git a/src/Model/wp_media_plugins.php b/src/Model/wp_media_plugins.php new file mode 100644 index 0000000..9490563 --- /dev/null +++ b/src/Model/wp_media_plugins.php @@ -0,0 +1,66 @@ + [ + 'title' => 'Optimize Performance', + 'plugins' => [ + 'wp-rocket/wp-rocket' => [ + 'logo' => [ + 'file' => 'logo-wp-rocket.svg', + 'width' => '50%', + ], + 'title' => 'Speed Up Your Website, Instantly', + 'desc' => 'WP Rocket is the easiest way to make your WordPress website faster and boost your Google PageSpeed score. Get more traffic, better engagement, and higher conversions effortlessly.', + 'link' => 'https://wp-rocket.me/?utm_source=imagify-coupon&utm_medium=plugin&utm_campaign=imagify', + ], + 'imagify-plugin/imagify' => [ + 'logo' => [ + 'file' => 'logo-imagify.svg', + 'width' => '50%', + ], + 'title' => 'Speed Up Your Website With Lighter Images', + 'desc' => 'Imagify is the easiest WordPress image optimizer. It automatically compresses images, converts them to WebP and AVIF formats, and lets you resize and optimize with just one click!', + 'link' => 'https://imagify.io/', + ], + ], + ], + 'boost_traffic' => [ + 'title' => 'Boost Traffic', + 'plugins' => [ + 'seo-by-rank-math/rank-math' => [ + 'logo' => [ + 'file' => 'logo-rank-math.svg', + 'width' => '60%', + ], + 'title' => 'The Swiss Army Knife of SEO Tools', + 'desc' => 'Rank Math SEO is the Best WordPress SEO plugin with the features of many SEO and AI SEO tools in a single package to help multiply your SEO traffic.', + 'link' => 'https://rankmath.com/wordpress/plugin/seo-suite/', + ], + ], + ], + 'protect_secure' => [ + 'title' => 'Protect & Secure', + 'plugins' => [ + 'backwpup/backwpup' => [ + 'logo' => [ + 'file' => 'logo-backwpup.svg', + 'width' => '60%', + ], + 'title' => 'The Easiest Way to Protect Your Website', + 'desc' => 'BackWPup is the most comprehensive and user-friendly backup & restore plugin for WordPress. Easily schedule automatic backups, securely store and restore with just a few clicks!', + 'link' => 'https://backwpup.com/', + ], + 'uk-cookie-consent/uk-cookie-consent' => [ + 'logo' => [ + 'file' => 'logo-termly.svg', + 'width' => '50%', + ], + 'title' => 'GDPR/CCPA Cookie Consent Banner', + 'desc' => 'One of the easiest, most comprehensive, and popular cookie consent plugins available. Google Gold Certified Partner to quickly comply with data privacy laws from around the world.', + 'link' => 'https://termly.io/resources/articles/wordpress-cookies-guide/', + ], + ], + ], +]; \ No newline at end of file From d8ec45716267f72ad12e0f71bafcd0683ad01ff1 Mon Sep 17 00:00:00 2001 From: Michael Lee Date: Tue, 15 Oct 2024 11:39:56 +0100 Subject: [PATCH 02/49] Added phpcs --- .github/workflows/lint_phpcs.yml | 38 ++++++++++++++++++++++++++++++++ composer.json | 19 +++++++++++++--- 2 files changed, 54 insertions(+), 3 deletions(-) create mode 100644 .github/workflows/lint_phpcs.yml diff --git a/.github/workflows/lint_phpcs.yml b/.github/workflows/lint_phpcs.yml new file mode 100644 index 0000000..96cc66e --- /dev/null +++ b/.github/workflows/lint_phpcs.yml @@ -0,0 +1,38 @@ +name: PHP CodeSniffer lint + +on: + pull_request: + branches: + - trunk + - develop + - branch-* + - enhancement/* + +jobs: + run: + runs-on: ${{ matrix.operating-system }} + + strategy: + fail-fast: false + matrix: + operating-system: [ubuntu-latest] + php-versions: ['8.2'] + + name: WP Media Plugin Family lint with PHPCS. PHP ${{ matrix.php-versions }} on ${{ matrix.operating-system }}. + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Setup PHP + uses: shivammathur/setup-php@v2 + with: + php-version: ${{ matrix.php-versions }} + coverage: none # XDebug can be enabled here 'coverage: xdebug' + tools: composer:v2 + + - name: Install dependencies + run: composer install --prefer-dist --no-interaction --no-scripts + + - name: Lint with phpcs + run: composer phpcs + diff --git a/composer.json b/composer.json index 29b71f9..beaeda2 100644 --- a/composer.json +++ b/composer.json @@ -10,11 +10,24 @@ } ], "config": { - "sort-packages": true + "sort-packages": true, + "allow-plugins": { + "dealerdirect/phpcodesniffer-composer-installer": true + } }, + "require-dev": { + "phpcompatibility/phpcompatibility-wp": "^2.0", + "dealerdirect/phpcodesniffer-composer-installer": "^0.7.0", + "wp-coding-standards/wpcs": "^3" + }, "autoload": { "psr-4": { "WPMediaPluginFamily\\": "src/" } - } -} \ No newline at end of file + }, + "scripts": { + "install-codestandards": "Dealerdirect\\Composer\\Plugin\\Installers\\PHPCodeSniffer\\Plugin::run", + "phpcs": "phpcs --basepath=.", + "phpcs:fix": "phpcbf" + } +} From f92f8d54fc042339400abe7100eed061f963c7ea Mon Sep 17 00:00:00 2001 From: Michael Lee Date: Tue, 15 Oct 2024 11:40:14 +0100 Subject: [PATCH 03/49] Added lint config --- phpcs.xml | 58 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 58 insertions(+) create mode 100644 phpcs.xml diff --git a/phpcs.xml b/phpcs.xml new file mode 100644 index 0000000..baa9bd0 --- /dev/null +++ b/phpcs.xml @@ -0,0 +1,58 @@ + + + The custom ruleset for WP Media Plugin Family. + + + + + + + src + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + From f402c43cfa6406f5ae01313f86b7a9461d382cee Mon Sep 17 00:00:00 2001 From: Michael Lee Date: Tue, 15 Oct 2024 11:41:01 +0100 Subject: [PATCH 04/49] Updated config file --- phpcs.xml | 3 --- 1 file changed, 3 deletions(-) diff --git a/phpcs.xml b/phpcs.xml index baa9bd0..c31f2cb 100644 --- a/phpcs.xml +++ b/phpcs.xml @@ -6,11 +6,8 @@ - src - - From 7742694e7a065c64c11266a7a92e83a8896438e4 Mon Sep 17 00:00:00 2001 From: Michael Lee Date: Tue, 15 Oct 2024 11:41:40 +0100 Subject: [PATCH 05/49] Added gitignore --- .gitignore | 1 + 1 file changed, 1 insertion(+) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..49ce3c1 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +/vendor \ No newline at end of file From 4cbcbc23f4ed6dcc6aa54b5767b043aa3ded70ff Mon Sep 17 00:00:00 2001 From: Michael Lee Date: Tue, 15 Oct 2024 11:41:57 +0100 Subject: [PATCH 06/49] Fixed phpcs errors --- src/Controller/PluginFamily.php | 426 ++++++++++++----------- src/Controller/PluginFamilyInterface.php | 26 +- src/Model/PluginFamily.php | 272 ++++++++------- src/Model/wp_media_plugins.php | 123 +++---- 4 files changed, 428 insertions(+), 419 deletions(-) diff --git a/src/Controller/PluginFamily.php b/src/Controller/PluginFamily.php index c1c1ffc..b1d856a 100644 --- a/src/Controller/PluginFamily.php +++ b/src/Controller/PluginFamily.php @@ -4,223 +4,227 @@ defined( 'ABSPATH' ) || exit; +/** + * Handles installation and Activation of plugin family members. + */ class PluginFamily implements PluginFamilyInterface { - /** - * Error transient. - * - * @var string - */ - protected $error_transient = 'plugin_family_error'; + /** + * Error transient. + * + * @var string + */ + protected $error_transient = 'plugin_family_error'; - /** + /** * Returns an array of events this subscriber listens to * * @return array */ - public static function get_subscribed_events (): array { - $events = self::get_post_install_event(); - $events['admin_notices'] = 'display_error_notice'; - - return $events; - } - - /** - * Set post install event. - * - * @return array - */ - private static function get_post_install_event(): array { - $allowed_plugin = [ - 'uk-cookie-consent', - 'backwpup', - 'imagify-plugin', - 'seo-by-rank-math', - ]; - - if ( ! isset( $_GET['action'], $_GET['_wpnonce'], $_GET['plugin_to_install'] ) ) { - return []; - } - - $plugin = str_replace( 'plugin_family_install_', '', sanitize_text_field( $_GET['action'] ) ); - - if ( ! in_array( $plugin, $allowed_plugin ) ) { - return []; - } - - return [ - 'admin_post_plugin_family_install_' . $plugin => 'install_activate', - ]; - } - - /** - * Process to install and activate plugin. - * - * @return void - */ - public function install_activate() { - if ( ! $this->is_allowed() ) { - wp_die( - 'Plugin Installation is not allowed.', - '', - [ 'back_link' => true ] - ); - } - - // Install plugin. - $this->install(); - - // Activate plugin - $result = activate_plugin( $this->get_plugin(), '', is_multisite() ); - - if ( is_wp_error( $result ) ) { - $this->set_error( $result ); - } - - wp_safe_redirect( wp_get_referer() ); - exit; - } - - /** - * Install plugin. - * - * @return void - */ - private function install() { - if ( $this->is_installed() ) { - return; - } - - require_once ABSPATH . 'wp-admin/includes/class-wp-upgrader.php'; - - $upgrader = new \Plugin_Upgrader( new \Automatic_Upgrader_Skin() ); - $result = $upgrader->install( $this->get_download_url() ); - - if ( is_wp_error( $result ) ) { - $this->set_error( $result ); - } - - clearstatcache(); - } - - /** - * Check if plugin is installed. - * - * @return boolean - */ - private function is_installed(): bool { - return file_exists( WP_PLUGIN_DIR . '/'. $this->get_plugin() ); - } - - /** - * Check if installation is allowed. - * - * @return boolean - */ - private function is_allowed(): bool { - if ( ! wp_verify_nonce( $_GET['_wpnonce'], 'plugin_family_install_' . $this->get_slug() ) ) { - return false; - } + public static function get_subscribed_events(): array { + $events = self::get_post_install_event(); + $events['admin_notices'] = 'display_error_notice'; + + return $events; + } + + /** + * Set post install event. + * + * @return array + */ + private static function get_post_install_event(): array { + $allowed_plugin = [ + 'uk-cookie-consent', + 'backwpup', + 'imagify-plugin', + 'seo-by-rank-math', + ]; + + if ( ! isset( $_GET['action'], $_GET['_wpnonce'], $_GET['plugin_to_install'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended + return []; + } + + $plugin = str_replace( 'plugin_family_install_', '', sanitize_text_field( wp_unslash( $_GET['action'] ) ) ); // phpcs:ignore WordPress.Security.NonceVerification.Recommended + + if ( ! in_array( $plugin, $allowed_plugin, true ) ) { + return []; + } + + return [ + 'admin_post_plugin_family_install_' . $plugin => 'install_activate', + ]; + } + + /** + * Process to install and activate plugin. + * + * @return void + */ + public function install_activate() { + if ( ! $this->is_allowed() ) { + wp_die( + 'Plugin Installation is not allowed.', + '', + [ 'back_link' => true ] + ); + } + + // Install plugin. + $this->install(); + + // Activate plugin. + $result = activate_plugin( $this->get_plugin(), '', is_multisite() ); + + if ( is_wp_error( $result ) ) { + $this->set_error( $result ); + } + + wp_safe_redirect( wp_get_referer() ); + exit; + } + + /** + * Install plugin. + * + * @return void + */ + private function install() { + if ( $this->is_installed() ) { + return; + } + + require_once ABSPATH . 'wp-admin/includes/class-wp-upgrader.php'; + + $upgrader = new \Plugin_Upgrader( new \Automatic_Upgrader_Skin() ); + $result = $upgrader->install( $this->get_download_url() ); + + if ( is_wp_error( $result ) ) { + $this->set_error( $result ); + } + + clearstatcache(); + } + + /** + * Check if plugin is installed. + * + * @return boolean + */ + private function is_installed(): bool { + return file_exists( WP_PLUGIN_DIR . '/' . $this->get_plugin() ); + } + + /** + * Check if installation is allowed. + * + * @return boolean + */ + private function is_allowed(): bool { + if ( ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_GET['_wpnonce'] ) ), 'plugin_family_install_' . $this->get_slug() ) ) { // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotValidated + return false; + } if ( ! current_user_can( is_multisite() ? 'manage_network_plugins' : 'install_plugins' ) ) { - return false; - } - - return true; - } - - /** - * Get plugin slug. - * - * @return string - */ - private function get_slug(): string { - return dirname( sanitize_text_field( urldecode( $_GET['plugin_to_install'] ) ) ); - } - - /** - * Get plugin identifier. - * - * @return void - */ - private function get_plugin() { - return sanitize_text_field( urldecode( $_GET['plugin_to_install'] ) ) . '.php'; - } - - /** - * Get plugin download url. - * - * @return void - */ - private function get_download_url() { - require_once ABSPATH . 'wp-admin/includes/plugin-install.php'; - - $data = [ - 'slug' => $this->get_slug(), - 'fields' => [ - 'download_link' => true, - 'short_description' => false, - 'sections' => false, - 'rating' => false, - 'ratings' => false, - 'downloaded' => false, - 'last_updated' => false, - 'added' => false, - 'tags' => false, - 'homepage' => false, - 'donate_link' => false, - ] - ]; - - // Get Plugin Infos. - $plugin_info = plugins_api( 'plugin_information', $data ); - - if ( is_wp_error( $plugin_info ) ) { - $this->set_error( $plugin_info ); - } - - return $plugin_info->download_link; - } - - /** - * Maybe display error notice. - * - * @return void - */ - public function display_error_notice() { - $errors = get_transient( $this->error_transient ); - - if ( ! $errors ) { - return; - } - - if ( ! is_wp_error( $errors ) ) { - delete_transient( $this->error_transient ); - return; - } - - $errors = $errors->get_error_messages(); - - if ( ! $errors ) { - $errors[] = 'Installation process failed'; - } - - echo '

' . implode( '
', $errors ) . '

'; - - // Remove transient after displaying notice. - delete_transient( $this->error_transient ); - } - - /** - * Store an error message in a transient then redirect. - * - * @param object $error A WP_Error object. - * @return void - */ - private function set_error( $error ) { - set_transient( $this->error_transient, $error, 30 ); - - wp_safe_redirect( wp_get_referer() ); - exit; - } -} \ No newline at end of file + return false; + } + + return true; + } + + /** + * Get plugin slug. + * + * @return string + */ + private function get_slug(): string { + return dirname( rawurldecode( sanitize_text_field( wp_unslash( $_GET['plugin_to_install'] ) ) ) ); // phpcs:ignore WordPress.Security.NonceVerification.Recommended, WordPress.Security.ValidatedSanitizedInput.InputNotValidated + } + + /** + * Get plugin identifier. + * + * @return string + */ + private function get_plugin(): string { + return rawurldecode( sanitize_text_field( wp_unslash( $_GET['plugin_to_install'] ) ) ) . '.php'; // phpcs:ignore WordPress.Security.NonceVerification.Recommended, WordPress.Security.ValidatedSanitizedInput.InputNotValidated + } + + /** + * Get plugin download url. + * + * @return string + */ + private function get_download_url(): string { + require_once ABSPATH . 'wp-admin/includes/plugin-install.php'; + + $data = [ + 'slug' => $this->get_slug(), + 'fields' => [ + 'download_link' => true, + 'short_description' => false, + 'sections' => false, + 'rating' => false, + 'ratings' => false, + 'downloaded' => false, + 'last_updated' => false, + 'added' => false, + 'tags' => false, + 'homepage' => false, + 'donate_link' => false, + ], + ]; + + // Get Plugin Infos. + $plugin_info = plugins_api( 'plugin_information', $data ); + + if ( is_wp_error( $plugin_info ) ) { + $this->set_error( $plugin_info ); + } + + return $plugin_info->download_link; + } + + /** + * Maybe display error notice. + * + * @return void + */ + public function display_error_notice() { + $errors = get_transient( $this->error_transient ); + + if ( ! $errors ) { + return; + } + + if ( ! is_wp_error( $errors ) ) { + delete_transient( $this->error_transient ); + return; + } + + $errors = $errors->get_error_messages(); + + if ( ! $errors ) { + $errors[] = 'Installation process failed'; + } + + $notice = '

' . implode( '
', $errors ) . '

'; + echo wp_kses_post( $notice ); + + // Remove transient after displaying notice. + delete_transient( $this->error_transient ); + } + + /** + * Store an error message in a transient then redirect. + * + * @param object $error A WP_Error object. + * @return void + */ + private function set_error( $error ) { + set_transient( $this->error_transient, $error, 30 ); + + wp_safe_redirect( wp_get_referer() ); + exit; + } +} diff --git a/src/Controller/PluginFamilyInterface.php b/src/Controller/PluginFamilyInterface.php index 753ea76..7237ac3 100644 --- a/src/Controller/PluginFamilyInterface.php +++ b/src/Controller/PluginFamilyInterface.php @@ -5,17 +5,17 @@ defined( 'ABSPATH' ) || exit; interface PluginFamilyInterface { - /** - * Process to install and activate plugin. - * - * @return void - */ - public function install_activate(); + /** + * Process to install and activate plugin. + * + * @return void + */ + public function install_activate(); - /** - * Maybe display error notice. - * - * @return void - */ - public function display_error_notice(); -} \ No newline at end of file + /** + * Maybe display error notice. + * + * @return void + */ + public function display_error_notice(); +} diff --git a/src/Model/PluginFamily.php b/src/Model/PluginFamily.php index a0deded..3f0e511 100644 --- a/src/Model/PluginFamily.php +++ b/src/Model/PluginFamily.php @@ -8,138 +8,142 @@ * Handles the data to be passed to the frontend. */ class PluginFamily { - /** - * Get filtered plugins. - * - * @param string $main_plugin Main plugin installed. - * - * @return array - */ - public function get_filtered_plugins( string $main_plugin ): array { - $plugins = require_once 'wp_media_plugins.php'; - - return $this->filter_plugins_by_activation( $plugins, $main_plugin ); - } - - /** - * Filter plugins family data by activation status and returns both categorized and uncategorized format. - * - * @param array $plugins Array of family plugins. - * @param string $main_plugin Main plugin installed. - * - * @return array - */ - public function filter_plugins_by_activation( array $plugins, string $main_plugin ): array { - if ( ! is_array( $plugins ) || empty( $plugins ) ) { - return []; - } - - list( $active_plugins, $inactive_plugins ) = [ [], [] ]; - - foreach ( $plugins as $cat => $cat_data ) { - foreach ( $cat_data['plugins'] as $plugin => $data ) { - - $plugin_path = $plugin . '.php'; - $plugin_slug = dirname( $plugin ); - $main_plugin_slug = dirname( $main_plugin ); - - /** - * Check for activated plugins and pop them out of the array - * to re-add them back using array_merge to be displayed after - * plugins that are not installed or not activated. - */ - if ( is_plugin_active( $plugin_path ) ) { - // set cta data of active plugins. - $plugins[ $cat ]['plugins'][ $plugin ]['cta'] = [ - 'text' => 'Activated', - 'url' => '#', - ]; - - // Send active plugin to new array. - $active_plugins[ $plugin ] = $plugins[ $cat ]['plugins'][ $plugin ]; - - // Remove active plugin from current category. - unset( $cat_data['plugins'][ $plugin ] ); - - // Send active plugin to the end of array in current category. - $cat_data['plugins'][ $plugin ] = $plugins[ $cat ]['plugins'][ $plugin ]; - - // Remove category with active plugin from current array. - unset( $plugins[ $cat ] ); - - // Send category with active plugins to the end of array. - $plugins[ $cat ] = $cat_data; - continue; - } - - $install_activate_url = admin_url( 'admin-post.php' ); - - $args = [ - 'action' => 'plugin_family_install_' . $plugin_slug, - '_wpnonce' => wp_create_nonce( 'plugin_family_install_' . $plugin_slug ), - 'plugin_to_install' => urlencode( $plugin ), - ]; - - if ( 'imagify-plugin' === $plugin_slug ) { - $args = [ - 'action' => 'install_imagify_from_partner_' . $main_plugin_slug, - '_wpnonce' => wp_create_nonce( 'install_imagify_from_partner' ), - '_wp_http_referer' => rawurlencode( $this->get_current_url() ), - ]; - } - - $install_activate_url = add_query_arg( $args, $install_activate_url ); - - // Set Installation link - $plugins[ $cat ]['plugins'][ $plugin ]['cta'] = [ - 'text' => 'Install', - 'url' => $install_activate_url, - ]; - - // Create unique CTA data for WP Rocket. - if ( 'wp-rocket/wp-rocket' === $plugin ) { - $plugins[ $cat ]['plugins'][ $plugin ]['cta'] = [ - 'text' => 'Get it Now', - 'url' => 'https://wp-rocket.me/?utm_source=imagify-coupon&utm_medium=plugin&utm_campaign=imagify', - ]; - } - - // Set activation text. - if ( file_exists( WP_PLUGIN_DIR . '/'. $plugin_path ) ) { - $plugins[ $cat ]['plugins'][ $plugin ]['cta']['text'] = 'Activate'; - } - - // Send inactive plugins to new array. - $inactive_plugins[ $plugin ] = $plugins[ $cat ]['plugins'][ $plugin ]; - } - - // Remove main plugin from categorized array. - if ( isset( $plugins[ $cat ]['plugins'][ $main_plugin ] ) ) { - unset( $plugins[ $cat ]['plugins'][ $main_plugin ] ); - } - } - - $uncategorized = array_merge( $inactive_plugins, $active_plugins ); - // Remove main plugin from uncategorized array. - unset( $uncategorized[ $main_plugin ] ); - - return [ - 'categorized' => $plugins, - 'uncategorized' => $uncategorized, - ]; - } - - /** - * Get the current URL. - * Gotten from Imagify_Partner Package. - * - * @return string - */ - private function get_current_url(): string { - $port = (int) $_SERVER['SERVER_PORT']; - $port = 80 !== $port && 443 !== $port ? ( ':' . $port ) : ''; - $url = ! empty( $GLOBALS['HTTP_SERVER_VARS']['REQUEST_URI'] ) ? $GLOBALS['HTTP_SERVER_VARS']['REQUEST_URI'] : ( ! empty( $_SERVER['REQUEST_URI'] ) ? $_SERVER['REQUEST_URI'] : '' ); - - return 'http' . ( is_ssl() ? 's' : '' ) . '://' . $_SERVER['HTTP_HOST'] . $port . $url; - } + /** + * Get filtered plugins. + * + * @param string $main_plugin Main plugin installed. + * + * @return array + */ + public function get_filtered_plugins( string $main_plugin ): array { + $plugins = require_once 'wp_media_plugins.php'; + + return $this->filter_plugins_by_activation( $plugins, $main_plugin ); + } + + /** + * Filter plugins family data by activation status and returns both categorized and uncategorized format. + * + * @param array $plugins Array of family plugins. + * @param string $main_plugin Main plugin installed. + * + * @return array + */ + public function filter_plugins_by_activation( array $plugins, string $main_plugin ): array { + if ( ! is_array( $plugins ) || empty( $plugins ) ) { + return []; + } + + list( $active_plugins, $inactive_plugins ) = [ [], [] ]; + + foreach ( $plugins as $cat => $cat_data ) { + foreach ( $cat_data['plugins'] as $plugin => $data ) { + + $plugin_path = $plugin . '.php'; + $plugin_slug = dirname( $plugin ); + $main_plugin_slug = dirname( $main_plugin ); + + /** + * Check for activated plugins and pop them out of the array + * to re-add them back using array_merge to be displayed after + * plugins that are not installed or not activated. + */ + if ( is_plugin_active( $plugin_path ) ) { + // set cta data of active plugins. + $plugins[ $cat ]['plugins'][ $plugin ]['cta'] = [ + 'text' => 'Activated', + 'url' => '#', + ]; + + // Send active plugin to new array. + $active_plugins[ $plugin ] = $plugins[ $cat ]['plugins'][ $plugin ]; + + // Remove active plugin from current category. + unset( $cat_data['plugins'][ $plugin ] ); + + // Send active plugin to the end of array in current category. + $cat_data['plugins'][ $plugin ] = $plugins[ $cat ]['plugins'][ $plugin ]; + + // Remove category with active plugin from current array. + unset( $plugins[ $cat ] ); + + // Send category with active plugins to the end of array. + $plugins[ $cat ] = $cat_data; + continue; + } + + $install_activate_url = admin_url( 'admin-post.php' ); + + $args = [ + 'action' => 'plugin_family_install_' . $plugin_slug, + '_wpnonce' => wp_create_nonce( 'plugin_family_install_' . $plugin_slug ), + 'plugin_to_install' => rawurlencode( $plugin ), + ]; + + if ( 'imagify-plugin' === $plugin_slug ) { + $args = [ + 'action' => 'install_imagify_from_partner_' . $main_plugin_slug, + '_wpnonce' => wp_create_nonce( 'install_imagify_from_partner' ), + '_wp_http_referer' => rawurlencode( $this->get_current_url() ), + ]; + } + + $install_activate_url = add_query_arg( $args, $install_activate_url ); + + // Set Installation link. + $plugins[ $cat ]['plugins'][ $plugin ]['cta'] = [ + 'text' => 'Install', + 'url' => $install_activate_url, + ]; + + // Create unique CTA data for WP Rocket. + if ( 'wp-rocket/wp-rocket' === $plugin ) { + $plugins[ $cat ]['plugins'][ $plugin ]['cta'] = [ + 'text' => 'Get it Now', + 'url' => 'https://wp-rocket.me/?utm_source=imagify-coupon&utm_medium=plugin&utm_campaign=imagify', + ]; + } + + // Set activation text. + if ( file_exists( WP_PLUGIN_DIR . '/' . $plugin_path ) ) { + $plugins[ $cat ]['plugins'][ $plugin ]['cta']['text'] = 'Activate'; + } + + // Send inactive plugins to new array. + $inactive_plugins[ $plugin ] = $plugins[ $cat ]['plugins'][ $plugin ]; + } + + // Remove main plugin from categorized array. + if ( isset( $plugins[ $cat ]['plugins'][ $main_plugin ] ) ) { + unset( $plugins[ $cat ]['plugins'][ $main_plugin ] ); + } + } + + $uncategorized = array_merge( $inactive_plugins, $active_plugins ); + // Remove main plugin from uncategorized array. + unset( $uncategorized[ $main_plugin ] ); + + return [ + 'categorized' => $plugins, + 'uncategorized' => $uncategorized, + ]; + } + + /** + * Get the current URL. + * Gotten from Imagify_Partner Package. + * + * @return string + */ + private function get_current_url(): string { + if ( ! isset( $_SERVER['SERVER_PORT'], $_SERVER['HTTP_HOST'] ) ) { + return ''; + } + + $port = (int) wp_unslash( $_SERVER['SERVER_PORT'] ); // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.ValidatedSanitizedInput.MissingUnslash + $port = 80 !== $port && 443 !== $port ? ( ':' . $port ) : ''; + $url = ! empty( $GLOBALS['HTTP_SERVER_VARS']['REQUEST_URI'] ) ? $GLOBALS['HTTP_SERVER_VARS']['REQUEST_URI'] : ( ! empty( $_SERVER['REQUEST_URI'] ) ? $_SERVER['REQUEST_URI'] : '' ); // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.ValidatedSanitizedInput.MissingUnslash + + return 'http' . ( is_ssl() ? 's' : '' ) . '://' . $_SERVER['HTTP_HOST'] . $port . $url; // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.ValidatedSanitizedInput.MissingUnslash + } } diff --git a/src/Model/wp_media_plugins.php b/src/Model/wp_media_plugins.php index 9490563..46bf8ef 100644 --- a/src/Model/wp_media_plugins.php +++ b/src/Model/wp_media_plugins.php @@ -2,65 +2,66 @@ /** * WP Media plugin family data. */ + return [ - 'optimize_performance' => [ - 'title' => 'Optimize Performance', - 'plugins' => [ - 'wp-rocket/wp-rocket' => [ - 'logo' => [ - 'file' => 'logo-wp-rocket.svg', - 'width' => '50%', - ], - 'title' => 'Speed Up Your Website, Instantly', - 'desc' => 'WP Rocket is the easiest way to make your WordPress website faster and boost your Google PageSpeed score. Get more traffic, better engagement, and higher conversions effortlessly.', - 'link' => 'https://wp-rocket.me/?utm_source=imagify-coupon&utm_medium=plugin&utm_campaign=imagify', - ], - 'imagify-plugin/imagify' => [ - 'logo' => [ - 'file' => 'logo-imagify.svg', - 'width' => '50%', - ], - 'title' => 'Speed Up Your Website With Lighter Images', - 'desc' => 'Imagify is the easiest WordPress image optimizer. It automatically compresses images, converts them to WebP and AVIF formats, and lets you resize and optimize with just one click!', - 'link' => 'https://imagify.io/', - ], - ], - ], - 'boost_traffic' => [ - 'title' => 'Boost Traffic', - 'plugins' => [ - 'seo-by-rank-math/rank-math' => [ - 'logo' => [ - 'file' => 'logo-rank-math.svg', - 'width' => '60%', - ], - 'title' => 'The Swiss Army Knife of SEO Tools', - 'desc' => 'Rank Math SEO is the Best WordPress SEO plugin with the features of many SEO and AI SEO tools in a single package to help multiply your SEO traffic.', - 'link' => 'https://rankmath.com/wordpress/plugin/seo-suite/', - ], - ], - ], - 'protect_secure' => [ - 'title' => 'Protect & Secure', - 'plugins' => [ - 'backwpup/backwpup' => [ - 'logo' => [ - 'file' => 'logo-backwpup.svg', - 'width' => '60%', - ], - 'title' => 'The Easiest Way to Protect Your Website', - 'desc' => 'BackWPup is the most comprehensive and user-friendly backup & restore plugin for WordPress. Easily schedule automatic backups, securely store and restore with just a few clicks!', - 'link' => 'https://backwpup.com/', - ], - 'uk-cookie-consent/uk-cookie-consent' => [ - 'logo' => [ - 'file' => 'logo-termly.svg', - 'width' => '50%', - ], - 'title' => 'GDPR/CCPA Cookie Consent Banner', - 'desc' => 'One of the easiest, most comprehensive, and popular cookie consent plugins available. Google Gold Certified Partner to quickly comply with data privacy laws from around the world.', - 'link' => 'https://termly.io/resources/articles/wordpress-cookies-guide/', - ], - ], - ], -]; \ No newline at end of file + 'optimize_performance' => [ + 'title' => 'Optimize Performance', + 'plugins' => [ + 'wp-rocket/wp-rocket' => [ + 'logo' => [ + 'file' => 'logo-wp-rocket.svg', + 'width' => '50%', + ], + 'title' => 'Speed Up Your Website, Instantly', + 'desc' => 'WP Rocket is the easiest way to make your WordPress website faster and boost your Google PageSpeed score. Get more traffic, better engagement, and higher conversions effortlessly.', + 'link' => 'https://wp-rocket.me/?utm_source=imagify-coupon&utm_medium=plugin&utm_campaign=imagify', + ], + 'imagify-plugin/imagify' => [ + 'logo' => [ + 'file' => 'logo-imagify.svg', + 'width' => '50%', + ], + 'title' => 'Speed Up Your Website With Lighter Images', + 'desc' => 'Imagify is the easiest WordPress image optimizer. It automatically compresses images, converts them to WebP and AVIF formats, and lets you resize and optimize with just one click!', + 'link' => 'https://imagify.io/', + ], + ], + ], + 'boost_traffic' => [ + 'title' => 'Boost Traffic', + 'plugins' => [ + 'seo-by-rank-math/rank-math' => [ + 'logo' => [ + 'file' => 'logo-rank-math.svg', + 'width' => '60%', + ], + 'title' => 'The Swiss Army Knife of SEO Tools', + 'desc' => 'Rank Math SEO is the Best WordPress SEO plugin with the features of many SEO and AI SEO tools in a single package to help multiply your SEO traffic.', + 'link' => 'https://rankmath.com/wordpress/plugin/seo-suite/', + ], + ], + ], + 'protect_secure' => [ + 'title' => 'Protect & Secure', + 'plugins' => [ + 'backwpup/backwpup' => [ + 'logo' => [ + 'file' => 'logo-backwpup.svg', + 'width' => '60%', + ], + 'title' => 'The Easiest Way to Protect Your Website', + 'desc' => 'BackWPup is the most comprehensive and user-friendly backup & restore plugin for WordPress. Easily schedule automatic backups, securely store and restore with just a few clicks!', + 'link' => 'https://backwpup.com/', + ], + 'uk-cookie-consent/uk-cookie-consent' => [ + 'logo' => [ + 'file' => 'logo-termly.svg', + 'width' => '50%', + ], + 'title' => 'GDPR/CCPA Cookie Consent Banner', + 'desc' => 'One of the easiest, most comprehensive, and popular cookie consent plugins available. Google Gold Certified Partner to quickly comply with data privacy laws from around the world.', + 'link' => 'https://termly.io/resources/articles/wordpress-cookies-guide/', + ], + ], + ], +]; From 1bd7fcfc07643694b162b6fafce123ae3bb72684 Mon Sep 17 00:00:00 2001 From: Michael Lee Date: Tue, 15 Oct 2024 11:57:29 +0100 Subject: [PATCH 07/49] Ignore composer.lock --- .gitignore | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 49ce3c1..7602b69 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ -/vendor \ No newline at end of file +/vendor +/composer.lock \ No newline at end of file From 1e10a4b080b1c151fdc701176b784707007460ca Mon Sep 17 00:00:00 2001 From: Michael Lee Date: Tue, 15 Oct 2024 19:11:40 +0100 Subject: [PATCH 08/49] Added tests --- .../PluginFamily/getPostInstallEvent.php | 32 ++ .../filterPluginsByActivation.php | 347 ++++++++++++++++++ tests/Unit/.phpunit.result.cache | 1 + tests/Unit/TestCase.php | 35 ++ tests/Unit/bootstrap.php | 10 + tests/Unit/phpunit.xml.dist | 27 ++ .../PluginFamily/getPostInstallEvent.php | 37 ++ .../filterPluginsByActivation.php | 81 ++++ 8 files changed, 570 insertions(+) create mode 100644 tests/Fixtures/src/Controller/PluginFamily/getPostInstallEvent.php create mode 100644 tests/Fixtures/src/Model/PluginFamily/filterPluginsByActivation.php create mode 100644 tests/Unit/.phpunit.result.cache create mode 100644 tests/Unit/TestCase.php create mode 100644 tests/Unit/bootstrap.php create mode 100644 tests/Unit/phpunit.xml.dist create mode 100644 tests/Unit/src/Controller/PluginFamily/getPostInstallEvent.php create mode 100644 tests/Unit/src/Model/PluginFamily/filterPluginsByActivation.php diff --git a/tests/Fixtures/src/Controller/PluginFamily/getPostInstallEvent.php b/tests/Fixtures/src/Controller/PluginFamily/getPostInstallEvent.php new file mode 100644 index 0000000..08b7eac --- /dev/null +++ b/tests/Fixtures/src/Controller/PluginFamily/getPostInstallEvent.php @@ -0,0 +1,32 @@ + [ + 'config' => [ + 'get_params' => [], + ], + 'expected' => [], + ], + 'testShouldReturnEmptyArrayIfActionIsNotValid' => [ + 'config' => [ + 'get_params' => [ + 'action' => 'plugin_family_install_some-wierd-plugin', + '_wpnonce' => '9a68f00b8d', + 'plugin_to_install' => 'some-wierd-plugin', + ], + ], + 'expected' => [], + ], + 'testShouldReturnExpected' => [ + 'config' => [ + 'get_params' => [ + 'action' => 'plugin_family_install_wp-rocket', + '_wpnonce' => '9a68f00b8d', + 'plugin_to_install' => 'wp-rocket', + ], + ], + 'expected' => [ + 'admin_post_plugin_family_install_wp-rocket' => 'install_activate', + ], + ], +]; \ No newline at end of file diff --git a/tests/Fixtures/src/Model/PluginFamily/filterPluginsByActivation.php b/tests/Fixtures/src/Model/PluginFamily/filterPluginsByActivation.php new file mode 100644 index 0000000..cd307c3 --- /dev/null +++ b/tests/Fixtures/src/Model/PluginFamily/filterPluginsByActivation.php @@ -0,0 +1,347 @@ + [ + 'title' => 'Optimize Performance', + 'plugins' => [ + 'wp-rocket/wp-rocket' => [ + 'logo' => [ + 'file' => 'logo-wp-rocket.svg', + 'width' => '50%', + ], + 'title' => 'Speed Up Your Website, Instantly', + 'desc' => 'WP Rocket is the easiest way to make your WordPress website faster and boost your Google PageSpeed score. Get more traffic, better engagement, and higher conversions effortlessly.', + 'link' => 'https://wp-rocket.me/?utm_source=imagify-coupon&utm_medium=plugin&utm_campaign=imagify', + ], + 'imagify-plugin/imagify' => [ + 'logo' => [ + 'file' => 'logo-imagify.svg', + 'width' => '50%', + ], + 'title' => 'Speed Up Your Website With Lighter Images', + 'desc' => 'Imagify is the easiest WordPress image optimizer. It automatically compresses images, converts them to WebP and AVIF formats, and lets you resize and optimize with just one click!', + 'link' => 'https://imagify.io/', + ], + ], + ], + 'boost_traffic' => [ + 'title' => 'Boost Traffic', + 'plugins' => [ + 'seo-by-rank-math/rank-math' => [ + 'logo' => [ + 'file' => 'logo-rank-math.svg', + 'width' => '60%', + ], + 'title' => 'The Swiss Army Knife of SEO Tools', + 'desc' => 'Rank Math SEO is the Best WordPress SEO plugin with the features of many SEO and AI SEO tools in a single package to help multiply your SEO traffic.', + 'link' => 'https://rankmath.com/wordpress/plugin/seo-suite/', + ], + ], + ], + 'protect_secure' => [ + 'title' => 'Protect & Secure', + 'plugins' => [ + 'backwpup/backwpup' => [ + 'logo' => [ + 'file' => 'logo-backwpup.svg', + 'width' => '60%', + ], + 'title' => 'The Easiest Way to Protect Your Website', + 'desc' => 'BackWPup is the most comprehensive and user-friendly backup & restore plugin for WordPress. Easily schedule automatic backups, securely store and restore with just a few clicks!', + 'link' => 'https://backwpup.com/', + ], + 'uk-cookie-consent/uk-cookie-consent' => [ + 'logo' => [ + 'file' => 'logo-termly.svg', + 'width' => '50%', + ], + 'title' => 'GDPR/CCPA Cookie Consent Banner', + 'desc' => 'One of the easiest, most comprehensive, and popular cookie consent plugins available. Google Gold Certified Partner to quickly comply with data privacy laws from around the world.', + 'link' => 'https://termly.io/resources/articles/wordpress-cookies-guide/', + ], + ], + ], +]; + +$expectedActivePluginAsTheLastElement = [ + 'boost_traffic' => [ + 'title' => 'Boost Traffic', + 'plugins' => [ + 'seo-by-rank-math/rank-math' => [ + 'logo' => [ + 'file' => 'logo-rank-math.svg', + 'width' => '60%', + ], + 'title' => 'The Swiss Army Knife of SEO Tools', + 'desc' => 'Rank Math SEO is the Best WordPress SEO plugin with the features of many SEO and AI SEO tools in a single package to help multiply your SEO traffic.', + 'link' => 'https://rankmath.com/wordpress/plugin/seo-suite/', + 'cta' => [ + 'text' => 'Install', + 'url' => 'http://example.org/wp-admin/admin-post.php?action=plugin_family_install_seo-by-rank-math&_wpnonce=9a68f00b8d&plugin_to_install=seo-by-rank-math%2Frank-math' + ], + ], + ], + ], + 'protect_secure' => [ + 'title' => 'Protect & Secure', + 'plugins' => [ + 'backwpup/backwpup' => [ + 'logo' => [ + 'file' => 'logo-backwpup.svg', + 'width' => '60%', + ], + 'title' => 'The Easiest Way to Protect Your Website', + 'desc' => 'BackWPup is the most comprehensive and user-friendly backup & restore plugin for WordPress. Easily schedule automatic backups, securely store and restore with just a few clicks!', + 'link' => 'https://backwpup.com/', + 'cta' => [ + 'text' => 'Install', + 'url' => 'http://example.org/wp-admin/admin-post.php?action=plugin_family_install_backwpup&_wpnonce=9a68f00b8d&plugin_to_install=backwpup%2Fbackwpup' + ], + ], + 'uk-cookie-consent/uk-cookie-consent' => [ + 'logo' => [ + 'file' => 'logo-termly.svg', + 'width' => '50%', + ], + 'title' => 'GDPR/CCPA Cookie Consent Banner', + 'desc' => 'One of the easiest, most comprehensive, and popular cookie consent plugins available. Google Gold Certified Partner to quickly comply with data privacy laws from around the world.', + 'link' => 'https://termly.io/resources/articles/wordpress-cookies-guide/', + 'cta' => [ + 'text' => 'Install', + 'url' => 'http://example.org/wp-admin/admin-post.php?action=plugin_family_install_uk-cookie-consent&_wpnonce=9a68f00b8d&plugin_to_install=uk-cookie-consent%2Fuk-cookie-consent' + ], + ], + ], + ], + 'optimize_performance' => [ + 'title' => 'Optimize Performance', + 'plugins' => [ + 'imagify-plugin/imagify' => [ + 'logo' => [ + 'file' => 'logo-imagify.svg', + 'width' => '50%', + ], + 'title' => 'Speed Up Your Website With Lighter Images', + 'desc' => 'Imagify is the easiest WordPress image optimizer. It automatically compresses images, converts them to WebP and AVIF formats, and lets you resize and optimize with just one click!', + 'link' => 'https://imagify.io/', + 'cta' => [ + 'text' => 'Activated', + 'url' => '#' + ], + ], + ], + ], +]; + +$expectedCategoryWithActivePluginAsTheLastElement = [ + 'wp-rocket/wp-rocket' => [ + 'logo' => [ + 'file' => 'logo-wp-rocket.svg', + 'width' => '50%', + ], + 'title' => 'Speed Up Your Website, Instantly', + 'desc' => 'WP Rocket is the easiest way to make your WordPress website faster and boost your Google PageSpeed score. Get more traffic, better engagement, and higher conversions effortlessly.', + 'link' => 'https://wp-rocket.me/?utm_source=imagify-coupon&utm_medium=plugin&utm_campaign=imagify', + 'cta' => [ + 'text' => 'Get it Now', + 'url' => 'https://wp-rocket.me/?utm_source=imagify-coupon&utm_medium=plugin&utm_campaign=imagify' + ], + ], + 'backwpup/backwpup' => [ + 'logo' => [ + 'file' => 'logo-backwpup.svg', + 'width' => '60%', + ], + 'title' => 'The Easiest Way to Protect Your Website', + 'desc' => 'BackWPup is the most comprehensive and user-friendly backup & restore plugin for WordPress. Easily schedule automatic backups, securely store and restore with just a few clicks!', + 'link' => 'https://backwpup.com/', + 'cta' => [ + 'text' => 'Install', + 'url' => 'http://example.org/wp-admin/admin-post.php?action=plugin_family_install_backwpup&_wpnonce=9a68f00b8d&plugin_to_install=backwpup%2Fbackwpup' + ], + ], + 'uk-cookie-consent/uk-cookie-consent' => [ + 'logo' => [ + 'file' => 'logo-termly.svg', + 'width' => '50%', + ], + 'title' => 'GDPR/CCPA Cookie Consent Banner', + 'desc' => 'One of the easiest, most comprehensive, and popular cookie consent plugins available. Google Gold Certified Partner to quickly comply with data privacy laws from around the world.', + 'link' => 'https://termly.io/resources/articles/wordpress-cookies-guide/', + 'cta' => [ + 'text' => 'Install', + 'url' => 'http://example.org/wp-admin/admin-post.php?action=plugin_family_install_uk-cookie-consent&_wpnonce=9a68f00b8d&plugin_to_install=uk-cookie-consent%2Fuk-cookie-consent' + ], + ], + 'seo-by-rank-math/rank-math' => [ + 'logo' => [ + 'file' => 'logo-rank-math.svg', + 'width' => '60%', + ], + 'title' => 'The Swiss Army Knife of SEO Tools', + 'desc' => 'Rank Math SEO is the Best WordPress SEO plugin with the features of many SEO and AI SEO tools in a single package to help multiply your SEO traffic.', + 'link' => 'https://rankmath.com/wordpress/plugin/seo-suite/', + 'cta' => [ + 'text' => 'Activated', + 'url' => '#' + ], + ], +]; + +$expectedActivateTextIfPluginIsAlreadyInstalled = [ + 'wp-rocket/wp-rocket' => [ + 'logo' => [ + 'file' => 'logo-wp-rocket.svg', + 'width' => '50%', + ], + 'title' => 'Speed Up Your Website, Instantly', + 'desc' => 'WP Rocket is the easiest way to make your WordPress website faster and boost your Google PageSpeed score. Get more traffic, better engagement, and higher conversions effortlessly.', + 'link' => 'https://wp-rocket.me/?utm_source=imagify-coupon&utm_medium=plugin&utm_campaign=imagify', + 'cta' => [ + 'text' => 'Activate', + 'url' => 'http://example.org/wp-admin/admin-post.php?action=plugin_family_install_wp-rocket&_wpnonce=9a68f00b8d&plugin_to_install=wp-rocket%2Fwp-rocket' + ], + ], + 'seo-by-rank-math/rank-math' => [ + 'logo' => [ + 'file' => 'logo-rank-math.svg', + 'width' => '60%', + ], + 'title' => 'The Swiss Army Knife of SEO Tools', + 'desc' => 'Rank Math SEO is the Best WordPress SEO plugin with the features of many SEO and AI SEO tools in a single package to help multiply your SEO traffic.', + 'link' => 'https://rankmath.com/wordpress/plugin/seo-suite/', + 'cta' => [ + 'text' => 'Activate', + 'url' => 'http://example.org/wp-admin/admin-post.php?action=plugin_family_install_seo-by-rank-math&_wpnonce=9a68f00b8d&plugin_to_install=seo-by-rank-math%2Frank-math' + ], + ], + 'backwpup/backwpup' => [ + 'logo' => [ + 'file' => 'logo-backwpup.svg', + 'width' => '60%', + ], + 'title' => 'The Easiest Way to Protect Your Website', + 'desc' => 'BackWPup is the most comprehensive and user-friendly backup & restore plugin for WordPress. Easily schedule automatic backups, securely store and restore with just a few clicks!', + 'link' => 'https://backwpup.com/', + 'cta' => [ + 'text' => 'Activate', + 'url' => 'http://example.org/wp-admin/admin-post.php?action=plugin_family_install_backwpup&_wpnonce=9a68f00b8d&plugin_to_install=backwpup%2Fbackwpup' + ], + ], + 'uk-cookie-consent/uk-cookie-consent' => [ + 'logo' => [ + 'file' => 'logo-termly.svg', + 'width' => '50%', + ], + 'title' => 'GDPR/CCPA Cookie Consent Banner', + 'desc' => 'One of the easiest, most comprehensive, and popular cookie consent plugins available. Google Gold Certified Partner to quickly comply with data privacy laws from around the world.', + 'link' => 'https://termly.io/resources/articles/wordpress-cookies-guide/', + 'cta' => [ + 'text' => 'Activate', + 'url' => 'http://example.org/wp-admin/admin-post.php?action=plugin_family_install_uk-cookie-consent&_wpnonce=9a68f00b8d&plugin_to_install=uk-cookie-consent%2Fuk-cookie-consent' + ], + ], +]; + +$expectedUniqueInstallLinkForImagify = [ + 'wp-rocket/wp-rocket' => [ + 'logo' => [ + 'file' => 'logo-wp-rocket.svg', + 'width' => '50%', + ], + 'title' => 'Speed Up Your Website, Instantly', + 'desc' => 'WP Rocket is the easiest way to make your WordPress website faster and boost your Google PageSpeed score. Get more traffic, better engagement, and higher conversions effortlessly.', + 'link' => 'https://wp-rocket.me/?utm_source=imagify-coupon&utm_medium=plugin&utm_campaign=imagify', + 'cta' => [ + 'text' => 'Get it Now', + 'url' => 'https://wp-rocket.me/?utm_source=imagify-coupon&utm_medium=plugin&utm_campaign=imagify' + ], + ], + 'imagify-plugin/imagify' => [ + 'logo' => [ + 'file' => 'logo-imagify.svg', + 'width' => '50%', + ], + 'title' => 'Speed Up Your Website With Lighter Images', + 'desc' => 'Imagify is the easiest WordPress image optimizer. It automatically compresses images, converts them to WebP and AVIF formats, and lets you resize and optimize with just one click!', + 'link' => 'https://imagify.io/', + 'cta' => [ + 'text' => 'Install', + 'url' => 'http://example.org/wp-admin/admin-post.php?action=install_imagify_from_partner_uk-cookie-consent&_wpnonce=9a68f00b8d&_wp_http_referer=http%253A%252F%252Fexample.org%252Fwp-admin' + ], + ], + 'seo-by-rank-math/rank-math' => [ + 'logo' => [ + 'file' => 'logo-rank-math.svg', + 'width' => '60%', + ], + 'title' => 'The Swiss Army Knife of SEO Tools', + 'desc' => 'Rank Math SEO is the Best WordPress SEO plugin with the features of many SEO and AI SEO tools in a single package to help multiply your SEO traffic.', + 'link' => 'https://rankmath.com/wordpress/plugin/seo-suite/', + 'cta' => [ + 'text' => 'Install', + 'url' => 'http://example.org/wp-admin/admin-post.php?action=plugin_family_install_seo-by-rank-math&_wpnonce=9a68f00b8d&plugin_to_install=seo-by-rank-math%2Frank-math' + ], + ], + 'backwpup/backwpup' => [ + 'logo' => [ + 'file' => 'logo-backwpup.svg', + 'width' => '60%', + ], + 'title' => 'The Easiest Way to Protect Your Website', + 'desc' => 'BackWPup is the most comprehensive and user-friendly backup & restore plugin for WordPress. Easily schedule automatic backups, securely store and restore with just a few clicks!', + 'link' => 'https://backwpup.com/', + 'cta' => [ + 'text' => 'Install', + 'url' => 'http://example.org/wp-admin/admin-post.php?action=plugin_family_install_backwpup&_wpnonce=9a68f00b8d&plugin_to_install=backwpup%2Fbackwpup' + ], + ], +]; + +return [ + 'testShouldReturnEmptyArrayIfEmptyArrayParsed' => [ + 'config' => [ + 'plugins' => [], + 'main_plugin' => 'wp-rocket/wp-rocket', + 'order' => 'both', + ], + 'expected' => [], + ], + 'testShouldReturnActivePluginAsTheLastElement' => [ + 'config' => [ + 'plugins' => $plugins, + 'main_plugin' => 'wp-rocket/wp-rocket', + 'order' => 'categorized', + 'active_plugin' => 'imagify-plugin/imagify.php', + ], + 'expected' => $expectedActivePluginAsTheLastElement, + ], + 'testShouldReturnCategoryWithActivePluginAsTheLastElement' => [ + 'config' => [ + 'plugins' => $plugins, + 'main_plugin' => 'imagify-plugin/imagify', + 'order' => 'uncategorized', + 'active_plugin' => 'seo-by-rank-math/rank-math.php', + ], + 'expected' => $expectedCategoryWithActivePluginAsTheLastElement, + ], + 'testShouldReturnActivateTextIfPluginIsAlreadyInstalled' => [ + 'config' => [ + 'plugins' => $plugins, + 'main_plugin' => 'imagify-plugin/imagify', + 'order' => 'uncategorized', + 'active_plugin' => '', + 'is_installed' => true, + ], + 'expected' => $expectedActivateTextIfPluginIsAlreadyInstalled, + ], + 'testShouldReturnUniqueInstallLinkForImagify' => [ + 'config' => [ + 'plugins' => $plugins, + 'main_plugin' => 'uk-cookie-consent/uk-cookie-consent', + 'order' => 'uncategorized', + 'active_plugin' => '', + ], + 'expected' => $expectedUniqueInstallLinkForImagify, + ], +]; \ No newline at end of file diff --git a/tests/Unit/.phpunit.result.cache b/tests/Unit/.phpunit.result.cache new file mode 100644 index 0000000..5481751 --- /dev/null +++ b/tests/Unit/.phpunit.result.cache @@ -0,0 +1 @@ +{"version":1,"defects":{"WPMediaPluginFamily\\Tests\\Unit\\Model\\PluginFamily\\TestfilterPluginsByActivation::testShouldReturnExpected with data set \"testShouldReturnEmptyArrayIfNotArrayOrEmptyArrayParsed\"":5,"WPMediaPluginFamily\\Tests\\Unit\\Model\\PluginFamily\\TestfilterPluginsByActivation::testShouldReturnExpected with data set \"testShouldReturnActivePluginAsTheLastElementForCategorizedArray\"":5,"WPMediaPluginFamily\\Tests\\Unit\\Model\\PluginFamily\\TestfilterPluginsByActivation::testShouldReturnExpected with data set \"testShouldReturnCategoryWithActivePluginAsTheLastElementForUncategorizedArray\"":3,"WPMediaPluginFamily\\Tests\\Unit\\Model\\PluginFamily\\TestfilterPluginsByActivation::testShouldReturnExpected with data set \"testShouldReturnUniqueCtaDataForWprocket\"":4,"WPMediaPluginFamily\\Tests\\Unit\\Model\\PluginFamily\\TestfilterPluginsByActivation::testShouldReturnExpected with data set \"testShouldReturnDifferentInstallUrlForImagify\"":4,"WPMediaPluginFamily\\Tests\\Unit\\Model\\PluginFamily\\TestfilterPluginsByActivation::testShouldReturnExpected with data set \"testShouldReturnAsExpectedForCategorizedAndUncategorizedArray\"":4,"WPMediaPluginFamily\\Tests\\Unit\\Model\\PluginFamily\\TestfilterPluginsByActivation::testShouldReturnExpected with data set \"testShouldReturnEmptyArrayIfNotArray\"":4,"WPMediaPluginFamily\\Tests\\Unit\\Model\\PluginFamily\\TestfilterPluginsByActivation::testShouldReturnExpected with data set \"testShouldReturnEmptyArrayIfEmptyArrayParsed\"":4,"WPMediaPluginFamily\\Tests\\Unit\\Model\\PluginFamily\\TestfilterPluginsByActivation::testShouldReturnExpected with data set \"testShouldReturnActivePluginAsTheLastElement\"":4,"WPMediaPluginFamily\\Tests\\Unit\\Model\\PluginFamily\\TestfilterPluginsByActivation::testShouldReturnExpected with data set \"testShouldReturnCategoryWithActivePluginAsTheLastElement\"":4,"WPMediaPluginFamily\\Tests\\Unit\\Model\\PluginFamily\\TestfilterPluginsByActivation::testShouldReturnExpected with data set \"testShouldReturnActivateTextIfPluginIsAlreadyInstalled\"":4,"WPMediaPluginFamily\\Tests\\Unit\\Model\\PluginFamily\\TestfilterPluginsByActivation::testShouldReturnExpected with data set \"testShouldReturnUniqueInstallLinkForImagify\"":3,"WPMediaPluginFamily\\Tests\\Unit\\Model\\PluginFamily\\TestGetPostInstallEvent::testShouldReturnExpected with data set \"testShouldReturnEmptyArrayIfActionIsNotValid\"":4,"WPMediaPluginFamily\\Tests\\Unit\\Model\\PluginFamily\\TestGetPostInstallEvent::testShouldReturnExpected with data set \"testShouldReturnEmptyArrayIfProperGetParamAreNotSet\"":4,"WPMediaPluginFamily\\Tests\\Unit\\Model\\PluginFamily\\TestGetPostInstallEvent::testShouldReturnExpected with data set \"testShouldReturnExpected\"":3},"times":{"WPMediaPluginFamily\\Tests\\Unit\\Model\\PluginFamily\\TestfilterPluginsByActivation::testShouldReturnExpected with data set \"testShouldReturnEmptyArrayIfNotArrayOrEmptyArrayParsed\"":0.038,"WPMediaPluginFamily\\Tests\\Unit\\Model\\PluginFamily\\TestfilterPluginsByActivation::testShouldReturnExpected with data set \"testShouldReturnActivePluginAsTheLastElementForCategorizedArray\"":0.005,"WPMediaPluginFamily\\Tests\\Unit\\Model\\PluginFamily\\TestfilterPluginsByActivation::testShouldReturnExpected with data set \"testShouldReturnCategoryWithActivePluginAsTheLastElementForUncategorizedArray\"":0.002,"WPMediaPluginFamily\\Tests\\Unit\\Model\\PluginFamily\\TestfilterPluginsByActivation::testShouldReturnExpected with data set \"testShouldReturnUniqueCtaDataForWprocket\"":0.001,"WPMediaPluginFamily\\Tests\\Unit\\Model\\PluginFamily\\TestfilterPluginsByActivation::testShouldReturnExpected with data set \"testShouldReturnDifferentInstallUrlForImagify\"":0.001,"WPMediaPluginFamily\\Tests\\Unit\\Model\\PluginFamily\\TestfilterPluginsByActivation::testShouldReturnExpected with data set \"testShouldReturnAsExpectedForCategorizedAndUncategorizedArray\"":0.001,"WPMediaPluginFamily\\Tests\\Unit\\Model\\PluginFamily\\TestfilterPluginsByActivation::testShouldReturnExpected with data set \"testShouldReturnEmptyArrayIfNotArray\"":0.023,"WPMediaPluginFamily\\Tests\\Unit\\Model\\PluginFamily\\TestfilterPluginsByActivation::testShouldReturnExpected with data set \"testShouldReturnEmptyArrayIfEmptyArrayParsed\"":0.082,"WPMediaPluginFamily\\Tests\\Unit\\Model\\PluginFamily\\TestfilterPluginsByActivation::testShouldReturnExpected with data set \"testShouldReturnActivePluginAsTheLastElement\"":0.017,"WPMediaPluginFamily\\Tests\\Unit\\Model\\PluginFamily\\TestfilterPluginsByActivation::testShouldReturnExpected with data set \"testShouldReturnCategoryWithActivePluginAsTheLastElement\"":0.006,"WPMediaPluginFamily\\Tests\\Unit\\Model\\PluginFamily\\TestfilterPluginsByActivation::testShouldReturnExpected with data set \"testShouldReturnActivateTextIfPluginIsAlreadyInstalled\"":0.004,"WPMediaPluginFamily\\Tests\\Unit\\Model\\PluginFamily\\TestfilterPluginsByActivation::testShouldReturnExpected with data set \"testShouldReturnUniqueInstallLinkForImagify\"":0.003,"WPMediaPluginFamily\\Tests\\Unit\\Model\\PluginFamily\\TestGetPostInstallEvent::testShouldReturnExpected with data set \"testShouldReturnEmptyArrayIfProperGetParamAreNotSet\"":0.048,"WPMediaPluginFamily\\Tests\\Unit\\Model\\PluginFamily\\TestFilterPluginsByActivation::testShouldReturnExpected with data set \"testShouldReturnEmptyArrayIfEmptyArrayParsed\"":0.035,"WPMediaPluginFamily\\Tests\\Unit\\Model\\PluginFamily\\TestFilterPluginsByActivation::testShouldReturnExpected with data set \"testShouldReturnActivePluginAsTheLastElement\"":0.013,"WPMediaPluginFamily\\Tests\\Unit\\Model\\PluginFamily\\TestFilterPluginsByActivation::testShouldReturnExpected with data set \"testShouldReturnCategoryWithActivePluginAsTheLastElement\"":0.006,"WPMediaPluginFamily\\Tests\\Unit\\Model\\PluginFamily\\TestFilterPluginsByActivation::testShouldReturnExpected with data set \"testShouldReturnActivateTextIfPluginIsAlreadyInstalled\"":0.004,"WPMediaPluginFamily\\Tests\\Unit\\Model\\PluginFamily\\TestFilterPluginsByActivation::testShouldReturnExpected with data set \"testShouldReturnUniqueInstallLinkForImagify\"":0.003,"WPMediaPluginFamily\\Tests\\Unit\\Model\\PluginFamily\\TestGetPostInstallEvent::testShouldReturnExpected with data set \"testShouldReturnEmptyArrayIfActionIsNotValid\"":0.004,"WPMediaPluginFamily\\Tests\\Unit\\Model\\PluginFamily\\TestGetPostInstallEvent::testShouldReturnExpected with data set \"testShouldReturnExpected\"":0.001}} \ No newline at end of file diff --git a/tests/Unit/TestCase.php b/tests/Unit/TestCase.php new file mode 100644 index 0000000..dd6f4e8 --- /dev/null +++ b/tests/Unit/TestCase.php @@ -0,0 +1,35 @@ +config ) ) { + $this->loadTestDataConfig(); + } + } + + public function configTestData() { + if ( empty( $this->config ) ) { + $this->loadTestDataConfig(); + } + + return isset( $this->config['test_data'] ) + ? $this->config['test_data'] + : $this->config; + } + + protected function loadTestDataConfig() { + $obj = new ReflectionObject( $this ); + $filename = $obj->getFileName(); + + $this->config = $this->getTestData( dirname( $filename ), basename( $filename, '.php' ) ); + } +} \ No newline at end of file diff --git a/tests/Unit/bootstrap.php b/tests/Unit/bootstrap.php new file mode 100644 index 0000000..8380fdc --- /dev/null +++ b/tests/Unit/bootstrap.php @@ -0,0 +1,10 @@ + + + + + + src + + + + + + ../../src + + + diff --git a/tests/Unit/src/Controller/PluginFamily/getPostInstallEvent.php b/tests/Unit/src/Controller/PluginFamily/getPostInstallEvent.php new file mode 100644 index 0000000..0f90a50 --- /dev/null +++ b/tests/Unit/src/Controller/PluginFamily/getPostInstallEvent.php @@ -0,0 +1,37 @@ + $value ) { + $_GET[ $param ] = $value; + } + + Functions\when( 'sanitize_text_field' )->justReturn( $_GET['action'] ); + Functions\when( 'wp_unslash' )->justReturn( $_GET['action'] ); + } + + $this->assertSame( $expected, PluginFamily::get_post_install_event() ); + } +} \ No newline at end of file diff --git a/tests/Unit/src/Model/PluginFamily/filterPluginsByActivation.php b/tests/Unit/src/Model/PluginFamily/filterPluginsByActivation.php new file mode 100644 index 0000000..e90b7ff --- /dev/null +++ b/tests/Unit/src/Model/PluginFamily/filterPluginsByActivation.php @@ -0,0 +1,81 @@ +plugin_family = $this->getMockBuilder(PluginFamily::class) + ->setMethods( ['get_current_url'] ) + ->getMock(); + } + + public function tear_down() { + parent::tear_down(); + } + + /** + * @dataProvider configTestData + */ + public function testShouldReturnExpected( $config, $expected ) { + $this->config = $config; + + if ( 'both' === $config['order'] ) { + $this->assertSame( $expected, $this->get_filtered_plugins() ); + return; + } + + Functions\when( 'is_plugin_active' )->alias( function( $plugin ) use ($config) { + return $plugin === $config['active_plugin']; + } ); + + Functions\when( 'admin_url' )->justReturn( 'http://example.org/wp-admin/admin-post.php' ); + Functions\when( 'wp_create_nonce' )->justReturn( '9a68f00b8d' ); + Functions\when( 'add_query_arg' )->alias( function( $args, $link ) { + $url = ''; + + foreach( $args as $param => $value ) { + $url .= $param . '=' . $value . '&'; + } + + return $link . '?' . rtrim( $url, '&' ); + } ); + + $this->plugin_family->method('get_current_url')->willReturn( 'http%3A%2F%2Fexample.org%2Fwp-admin' ); + + if ( isset( $config['is_installed'] ) ) { + Functions\when( 'file_exists' )->justReturn( $config['is_installed'] ); + } + + $this->assertSame( $expected, $this->get_filtered_plugins() ); + } + + private function get_filtered_plugins(): array { + $filtered = $this->plugin_family + ->filter_plugins_by_activation( $this->config['plugins'], $this->config['main_plugin'] ); + + if ( 'both' !== $this->config['order'] ) { + return $filtered[ $this->config['order'] ]; + } + + return $filtered; + } +} \ No newline at end of file From 5553a85d4d432cdbba28a7be67c59ddfef2950a7 Mon Sep 17 00:00:00 2001 From: Michael Lee Date: Tue, 15 Oct 2024 19:11:57 +0100 Subject: [PATCH 09/49] Added patchwork config --- patchwork.json | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 patchwork.json diff --git a/patchwork.json b/patchwork.json new file mode 100644 index 0000000..c7a192c --- /dev/null +++ b/patchwork.json @@ -0,0 +1,3 @@ +{ + "redefinable-internals": ["file_exists"] +} From 88ea2d396d1bdd4d367abfbabfd3b5a3bd11780e Mon Sep 17 00:00:00 2001 From: Michael Lee Date: Tue, 15 Oct 2024 19:12:18 +0100 Subject: [PATCH 10/49] Updated composer packages and script --- composer.json | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/composer.json b/composer.json index beaeda2..04c56d6 100644 --- a/composer.json +++ b/composer.json @@ -18,16 +18,20 @@ "require-dev": { "phpcompatibility/phpcompatibility-wp": "^2.0", "dealerdirect/phpcodesniffer-composer-installer": "^0.7.0", - "wp-coding-standards/wpcs": "^3" + "wp-coding-standards/wpcs": "^3", + "wp-media/phpunit": "^3" }, "autoload": { "psr-4": { - "WPMediaPluginFamily\\": "src/" + "WPMediaPluginFamily\\": "src/", + "WPMediaPluginFamily\\Tests\\": "tests/" } }, "scripts": { "install-codestandards": "Dealerdirect\\Composer\\Plugin\\Installers\\PHPCodeSniffer\\Plugin::run", "phpcs": "phpcs --basepath=.", - "phpcs:fix": "phpcbf" + "phpcs:fix": "phpcbf", + "test-unit": "\"vendor/bin/phpunit\" --testsuite unit --colors=always --configuration tests/Unit/phpunit.xml.dist --coverage-php tests/report/unit.cov", + "report-code-coverage": "\"vendor/bin/phpcov\" merge tests/report --clover tests/report/coverage.clover" } } From d53b905b1833c318dffdb0f90bfe9d683dd1d9cd Mon Sep 17 00:00:00 2001 From: Michael Lee Date: Tue, 15 Oct 2024 19:12:51 +0100 Subject: [PATCH 11/49] Updated method --- src/Controller/PluginFamily.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/Controller/PluginFamily.php b/src/Controller/PluginFamily.php index b1d856a..331708b 100644 --- a/src/Controller/PluginFamily.php +++ b/src/Controller/PluginFamily.php @@ -1,6 +1,6 @@ Date: Tue, 15 Oct 2024 19:13:26 +0100 Subject: [PATCH 12/49] Updated namespace --- src/Controller/PluginFamilyInterface.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Controller/PluginFamilyInterface.php b/src/Controller/PluginFamilyInterface.php index 7237ac3..f060ec5 100644 --- a/src/Controller/PluginFamilyInterface.php +++ b/src/Controller/PluginFamilyInterface.php @@ -1,6 +1,6 @@ Date: Tue, 15 Oct 2024 19:13:50 +0100 Subject: [PATCH 13/49] Updated namespace and methods --- src/Model/PluginFamily.php | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/Model/PluginFamily.php b/src/Model/PluginFamily.php index 3f0e511..17a2a70 100644 --- a/src/Model/PluginFamily.php +++ b/src/Model/PluginFamily.php @@ -1,6 +1,6 @@ Date: Tue, 15 Oct 2024 19:14:06 +0100 Subject: [PATCH 14/49] Added test workflow --- .github/workflows/test.yml | 64 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 64 insertions(+) create mode 100644 .github/workflows/test.yml diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml new file mode 100644 index 0000000..79ab7b9 --- /dev/null +++ b/.github/workflows/test.yml @@ -0,0 +1,64 @@ +name: Unit tests + +on: + pull_request: + branches: + - trunk + - develop + +jobs: + run: + runs-on: ${{ matrix.operating-system }} + + strategy: + fail-fast: true + matrix: + operating-system: [ubuntu-latest] + php-versions: ['7.3', '7.4', '8.0', '8.1', '8.2'] + wp-versions: ['latest'] + + name: WP ${{ matrix.wp-versions }} with PHP ${{ matrix.php-versions }} on ${{ matrix.operating-system }}. + + env: + WP_TESTS_DIR: "/tmp/tests/phpunit" + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Setup PHP + uses: shivammathur/setup-php@v2 + with: + php-version: ${{ matrix.php-versions }} + coverage: xdebug + tools: composer:v2, phpunit + + - name: Setup problem matchers for PHP + run: echo "::add-matcher::${{ runner.tool_cache }}/php.json" + + - name: Setup problem matchers for PHPUnit + run: echo "::add-matcher::${{ runner.tool_cache }}/phpunit.json" + + - name: Require phpcov for coverage reporting + run: composer require --dev --no-scripts phpunit/phpcov -W + + - name: Get composer cache directory + id: composercache + run: echo "::set-output name=dir::$(composer config cache-files-dir)" + + - name: Cache dependencies + uses: actions/cache@v4 + with: + path: ${{ steps.composercache.outputs.dir }} + key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.json') }} + restore-keys: ${{ runner.os }}-composer- + + - name: Install dependencies + run: composer install --prefer-dist --no-interaction --no-scripts + + - name: Unit/Integration tests + run: composer test-unit + + - name: Code Coverage Report + if: ${{ matrix.php-versions == '8.2' }} + run: composer report-code-coverage \ No newline at end of file From e2f0d805753ae461b3e6f081ff5d079f13b97ebb Mon Sep 17 00:00:00 2001 From: Michael Lee Date: Tue, 15 Oct 2024 19:20:01 +0100 Subject: [PATCH 15/49] Remove test cache --- tests/Unit/.phpunit.result.cache | 1 - 1 file changed, 1 deletion(-) delete mode 100644 tests/Unit/.phpunit.result.cache diff --git a/tests/Unit/.phpunit.result.cache b/tests/Unit/.phpunit.result.cache deleted file mode 100644 index 5481751..0000000 --- a/tests/Unit/.phpunit.result.cache +++ /dev/null @@ -1 +0,0 @@ -{"version":1,"defects":{"WPMediaPluginFamily\\Tests\\Unit\\Model\\PluginFamily\\TestfilterPluginsByActivation::testShouldReturnExpected with data set \"testShouldReturnEmptyArrayIfNotArrayOrEmptyArrayParsed\"":5,"WPMediaPluginFamily\\Tests\\Unit\\Model\\PluginFamily\\TestfilterPluginsByActivation::testShouldReturnExpected with data set \"testShouldReturnActivePluginAsTheLastElementForCategorizedArray\"":5,"WPMediaPluginFamily\\Tests\\Unit\\Model\\PluginFamily\\TestfilterPluginsByActivation::testShouldReturnExpected with data set \"testShouldReturnCategoryWithActivePluginAsTheLastElementForUncategorizedArray\"":3,"WPMediaPluginFamily\\Tests\\Unit\\Model\\PluginFamily\\TestfilterPluginsByActivation::testShouldReturnExpected with data set \"testShouldReturnUniqueCtaDataForWprocket\"":4,"WPMediaPluginFamily\\Tests\\Unit\\Model\\PluginFamily\\TestfilterPluginsByActivation::testShouldReturnExpected with data set \"testShouldReturnDifferentInstallUrlForImagify\"":4,"WPMediaPluginFamily\\Tests\\Unit\\Model\\PluginFamily\\TestfilterPluginsByActivation::testShouldReturnExpected with data set \"testShouldReturnAsExpectedForCategorizedAndUncategorizedArray\"":4,"WPMediaPluginFamily\\Tests\\Unit\\Model\\PluginFamily\\TestfilterPluginsByActivation::testShouldReturnExpected with data set \"testShouldReturnEmptyArrayIfNotArray\"":4,"WPMediaPluginFamily\\Tests\\Unit\\Model\\PluginFamily\\TestfilterPluginsByActivation::testShouldReturnExpected with data set \"testShouldReturnEmptyArrayIfEmptyArrayParsed\"":4,"WPMediaPluginFamily\\Tests\\Unit\\Model\\PluginFamily\\TestfilterPluginsByActivation::testShouldReturnExpected with data set \"testShouldReturnActivePluginAsTheLastElement\"":4,"WPMediaPluginFamily\\Tests\\Unit\\Model\\PluginFamily\\TestfilterPluginsByActivation::testShouldReturnExpected with data set \"testShouldReturnCategoryWithActivePluginAsTheLastElement\"":4,"WPMediaPluginFamily\\Tests\\Unit\\Model\\PluginFamily\\TestfilterPluginsByActivation::testShouldReturnExpected with data set \"testShouldReturnActivateTextIfPluginIsAlreadyInstalled\"":4,"WPMediaPluginFamily\\Tests\\Unit\\Model\\PluginFamily\\TestfilterPluginsByActivation::testShouldReturnExpected with data set \"testShouldReturnUniqueInstallLinkForImagify\"":3,"WPMediaPluginFamily\\Tests\\Unit\\Model\\PluginFamily\\TestGetPostInstallEvent::testShouldReturnExpected with data set \"testShouldReturnEmptyArrayIfActionIsNotValid\"":4,"WPMediaPluginFamily\\Tests\\Unit\\Model\\PluginFamily\\TestGetPostInstallEvent::testShouldReturnExpected with data set \"testShouldReturnEmptyArrayIfProperGetParamAreNotSet\"":4,"WPMediaPluginFamily\\Tests\\Unit\\Model\\PluginFamily\\TestGetPostInstallEvent::testShouldReturnExpected with data set \"testShouldReturnExpected\"":3},"times":{"WPMediaPluginFamily\\Tests\\Unit\\Model\\PluginFamily\\TestfilterPluginsByActivation::testShouldReturnExpected with data set \"testShouldReturnEmptyArrayIfNotArrayOrEmptyArrayParsed\"":0.038,"WPMediaPluginFamily\\Tests\\Unit\\Model\\PluginFamily\\TestfilterPluginsByActivation::testShouldReturnExpected with data set \"testShouldReturnActivePluginAsTheLastElementForCategorizedArray\"":0.005,"WPMediaPluginFamily\\Tests\\Unit\\Model\\PluginFamily\\TestfilterPluginsByActivation::testShouldReturnExpected with data set \"testShouldReturnCategoryWithActivePluginAsTheLastElementForUncategorizedArray\"":0.002,"WPMediaPluginFamily\\Tests\\Unit\\Model\\PluginFamily\\TestfilterPluginsByActivation::testShouldReturnExpected with data set \"testShouldReturnUniqueCtaDataForWprocket\"":0.001,"WPMediaPluginFamily\\Tests\\Unit\\Model\\PluginFamily\\TestfilterPluginsByActivation::testShouldReturnExpected with data set \"testShouldReturnDifferentInstallUrlForImagify\"":0.001,"WPMediaPluginFamily\\Tests\\Unit\\Model\\PluginFamily\\TestfilterPluginsByActivation::testShouldReturnExpected with data set \"testShouldReturnAsExpectedForCategorizedAndUncategorizedArray\"":0.001,"WPMediaPluginFamily\\Tests\\Unit\\Model\\PluginFamily\\TestfilterPluginsByActivation::testShouldReturnExpected with data set \"testShouldReturnEmptyArrayIfNotArray\"":0.023,"WPMediaPluginFamily\\Tests\\Unit\\Model\\PluginFamily\\TestfilterPluginsByActivation::testShouldReturnExpected with data set \"testShouldReturnEmptyArrayIfEmptyArrayParsed\"":0.082,"WPMediaPluginFamily\\Tests\\Unit\\Model\\PluginFamily\\TestfilterPluginsByActivation::testShouldReturnExpected with data set \"testShouldReturnActivePluginAsTheLastElement\"":0.017,"WPMediaPluginFamily\\Tests\\Unit\\Model\\PluginFamily\\TestfilterPluginsByActivation::testShouldReturnExpected with data set \"testShouldReturnCategoryWithActivePluginAsTheLastElement\"":0.006,"WPMediaPluginFamily\\Tests\\Unit\\Model\\PluginFamily\\TestfilterPluginsByActivation::testShouldReturnExpected with data set \"testShouldReturnActivateTextIfPluginIsAlreadyInstalled\"":0.004,"WPMediaPluginFamily\\Tests\\Unit\\Model\\PluginFamily\\TestfilterPluginsByActivation::testShouldReturnExpected with data set \"testShouldReturnUniqueInstallLinkForImagify\"":0.003,"WPMediaPluginFamily\\Tests\\Unit\\Model\\PluginFamily\\TestGetPostInstallEvent::testShouldReturnExpected with data set \"testShouldReturnEmptyArrayIfProperGetParamAreNotSet\"":0.048,"WPMediaPluginFamily\\Tests\\Unit\\Model\\PluginFamily\\TestFilterPluginsByActivation::testShouldReturnExpected with data set \"testShouldReturnEmptyArrayIfEmptyArrayParsed\"":0.035,"WPMediaPluginFamily\\Tests\\Unit\\Model\\PluginFamily\\TestFilterPluginsByActivation::testShouldReturnExpected with data set \"testShouldReturnActivePluginAsTheLastElement\"":0.013,"WPMediaPluginFamily\\Tests\\Unit\\Model\\PluginFamily\\TestFilterPluginsByActivation::testShouldReturnExpected with data set \"testShouldReturnCategoryWithActivePluginAsTheLastElement\"":0.006,"WPMediaPluginFamily\\Tests\\Unit\\Model\\PluginFamily\\TestFilterPluginsByActivation::testShouldReturnExpected with data set \"testShouldReturnActivateTextIfPluginIsAlreadyInstalled\"":0.004,"WPMediaPluginFamily\\Tests\\Unit\\Model\\PluginFamily\\TestFilterPluginsByActivation::testShouldReturnExpected with data set \"testShouldReturnUniqueInstallLinkForImagify\"":0.003,"WPMediaPluginFamily\\Tests\\Unit\\Model\\PluginFamily\\TestGetPostInstallEvent::testShouldReturnExpected with data set \"testShouldReturnEmptyArrayIfActionIsNotValid\"":0.004,"WPMediaPluginFamily\\Tests\\Unit\\Model\\PluginFamily\\TestGetPostInstallEvent::testShouldReturnExpected with data set \"testShouldReturnExpected\"":0.001}} \ No newline at end of file From 3672163ced99a372786134ce0870d7710d6bbdfb Mon Sep 17 00:00:00 2001 From: Michael Lee Date: Tue, 15 Oct 2024 19:20:47 +0100 Subject: [PATCH 16/49] Ignore test cache --- .gitignore | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 7602b69..b7a816f 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ /vendor -/composer.lock \ No newline at end of file +/composer.lock +tests/Unit/.phpunit.result.cache \ No newline at end of file From d5af0e302192592197f65153de9dead6d04dae4a Mon Sep 17 00:00:00 2001 From: Michael Lee Date: Wed, 16 Oct 2024 09:42:49 +0100 Subject: [PATCH 17/49] Updated README --- README.md | 73 ++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 72 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index bdebe9d..0b978cd 100644 --- a/README.md +++ b/README.md @@ -1 +1,72 @@ -# wp-media-plugin-family \ No newline at end of file +# WP Media Family Plugin + +This package bundles the WP Media plugin collection within a single plugin. + +## Functionality + +This package gathers essential data about each member plugin and provides their installation and activation links, similar to the [Imagify Partner](https://github.com/wp-media/wp-imagify-partner/) package. It returns an installation link for plugins that are not installed, and an activation link for those that are installed but not active. +For Imagify, the link generated by the Imagify Partner package is used. + +PS: The Imagify Partner package needs be installed along side. refer [here](https://github.com/wp-media/wp-imagify-partner/) for more information. + +## Usage Instructions + +- Install using composer: `composer require wp-media/wp-media-plugin-family` +- Import the model that holds the filtered data into your view class. + +```php +use WPMediaPluginFamily\Model\PluginFamily; + +class View { + protected $plugin_family; + + public function __construct( $plugin_family ) { + $this->plugin_family = $plugin_family; + } + + public function display_page() { + $plugin_family = $this->plugin_family->get_filtered_plugins( 'imagify-plugin/imagify' ); + + $data = [ + 'plugin_family' => $plugin_family['uncategorized'], + ]; + + $this->print_template( 'page-settings', $data ); + } +} +``` +The model returns an array with 2 keys ( categorized & uncategorized ) +- The categorized version has the plugins grouped by their categories. +- The uncategorized version reverse of the former. + +Next, we need to invoke the controller responsible for managing the installation and activation. This controller has a corresponding interface that needs to be implemented. + +```php +use WPMediaPluginFamily\Controller\{ PluginFamily, PluginFamilyInterface }; + +class Subscriber implements SubscriberInterface, PluginFamilyInterface { + + protected $plugin_family; + + public function __construct( $plugin_family ) { + $this->plugin_family = $plugin_family; + } + + public static function get_subscribed_events() { + $events = PluginFamily::get_subscribed_events(); + + return $events; + } + + public function install_activate() { + $this->plugin_family->install_activate(); + } + + public function display_error_notice() { + $this->plugin_family->display_error_notice(); + } +} +``` +The methods ( `install_activate` & `display_error_notice` ) are required. + +PS: This example is based on the assumption that your plugin utilizes EDA. If EDA is not available, you can iterate through the events returned by `PluginFamily::get_subscribed_events()` and use `add_action` accordingly. \ No newline at end of file From 58cf829aaa5970600d005d87f40123afe7866eb4 Mon Sep 17 00:00:00 2001 From: Michael Lee Date: Wed, 16 Oct 2024 09:46:16 +0100 Subject: [PATCH 18/49] Updated README --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 0b978cd..531436f 100644 --- a/README.md +++ b/README.md @@ -37,7 +37,7 @@ class View { ``` The model returns an array with 2 keys ( categorized & uncategorized ) - The categorized version has the plugins grouped by their categories. -- The uncategorized version reverse of the former. +- The uncategorized version is the reverse of the former. Next, we need to invoke the controller responsible for managing the installation and activation. This controller has a corresponding interface that needs to be implemented. From d0002d475c3850bb2e8d80916b7566b9473edc5a Mon Sep 17 00:00:00 2001 From: Michael Lee Date: Wed, 16 Oct 2024 09:55:25 +0100 Subject: [PATCH 19/49] Updated README --- README.md | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 531436f..1d0951b 100644 --- a/README.md +++ b/README.md @@ -69,4 +69,30 @@ class Subscriber implements SubscriberInterface, PluginFamilyInterface { ``` The methods ( `install_activate` & `display_error_notice` ) are required. -PS: This example is based on the assumption that your plugin utilizes EDA. If EDA is not available, you can iterate through the events returned by `PluginFamily::get_subscribed_events()` and use `add_action` accordingly. \ No newline at end of file +PS: This example is based on the assumption that your plugin utilizes EDA. If EDA is not available, you can iterate through the events returned by `PluginFamily::get_subscribed_events()` and use `add_action` accordingly. + +## Development & Testing + +To facilitate development and testing of the package, it is recommended to specify a development branch in the composer.json file of your project. + +## Taking WP Rocket as example + +```JSON +"require": { + "wp-media/wp-media-plugin-family": "dev-whatever-dev-branch" +} +``` + +PS: Always have the dev prefix before the actual branch. + +```JSON +"require": { + "wp-media/wp-media-plugin-family": "dev-develop" +} +"repositories": [ + { + "type": "vcs", + "url": "https://github.com/wp-media/wp-media-plugin-family" + } + ] +``` \ No newline at end of file From 4e9ae88580ab68bb213156dab3523af788d45dc1 Mon Sep 17 00:00:00 2001 From: Michael Lee Date: Wed, 16 Oct 2024 10:26:04 +0100 Subject: [PATCH 20/49] Updated README --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 1d0951b..7fdfcbd 100644 --- a/README.md +++ b/README.md @@ -35,7 +35,8 @@ class View { } } ``` -The model returns an array with 2 keys ( categorized & uncategorized ) +The model returns an array with 2 keys ( categorized & uncategorized ). This for plugins like WP Rocket that needs to display the plugins by category. + - The categorized version has the plugins grouped by their categories. - The uncategorized version is the reverse of the former. From 4b11dda30af262f03010c854f16bf0ffe35ba353 Mon Sep 17 00:00:00 2001 From: Michael Lee Date: Wed, 16 Oct 2024 10:26:34 +0100 Subject: [PATCH 21/49] Updated test --- .../filterPluginsByActivation.php | 28 +++++++++---------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/tests/Fixtures/src/Model/PluginFamily/filterPluginsByActivation.php b/tests/Fixtures/src/Model/PluginFamily/filterPluginsByActivation.php index cd307c3..7e8ba6e 100644 --- a/tests/Fixtures/src/Model/PluginFamily/filterPluginsByActivation.php +++ b/tests/Fixtures/src/Model/PluginFamily/filterPluginsByActivation.php @@ -202,30 +202,30 @@ 'url' => 'http://example.org/wp-admin/admin-post.php?action=plugin_family_install_wp-rocket&_wpnonce=9a68f00b8d&plugin_to_install=wp-rocket%2Fwp-rocket' ], ], - 'seo-by-rank-math/rank-math' => [ + 'imagify-plugin/imagify' => [ 'logo' => [ - 'file' => 'logo-rank-math.svg', - 'width' => '60%', + 'file' => 'logo-imagify.svg', + 'width' => '50%', ], - 'title' => 'The Swiss Army Knife of SEO Tools', - 'desc' => 'Rank Math SEO is the Best WordPress SEO plugin with the features of many SEO and AI SEO tools in a single package to help multiply your SEO traffic.', - 'link' => 'https://rankmath.com/wordpress/plugin/seo-suite/', + 'title' => 'Speed Up Your Website With Lighter Images', + 'desc' => 'Imagify is the easiest WordPress image optimizer. It automatically compresses images, converts them to WebP and AVIF formats, and lets you resize and optimize with just one click!', + 'link' => 'https://imagify.io/', 'cta' => [ 'text' => 'Activate', - 'url' => 'http://example.org/wp-admin/admin-post.php?action=plugin_family_install_seo-by-rank-math&_wpnonce=9a68f00b8d&plugin_to_install=seo-by-rank-math%2Frank-math' + 'url' => 'http://example.org/wp-admin/admin-post.php?action=install_imagify_from_partner_backwpup&_wpnonce=9a68f00b8d&_wp_http_referer=http%253A%252F%252Fexample.org%252Fwp-admin' ], ], - 'backwpup/backwpup' => [ + 'seo-by-rank-math/rank-math' => [ 'logo' => [ - 'file' => 'logo-backwpup.svg', + 'file' => 'logo-rank-math.svg', 'width' => '60%', ], - 'title' => 'The Easiest Way to Protect Your Website', - 'desc' => 'BackWPup is the most comprehensive and user-friendly backup & restore plugin for WordPress. Easily schedule automatic backups, securely store and restore with just a few clicks!', - 'link' => 'https://backwpup.com/', + 'title' => 'The Swiss Army Knife of SEO Tools', + 'desc' => 'Rank Math SEO is the Best WordPress SEO plugin with the features of many SEO and AI SEO tools in a single package to help multiply your SEO traffic.', + 'link' => 'https://rankmath.com/wordpress/plugin/seo-suite/', 'cta' => [ 'text' => 'Activate', - 'url' => 'http://example.org/wp-admin/admin-post.php?action=plugin_family_install_backwpup&_wpnonce=9a68f00b8d&plugin_to_install=backwpup%2Fbackwpup' + 'url' => 'http://example.org/wp-admin/admin-post.php?action=plugin_family_install_seo-by-rank-math&_wpnonce=9a68f00b8d&plugin_to_install=seo-by-rank-math%2Frank-math' ], ], 'uk-cookie-consent/uk-cookie-consent' => [ @@ -328,7 +328,7 @@ 'testShouldReturnActivateTextIfPluginIsAlreadyInstalled' => [ 'config' => [ 'plugins' => $plugins, - 'main_plugin' => 'imagify-plugin/imagify', + 'main_plugin' => 'backwpup/backwpup', 'order' => 'uncategorized', 'active_plugin' => '', 'is_installed' => true, From 4bec6fec7ada5e625b1b0d0fe6710aee8ad8b34e Mon Sep 17 00:00:00 2001 From: Michael Lee Date: Thu, 17 Oct 2024 11:18:31 +0100 Subject: [PATCH 22/49] Updated README --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 7fdfcbd..33e8b4c 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# WP Media Family Plugin +# Plugin Family This package bundles the WP Media plugin collection within a single plugin. From d12ca1df1271b1f0308ccbfcb4fc13a7ba2b5bcc Mon Sep 17 00:00:00 2001 From: Michael Lee Date: Thu, 17 Oct 2024 11:29:27 +0100 Subject: [PATCH 23/49] Updated namespace --- composer.json | 10 +++++++--- src/Controller/PluginFamily.php | 4 +--- src/Controller/PluginFamilyInterface.php | 2 +- src/Model/PluginFamily.php | 2 +- tests/Unit/TestCase.php | 2 +- .../Controller/PluginFamily/getPostInstallEvent.php | 6 +++--- .../Model/PluginFamily/filterPluginsByActivation.php | 6 +++--- 7 files changed, 17 insertions(+), 15 deletions(-) diff --git a/composer.json b/composer.json index 04c56d6..bdec3d9 100644 --- a/composer.json +++ b/composer.json @@ -1,5 +1,5 @@ { - "name": "wp-media/wp-media-plugin-family", + "name": "wp-media/plugin-family", "description": "Organizes and displays WP Media plugin family across other members.", "license": "GPL-3.0-or-later", "authors": [ @@ -23,8 +23,12 @@ }, "autoload": { "psr-4": { - "WPMediaPluginFamily\\": "src/", - "WPMediaPluginFamily\\Tests\\": "tests/" + "WPMedia\\PluginFamily\\": "src/" + } + }, + "autoload-dev": { + "psr-4": { + "WPMedia\\PluginFamily\\Tests\\": "tests/" } }, "scripts": { diff --git a/src/Controller/PluginFamily.php b/src/Controller/PluginFamily.php index 331708b..a706cc4 100644 --- a/src/Controller/PluginFamily.php +++ b/src/Controller/PluginFamily.php @@ -1,8 +1,6 @@ Date: Thu, 17 Oct 2024 11:41:11 +0100 Subject: [PATCH 24/49] Added phpstan --- composer.json | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/composer.json b/composer.json index bdec3d9..ec571a0 100644 --- a/composer.json +++ b/composer.json @@ -19,7 +19,9 @@ "phpcompatibility/phpcompatibility-wp": "^2.0", "dealerdirect/phpcodesniffer-composer-installer": "^0.7.0", "wp-coding-standards/wpcs": "^3", - "wp-media/phpunit": "^3" + "wp-media/phpunit": "^3", + "phpstan/extension-installer": "^1.4", + "szepeviktor/phpstan-wordpress": "^1.3" }, "autoload": { "psr-4": { From f8454ab5c854e242192372e4ab606f0f9ea082b9 Mon Sep 17 00:00:00 2001 From: Michael Lee Date: Thu, 17 Oct 2024 12:40:42 +0100 Subject: [PATCH 25/49] Fixed phpstan errors --- src/Controller/PluginFamily.php | 29 +++++++++++++++++++++++++++-- src/Model/PluginFamily.php | 4 +--- 2 files changed, 28 insertions(+), 5 deletions(-) diff --git a/src/Controller/PluginFamily.php b/src/Controller/PluginFamily.php index a706cc4..fcdafbd 100644 --- a/src/Controller/PluginFamily.php +++ b/src/Controller/PluginFamily.php @@ -93,7 +93,17 @@ private function install() { return; } - require_once ABSPATH . 'wp-admin/includes/class-wp-upgrader.php'; + $upgrader_class = ABSPATH . 'wp-admin/includes/class-wp-upgrader.php'; + + if ( ! defined( 'ABSPATH' ) || ! file_exists( $upgrader_class ) ) { + wp_die( + 'Plugin Installation failed. class-wp-upgrader.php not found', + '', + [ 'back_link' => true ] + ); + } + + require_once $upgrader_class; // @phpstan-ignore-line $upgrader = new \Plugin_Upgrader( new \Automatic_Upgrader_Skin() ); $result = $upgrader->install( $this->get_download_url() ); @@ -155,7 +165,17 @@ private function get_plugin(): string { * @return string */ private function get_download_url(): string { - require_once ABSPATH . 'wp-admin/includes/plugin-install.php'; + $plugin_install = ABSPATH . 'wp-admin/includes/plugin-install.php'; + + if ( ! defined( 'ABSPATH' ) || ! file_exists( $plugin_install ) ) { + wp_die( + 'Plugin Installation failed. plugin-install.php not found', + '', + [ 'back_link' => true ] + ); + } + + require_once $upgrader_class; // @phpstan-ignore-line $data = [ 'slug' => $this->get_slug(), @@ -181,6 +201,11 @@ private function get_download_url(): string { $this->set_error( $plugin_info ); } + // Ensure that $plugin_info is an object before accessing the property. + if ( ! is_object( $plugin_info ) || ! isset( $plugin_info->download_link ) ) { + return ''; + } + return $plugin_info->download_link; } diff --git a/src/Model/PluginFamily.php b/src/Model/PluginFamily.php index 54279bd..d63bee7 100644 --- a/src/Model/PluginFamily.php +++ b/src/Model/PluginFamily.php @@ -2,8 +2,6 @@ namespace WPMedia\PluginFamily\Model; -defined( 'ABSPATH' ) || exit; - /** * Handles the data to be passed to the frontend. */ @@ -30,7 +28,7 @@ public function get_filtered_plugins( string $main_plugin ): array { * @return array */ public function filter_plugins_by_activation( array $plugins, string $main_plugin ): array { - if ( ! is_array( $plugins ) || empty( $plugins ) ) { + if ( empty( $plugins ) ) { return []; } From ecf9f67ff8d4ca826b90598d99ef032db234af2f Mon Sep 17 00:00:00 2001 From: Michael Lee Date: Thu, 17 Oct 2024 12:41:06 +0100 Subject: [PATCH 26/49] Updated composer.json --- composer.json | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/composer.json b/composer.json index ec571a0..ad4cf3c 100644 --- a/composer.json +++ b/composer.json @@ -12,7 +12,8 @@ "config": { "sort-packages": true, "allow-plugins": { - "dealerdirect/phpcodesniffer-composer-installer": true + "dealerdirect/phpcodesniffer-composer-installer": true, + "phpstan/extension-installer": true } }, "require-dev": { @@ -38,6 +39,7 @@ "phpcs": "phpcs --basepath=.", "phpcs:fix": "phpcbf", "test-unit": "\"vendor/bin/phpunit\" --testsuite unit --colors=always --configuration tests/Unit/phpunit.xml.dist --coverage-php tests/report/unit.cov", - "report-code-coverage": "\"vendor/bin/phpcov\" merge tests/report --clover tests/report/coverage.clover" + "report-code-coverage": "\"vendor/bin/phpcov\" merge tests/report --clover tests/report/coverage.clover", + "phpstan": "vendor/bin/phpstan analyze --memory-limit=2G --no-progress" } } From ce0f113aa48be6b5ef8ee942fe5bb7ccbcc89545 Mon Sep 17 00:00:00 2001 From: Michael Lee Date: Thu, 17 Oct 2024 12:41:23 +0100 Subject: [PATCH 27/49] Added phpstan config --- phpstan.neon.dist | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 phpstan.neon.dist diff --git a/phpstan.neon.dist b/phpstan.neon.dist new file mode 100644 index 0000000..5e36fec --- /dev/null +++ b/phpstan.neon.dist @@ -0,0 +1,6 @@ +includes: + - phar://phpstan.phar/conf/bleedingEdge.neon +parameters: + level: 5 + paths: + - %currentWorkingDirectory%/src \ No newline at end of file From 2c7bb56d50603eebb7270ab16263b8f91a2499da Mon Sep 17 00:00:00 2001 From: Michael Lee Date: Thu, 17 Oct 2024 12:43:24 +0100 Subject: [PATCH 28/49] Added workflow file for phpstan --- .github/workflows/phpstan.yml | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 .github/workflows/phpstan.yml diff --git a/.github/workflows/phpstan.yml b/.github/workflows/phpstan.yml new file mode 100644 index 0000000..06339ea --- /dev/null +++ b/.github/workflows/phpstan.yml @@ -0,0 +1,35 @@ +name: PHP Stan lint + +on: + pull_request: + branches: + - trunk + - develop + +jobs: + run: + runs-on: ${{ matrix.operating-system }} + + strategy: + fail-fast: false + matrix: + operating-system: [ubuntu-latest] + php-versions: ['8.2'] + + name: Lint with PHP Stan. PHP ${{ matrix.php-versions }} on ${{ matrix.operating-system }}. + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Setup PHP + uses: shivammathur/setup-php@v2 + with: + php-version: ${{ matrix.php-versions }} + coverage: none # XDebug can be enabled here 'coverage: xdebug' + tools: composer:v2 + + - name: Install dependencies + run: composer install --prefer-dist --no-interaction --no-scripts + + - name: Lint with PHP Stan + run: composer phpstan -- --error-format=github \ No newline at end of file From e25931f7117ba5acdadf441c0d0603866665bcf5 Mon Sep 17 00:00:00 2001 From: Michael Lee Date: Thu, 17 Oct 2024 12:45:18 +0100 Subject: [PATCH 29/49] Updated namespace --- src/Controller/PluginFamilyInterface.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/Controller/PluginFamilyInterface.php b/src/Controller/PluginFamilyInterface.php index b41d11c..e4fbe87 100644 --- a/src/Controller/PluginFamilyInterface.php +++ b/src/Controller/PluginFamilyInterface.php @@ -2,8 +2,6 @@ namespace WPMedia\PluginFamily\Controller; -defined( 'ABSPATH' ) || exit; - interface PluginFamilyInterface { /** * Process to install and activate plugin. From 276981e4937ce278626aace5d6e66083d21a18bd Mon Sep 17 00:00:00 2001 From: Michael Lee Date: Thu, 17 Oct 2024 12:59:53 +0100 Subject: [PATCH 30/49] use defined var --- src/Controller/PluginFamily.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Controller/PluginFamily.php b/src/Controller/PluginFamily.php index fcdafbd..26aad5b 100644 --- a/src/Controller/PluginFamily.php +++ b/src/Controller/PluginFamily.php @@ -175,7 +175,7 @@ private function get_download_url(): string { ); } - require_once $upgrader_class; // @phpstan-ignore-line + require_once $plugin_install; // @phpstan-ignore-line $data = [ 'slug' => $this->get_slug(), From a72f32d10c7c6bc9bb771a6038e42d15daadc5c9 Mon Sep 17 00:00:00 2001 From: Michael Lee Date: Thu, 17 Oct 2024 14:22:35 +0100 Subject: [PATCH 31/49] Updated README --- README.md | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 33e8b4c..3afd066 100644 --- a/README.md +++ b/README.md @@ -11,11 +11,11 @@ PS: The Imagify Partner package needs be installed along side. refer [here](http ## Usage Instructions -- Install using composer: `composer require wp-media/wp-media-plugin-family` +- Install using composer: `composer require wp-media/plugin-family` - Import the model that holds the filtered data into your view class. ```php -use WPMediaPluginFamily\Model\PluginFamily; +use WPMedia\PluginFamily\Model\PluginFamily; class View { protected $plugin_family; @@ -43,7 +43,7 @@ The model returns an array with 2 keys ( categorized & uncategorized ). This for Next, we need to invoke the controller responsible for managing the installation and activation. This controller has a corresponding interface that needs to be implemented. ```php -use WPMediaPluginFamily\Controller\{ PluginFamily, PluginFamilyInterface }; +use WPMedia\PluginFamily\Controller\{ PluginFamily, PluginFamilyInterface }; class Subscriber implements SubscriberInterface, PluginFamilyInterface { @@ -80,20 +80,17 @@ To facilitate development and testing of the package, it is recommended to speci ```JSON "require": { - "wp-media/wp-media-plugin-family": "dev-whatever-dev-branch" + "wp-media/plugin-family": "dev-whatever-dev-branch" } ``` PS: Always have the dev prefix before the actual branch. ```JSON -"require": { - "wp-media/wp-media-plugin-family": "dev-develop" -} "repositories": [ { "type": "vcs", - "url": "https://github.com/wp-media/wp-media-plugin-family" + "url": "https://github.com/wp-media/plugin-family" } ] ``` \ No newline at end of file From 7bf9c44232f1679efe7d4d7076f1c3bbb5819c5d Mon Sep 17 00:00:00 2001 From: Michael Lee Date: Fri, 18 Oct 2024 11:36:24 +0100 Subject: [PATCH 32/49] Updated tests --- .../filterPluginsByActivation.php | 4 ++-- .../filterPluginsByActivation.php | 23 ++++++++++++++----- 2 files changed, 19 insertions(+), 8 deletions(-) diff --git a/tests/Fixtures/src/Model/PluginFamily/filterPluginsByActivation.php b/tests/Fixtures/src/Model/PluginFamily/filterPluginsByActivation.php index 7e8ba6e..a2253d7 100644 --- a/tests/Fixtures/src/Model/PluginFamily/filterPluginsByActivation.php +++ b/tests/Fixtures/src/Model/PluginFamily/filterPluginsByActivation.php @@ -212,7 +212,7 @@ 'link' => 'https://imagify.io/', 'cta' => [ 'text' => 'Activate', - 'url' => 'http://example.org/wp-admin/admin-post.php?action=install_imagify_from_partner_backwpup&_wpnonce=9a68f00b8d&_wp_http_referer=http%253A%252F%252Fexample.org%252Fwp-admin' + 'url' => 'http://example.org/wp-admin/admin-post.php?action=install_imagify_from_partner_backwpup&_wpnonce=9a68f00b8d&_wp_http_referer=https%3A%2F%2Fexample.org%2Fwp-admin' ], ], 'seo-by-rank-math/rank-math' => [ @@ -267,7 +267,7 @@ 'link' => 'https://imagify.io/', 'cta' => [ 'text' => 'Install', - 'url' => 'http://example.org/wp-admin/admin-post.php?action=install_imagify_from_partner_uk-cookie-consent&_wpnonce=9a68f00b8d&_wp_http_referer=http%253A%252F%252Fexample.org%252Fwp-admin' + 'url' => 'http://example.org/wp-admin/admin-post.php?action=install_imagify_from_partner_uk-cookie-consent&_wpnonce=9a68f00b8d&_wp_http_referer=https%3A%2F%2Fexample.org%2Fwp-admin' ], ], 'seo-by-rank-math/rank-math' => [ diff --git a/tests/Unit/src/Model/PluginFamily/filterPluginsByActivation.php b/tests/Unit/src/Model/PluginFamily/filterPluginsByActivation.php index 5f8a14d..c8257e0 100644 --- a/tests/Unit/src/Model/PluginFamily/filterPluginsByActivation.php +++ b/tests/Unit/src/Model/PluginFamily/filterPluginsByActivation.php @@ -22,13 +22,19 @@ class TestFilterPluginsByActivation extends TestCase { public function set_up() { parent::set_up(); - - $this->plugin_family = $this->getMockBuilder(PluginFamily::class) - ->setMethods( ['get_current_url'] ) - ->getMock(); + + $this->plugin_family = new PluginFamily(); + + $_SERVER = [ + 'SERVER_PORT' => 80, + 'HTTP_HOST' => 'example.org', + 'REQUEST_URI' => '/wp-admin', + ]; } public function tear_down() { + $_SERVER = []; + parent::tear_down(); } @@ -47,7 +53,11 @@ public function testShouldReturnExpected( $config, $expected ) { return $plugin === $config['active_plugin']; } ); - Functions\when( 'admin_url' )->justReturn( 'http://example.org/wp-admin/admin-post.php' ); + Functions\when( 'admin_url' )->alias( + function ( $path ) { + return "http://example.org/wp-admin/{$path}"; + } + ); Functions\when( 'wp_create_nonce' )->justReturn( '9a68f00b8d' ); Functions\when( 'add_query_arg' )->alias( function( $args, $link ) { $url = ''; @@ -59,7 +69,8 @@ public function testShouldReturnExpected( $config, $expected ) { return $link . '?' . rtrim( $url, '&' ); } ); - $this->plugin_family->method('get_current_url')->willReturn( 'http%3A%2F%2Fexample.org%2Fwp-admin' ); + Functions\when( 'wp_unslash' )->returnArg(); + Functions\when( 'is_ssl' )->justReturn( true ); if ( isset( $config['is_installed'] ) ) { Functions\when( 'file_exists' )->justReturn( $config['is_installed'] ); From 193a534602a0c5aee6f50679076a3fa09168a235 Mon Sep 17 00:00:00 2001 From: Michael Lee Date: Mon, 21 Oct 2024 14:25:07 +0100 Subject: [PATCH 33/49] Make wp rocket referrer dynamic --- src/Model/PluginFamily.php | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/src/Model/PluginFamily.php b/src/Model/PluginFamily.php index d63bee7..6b59921 100644 --- a/src/Model/PluginFamily.php +++ b/src/Model/PluginFamily.php @@ -6,6 +6,19 @@ * Handles the data to be passed to the frontend. */ class PluginFamily { + + /** + * An array of referrers for wp rocket. + * + * @var array + */ + protected $wp_rocket_referrer = [ + 'imagify-plugin' => 'imagify', + 'seo-by-rank-math' => '', + 'backwpup' => '', + 'uk-cookie-consent' => '', + ]; + /** * Get filtered plugins. * @@ -40,6 +53,7 @@ public function filter_plugins_by_activation( array $plugins, string $main_plugi $plugin_path = $plugin . '.php'; $plugin_slug = dirname( $plugin ); $main_plugin_slug = dirname( $main_plugin ); + $wpr_referrer = 'wp-rocket' !== $main_plugin_slug ? $this->wp_rocket_referrer[ $main_plugin_slug ] : ''; /** * Check for activated plugins and pop them out of the array @@ -96,10 +110,14 @@ public function filter_plugins_by_activation( array $plugins, string $main_plugi // Create unique CTA data for WP Rocket. if ( 'wp-rocket/wp-rocket' === $plugin ) { + $url = 'https://wp-rocket.me/?utm_source=' . $wpr_referrer . '-coupon&utm_medium=plugin&utm_campaign=' . $wpr_referrer; + $plugins[ $cat ]['plugins'][ $plugin ]['cta'] = [ 'text' => 'Get it Now', - 'url' => 'https://wp-rocket.me/?utm_source=imagify-coupon&utm_medium=plugin&utm_campaign=imagify', + 'url' => $url, ]; + + $plugins[ $cat ]['plugins'][ $plugin ]['link'] = $url; } // Set activation text. From 9453a5fc743ec5abe9c3c8ab63a4740f3ab17f90 Mon Sep 17 00:00:00 2001 From: Michael Lee Date: Mon, 21 Oct 2024 14:29:28 +0100 Subject: [PATCH 34/49] Updated data --- src/Model/wp_media_plugins.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Model/wp_media_plugins.php b/src/Model/wp_media_plugins.php index 46bf8ef..0432334 100644 --- a/src/Model/wp_media_plugins.php +++ b/src/Model/wp_media_plugins.php @@ -14,7 +14,7 @@ ], 'title' => 'Speed Up Your Website, Instantly', 'desc' => 'WP Rocket is the easiest way to make your WordPress website faster and boost your Google PageSpeed score. Get more traffic, better engagement, and higher conversions effortlessly.', - 'link' => 'https://wp-rocket.me/?utm_source=imagify-coupon&utm_medium=plugin&utm_campaign=imagify', + 'link' => '', ], 'imagify-plugin/imagify' => [ 'logo' => [ From e198429d0747870b81a4467e0e8435a80ead4515 Mon Sep 17 00:00:00 2001 From: Michael Lee Date: Mon, 21 Oct 2024 14:29:46 +0100 Subject: [PATCH 35/49] Updated tests --- .../src/Model/PluginFamily/filterPluginsByActivation.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/Fixtures/src/Model/PluginFamily/filterPluginsByActivation.php b/tests/Fixtures/src/Model/PluginFamily/filterPluginsByActivation.php index a2253d7..f37df58 100644 --- a/tests/Fixtures/src/Model/PluginFamily/filterPluginsByActivation.php +++ b/tests/Fixtures/src/Model/PluginFamily/filterPluginsByActivation.php @@ -196,7 +196,7 @@ ], 'title' => 'Speed Up Your Website, Instantly', 'desc' => 'WP Rocket is the easiest way to make your WordPress website faster and boost your Google PageSpeed score. Get more traffic, better engagement, and higher conversions effortlessly.', - 'link' => 'https://wp-rocket.me/?utm_source=imagify-coupon&utm_medium=plugin&utm_campaign=imagify', + 'link' => 'https://wp-rocket.me/?utm_source=-coupon&utm_medium=plugin&utm_campaign=', 'cta' => [ 'text' => 'Activate', 'url' => 'http://example.org/wp-admin/admin-post.php?action=plugin_family_install_wp-rocket&_wpnonce=9a68f00b8d&plugin_to_install=wp-rocket%2Fwp-rocket' @@ -251,10 +251,10 @@ ], 'title' => 'Speed Up Your Website, Instantly', 'desc' => 'WP Rocket is the easiest way to make your WordPress website faster and boost your Google PageSpeed score. Get more traffic, better engagement, and higher conversions effortlessly.', - 'link' => 'https://wp-rocket.me/?utm_source=imagify-coupon&utm_medium=plugin&utm_campaign=imagify', + 'link' => 'https://wp-rocket.me/?utm_source=-coupon&utm_medium=plugin&utm_campaign=', 'cta' => [ 'text' => 'Get it Now', - 'url' => 'https://wp-rocket.me/?utm_source=imagify-coupon&utm_medium=plugin&utm_campaign=imagify' + 'url' => 'https://wp-rocket.me/?utm_source=-coupon&utm_medium=plugin&utm_campaign=' ], ], 'imagify-plugin/imagify' => [ From 13ddeeea9e299ca670db96b384f651f5e32a0cba Mon Sep 17 00:00:00 2001 From: Michael Lee Date: Mon, 21 Oct 2024 14:30:23 +0100 Subject: [PATCH 36/49] Added git attribute file --- .gitattributes | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 .gitattributes diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..2649aa9 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,9 @@ +.github export-ignore +tests export-ignore +.gitattributes export-ignore +.gitignore export-ignore +patchwork.json export-ignore +phpcs.xml export-ignore +phpstan.neon.dist export-ignore +README.md export-ignore + From d62f483c9ba063206f2084e5fe43e8e9e34b7af5 Mon Sep 17 00:00:00 2001 From: Michael Lee Date: Mon, 21 Oct 2024 14:49:30 +0100 Subject: [PATCH 37/49] Fixed phpcs --- src/Model/PluginFamily.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Model/PluginFamily.php b/src/Model/PluginFamily.php index 6b59921..b3e616d 100644 --- a/src/Model/PluginFamily.php +++ b/src/Model/PluginFamily.php @@ -13,9 +13,9 @@ class PluginFamily { * @var array */ protected $wp_rocket_referrer = [ - 'imagify-plugin' => 'imagify', - 'seo-by-rank-math' => '', - 'backwpup' => '', + 'imagify-plugin' => 'imagify', + 'seo-by-rank-math' => '', + 'backwpup' => '', 'uk-cookie-consent' => '', ]; @@ -53,7 +53,7 @@ public function filter_plugins_by_activation( array $plugins, string $main_plugi $plugin_path = $plugin . '.php'; $plugin_slug = dirname( $plugin ); $main_plugin_slug = dirname( $main_plugin ); - $wpr_referrer = 'wp-rocket' !== $main_plugin_slug ? $this->wp_rocket_referrer[ $main_plugin_slug ] : ''; + $wpr_referrer = 'wp-rocket' !== $main_plugin_slug ? $this->wp_rocket_referrer[ $main_plugin_slug ] : ''; /** * Check for activated plugins and pop them out of the array From 0c8a7d4c7d248bac6e2fc7ea49be3e421f8b4684 Mon Sep 17 00:00:00 2001 From: Opeyemi Ibrahim Date: Fri, 25 Oct 2024 07:03:43 +0100 Subject: [PATCH 38/49] :fixes: #6 change imagify plugin path --- src/Model/wp_media_plugins.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Model/wp_media_plugins.php b/src/Model/wp_media_plugins.php index 0432334..6036432 100644 --- a/src/Model/wp_media_plugins.php +++ b/src/Model/wp_media_plugins.php @@ -16,7 +16,7 @@ 'desc' => 'WP Rocket is the easiest way to make your WordPress website faster and boost your Google PageSpeed score. Get more traffic, better engagement, and higher conversions effortlessly.', 'link' => '', ], - 'imagify-plugin/imagify' => [ + 'imagify/imagify' => [ 'logo' => [ 'file' => 'logo-imagify.svg', 'width' => '50%', From 22da91b90dab963cd8c4efb083c501d962b2083d Mon Sep 17 00:00:00 2001 From: Opeyemi Ibrahim Date: Fri, 25 Oct 2024 07:23:51 +0100 Subject: [PATCH 39/49] Fix install event for imagify --- src/Controller/PluginFamily.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Controller/PluginFamily.php b/src/Controller/PluginFamily.php index 26aad5b..eb08d67 100644 --- a/src/Controller/PluginFamily.php +++ b/src/Controller/PluginFamily.php @@ -35,7 +35,7 @@ public static function get_post_install_event(): array { $allowed_plugin = [ 'uk-cookie-consent', 'backwpup', - 'imagify-plugin', + 'imagify', 'seo-by-rank-math', 'wp-rocket', ]; From 2796befc077c18d6ba8fb7cfccec1d84e1cbf2eb Mon Sep 17 00:00:00 2001 From: Opeyemi Ibrahim Date: Fri, 25 Oct 2024 08:15:44 +0100 Subject: [PATCH 40/49] Fix imagify urls --- src/Model/PluginFamily.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Model/PluginFamily.php b/src/Model/PluginFamily.php index b3e616d..7c57795 100644 --- a/src/Model/PluginFamily.php +++ b/src/Model/PluginFamily.php @@ -92,7 +92,7 @@ public function filter_plugins_by_activation( array $plugins, string $main_plugi 'plugin_to_install' => rawurlencode( $plugin ), ]; - if ( 'imagify-plugin' === $plugin_slug ) { + if ( 'imagify' === $plugin_slug ) { $args = [ 'action' => 'install_imagify_from_partner_' . $main_plugin_slug, '_wpnonce' => wp_create_nonce( 'install_imagify_from_partner' ), From 60a034d8a6baa3819a60c07b878ca8b0975f536d Mon Sep 17 00:00:00 2001 From: Opeyemi Ibrahim Date: Fri, 25 Oct 2024 08:19:59 +0100 Subject: [PATCH 41/49] Fix lint error --- src/Model/wp_media_plugins.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Model/wp_media_plugins.php b/src/Model/wp_media_plugins.php index 6036432..e1a1e29 100644 --- a/src/Model/wp_media_plugins.php +++ b/src/Model/wp_media_plugins.php @@ -7,7 +7,7 @@ 'optimize_performance' => [ 'title' => 'Optimize Performance', 'plugins' => [ - 'wp-rocket/wp-rocket' => [ + 'wp-rocket/wp-rocket' => [ 'logo' => [ 'file' => 'logo-wp-rocket.svg', 'width' => '50%', @@ -16,7 +16,7 @@ 'desc' => 'WP Rocket is the easiest way to make your WordPress website faster and boost your Google PageSpeed score. Get more traffic, better engagement, and higher conversions effortlessly.', 'link' => '', ], - 'imagify/imagify' => [ + 'imagify/imagify' => [ 'logo' => [ 'file' => 'logo-imagify.svg', 'width' => '50%', From f982832a607e17fe6e014c470bb3cfb0e5ac0e5e Mon Sep 17 00:00:00 2001 From: Opeyemi Ibrahim Date: Fri, 25 Oct 2024 09:47:51 +0100 Subject: [PATCH 42/49] fix test error --- src/Model/PluginFamily.php | 2 +- .../Model/PluginFamily/filterPluginsByActivation.php | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/Model/PluginFamily.php b/src/Model/PluginFamily.php index 7c57795..ef75280 100644 --- a/src/Model/PluginFamily.php +++ b/src/Model/PluginFamily.php @@ -13,7 +13,7 @@ class PluginFamily { * @var array */ protected $wp_rocket_referrer = [ - 'imagify-plugin' => 'imagify', + 'imagify' => 'imagify', 'seo-by-rank-math' => '', 'backwpup' => '', 'uk-cookie-consent' => '', diff --git a/tests/Fixtures/src/Model/PluginFamily/filterPluginsByActivation.php b/tests/Fixtures/src/Model/PluginFamily/filterPluginsByActivation.php index f37df58..14ca685 100644 --- a/tests/Fixtures/src/Model/PluginFamily/filterPluginsByActivation.php +++ b/tests/Fixtures/src/Model/PluginFamily/filterPluginsByActivation.php @@ -13,7 +13,7 @@ 'desc' => 'WP Rocket is the easiest way to make your WordPress website faster and boost your Google PageSpeed score. Get more traffic, better engagement, and higher conversions effortlessly.', 'link' => 'https://wp-rocket.me/?utm_source=imagify-coupon&utm_medium=plugin&utm_campaign=imagify', ], - 'imagify-plugin/imagify' => [ + 'imagify/imagify' => [ 'logo' => [ 'file' => 'logo-imagify.svg', 'width' => '50%', @@ -116,7 +116,7 @@ 'optimize_performance' => [ 'title' => 'Optimize Performance', 'plugins' => [ - 'imagify-plugin/imagify' => [ + 'imagify/imagify' => [ 'logo' => [ 'file' => 'logo-imagify.svg', 'width' => '50%', @@ -202,7 +202,7 @@ 'url' => 'http://example.org/wp-admin/admin-post.php?action=plugin_family_install_wp-rocket&_wpnonce=9a68f00b8d&plugin_to_install=wp-rocket%2Fwp-rocket' ], ], - 'imagify-plugin/imagify' => [ + 'imagify/imagify' => [ 'logo' => [ 'file' => 'logo-imagify.svg', 'width' => '50%', @@ -257,7 +257,7 @@ 'url' => 'https://wp-rocket.me/?utm_source=-coupon&utm_medium=plugin&utm_campaign=' ], ], - 'imagify-plugin/imagify' => [ + 'imagify/imagify' => [ 'logo' => [ 'file' => 'logo-imagify.svg', 'width' => '50%', @@ -312,14 +312,14 @@ 'plugins' => $plugins, 'main_plugin' => 'wp-rocket/wp-rocket', 'order' => 'categorized', - 'active_plugin' => 'imagify-plugin/imagify.php', + 'active_plugin' => 'imagify/imagify.php', ], 'expected' => $expectedActivePluginAsTheLastElement, ], 'testShouldReturnCategoryWithActivePluginAsTheLastElement' => [ 'config' => [ 'plugins' => $plugins, - 'main_plugin' => 'imagify-plugin/imagify', + 'main_plugin' => 'imagify/imagify', 'order' => 'uncategorized', 'active_plugin' => 'seo-by-rank-math/rank-math.php', ], From 9e303488571b5989c4582d6452830eba45c29441 Mon Sep 17 00:00:00 2001 From: Michael Lee Date: Fri, 25 Oct 2024 11:31:11 +0100 Subject: [PATCH 43/49] Directly reference plugin array copy --- src/Model/PluginFamily.php | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/Model/PluginFamily.php b/src/Model/PluginFamily.php index b3e616d..785f4d2 100644 --- a/src/Model/PluginFamily.php +++ b/src/Model/PluginFamily.php @@ -71,16 +71,18 @@ public function filter_plugins_by_activation( array $plugins, string $main_plugi $active_plugins[ $plugin ] = $plugins[ $cat ]['plugins'][ $plugin ]; // Remove active plugin from current category. - unset( $cat_data['plugins'][ $plugin ] ); + $active_plugin = $plugins[ $cat ]['plugins'][ $plugin ]; + unset( $plugins[ $cat ]['plugins'][ $plugin ] ); // Send active plugin to the end of array in current category. - $cat_data['plugins'][ $plugin ] = $plugins[ $cat ]['plugins'][ $plugin ]; + $plugins[ $cat ]['plugins'][ $plugin ] = $active_plugin; // Remove category with active plugin from current array. + $active_cat = $plugins[ $cat ]; unset( $plugins[ $cat ] ); // Send category with active plugins to the end of array. - $plugins[ $cat ] = $cat_data; + $plugins[ $cat ] = $active_cat; continue; } From 3de5d91ff958d50a59d437284844d1e5bb8f9529 Mon Sep 17 00:00:00 2001 From: Michael Lee Date: Fri, 25 Oct 2024 11:46:36 +0100 Subject: [PATCH 44/49] Updated test --- .../filterPluginsByActivation.php | 79 +++++++++++++++++++ 1 file changed, 79 insertions(+) diff --git a/tests/Fixtures/src/Model/PluginFamily/filterPluginsByActivation.php b/tests/Fixtures/src/Model/PluginFamily/filterPluginsByActivation.php index f37df58..6653a2b 100644 --- a/tests/Fixtures/src/Model/PluginFamily/filterPluginsByActivation.php +++ b/tests/Fixtures/src/Model/PluginFamily/filterPluginsByActivation.php @@ -298,6 +298,76 @@ ], ]; +$expectedWithSecondOrLastPluginActiveInCategory = [ + 'optimize_performance' => [ + 'title' => 'Optimize Performance', + 'plugins' => [ + 'imagify-plugin/imagify' => [ + 'logo' => [ + 'file' => 'logo-imagify.svg', + 'width' => '50%', + ], + 'title' => 'Speed Up Your Website With Lighter Images', + 'desc' => 'Imagify is the easiest WordPress image optimizer. It automatically compresses images, converts them to WebP and AVIF formats, and lets you resize and optimize with just one click!', + 'link' => 'https://imagify.io/', + 'cta' => [ + 'text' => 'Install', + 'url' => 'http://example.org/wp-admin/admin-post.php?action=install_imagify_from_partner_wp-rocket&_wpnonce=9a68f00b8d&_wp_http_referer=https%3A%2F%2Fexample.org%2Fwp-admin' + ], + ], + ], + ], + 'boost_traffic' => [ + 'title' => 'Boost Traffic', + 'plugins' => [ + 'seo-by-rank-math/rank-math' => [ + 'logo' => [ + 'file' => 'logo-rank-math.svg', + 'width' => '60%', + ], + 'title' => 'The Swiss Army Knife of SEO Tools', + 'desc' => 'Rank Math SEO is the Best WordPress SEO plugin with the features of many SEO and AI SEO tools in a single package to help multiply your SEO traffic.', + 'link' => 'https://rankmath.com/wordpress/plugin/seo-suite/', + 'cta' => [ + 'text' => 'Install', + 'url' => 'http://example.org/wp-admin/admin-post.php?action=plugin_family_install_seo-by-rank-math&_wpnonce=9a68f00b8d&plugin_to_install=seo-by-rank-math%2Frank-math' + ], + ], + ], + ], + 'protect_secure' => [ + 'title' => 'Protect & Secure', + 'plugins' => [ + 'backwpup/backwpup' => [ + 'logo' => [ + 'file' => 'logo-backwpup.svg', + 'width' => '60%', + ], + 'title' => 'The Easiest Way to Protect Your Website', + 'desc' => 'BackWPup is the most comprehensive and user-friendly backup & restore plugin for WordPress. Easily schedule automatic backups, securely store and restore with just a few clicks!', + 'link' => 'https://backwpup.com/', + 'cta' => [ + 'text' => 'Install', + 'url' => 'http://example.org/wp-admin/admin-post.php?action=plugin_family_install_backwpup&_wpnonce=9a68f00b8d&plugin_to_install=backwpup%2Fbackwpup' + ], + ], + 'uk-cookie-consent/uk-cookie-consent' => [ + 'logo' => [ + 'file' => 'logo-termly.svg', + 'width' => '50%', + ], + 'title' => 'GDPR/CCPA Cookie Consent Banner', + 'desc' => 'One of the easiest, most comprehensive, and popular cookie consent plugins available. Google Gold Certified Partner to quickly comply with data privacy laws from around the world.', + 'link' => 'https://termly.io/resources/articles/wordpress-cookies-guide/', + 'cta' => [ + 'text' => 'Activated', + 'url' => '#' + ], + ], + ], + ], +]; + return [ 'testShouldReturnEmptyArrayIfEmptyArrayParsed' => [ 'config' => [ @@ -344,4 +414,13 @@ ], 'expected' => $expectedUniqueInstallLinkForImagify, ], + 'testShouldReturnAsExpectedWithSecondOrLastPluginActiveInCategory' => [ + 'config' => [ + 'plugins' => $plugins, + 'main_plugin' => 'wp-rocket/wp-rocket', + 'order' => 'categorized', + 'active_plugin' => 'uk-cookie-consent/uk-cookie-consent.php', + ], + 'expected' => $expectedWithSecondOrLastPluginActiveInCategory, + ] ]; \ No newline at end of file From acb4ae0f8f56237136d1aced103381354fe0c039 Mon Sep 17 00:00:00 2001 From: Michael Lee Date: Fri, 25 Oct 2024 12:31:24 +0100 Subject: [PATCH 45/49] Keep optimize category at the top even when containing main plugin --- src/Model/PluginFamily.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Model/PluginFamily.php b/src/Model/PluginFamily.php index 785f4d2..dcf3073 100644 --- a/src/Model/PluginFamily.php +++ b/src/Model/PluginFamily.php @@ -60,7 +60,7 @@ public function filter_plugins_by_activation( array $plugins, string $main_plugi * to re-add them back using array_merge to be displayed after * plugins that are not installed or not activated. */ - if ( is_plugin_active( $plugin_path ) ) { + if ( is_plugin_active( $plugin_path ) && $main_plugin.'.php' !== $plugin_path ) { // set cta data of active plugins. $plugins[ $cat ]['plugins'][ $plugin ]['cta'] = [ 'text' => 'Activated', From dce70461447dc8d74488b2c7e30882ffd68823f4 Mon Sep 17 00:00:00 2001 From: Michael Lee Date: Fri, 25 Oct 2024 12:31:40 +0100 Subject: [PATCH 46/49] Added test --- .../filterPluginsByActivation.php | 79 +++++++++++++++++++ 1 file changed, 79 insertions(+) diff --git a/tests/Fixtures/src/Model/PluginFamily/filterPluginsByActivation.php b/tests/Fixtures/src/Model/PluginFamily/filterPluginsByActivation.php index 6653a2b..7da1070 100644 --- a/tests/Fixtures/src/Model/PluginFamily/filterPluginsByActivation.php +++ b/tests/Fixtures/src/Model/PluginFamily/filterPluginsByActivation.php @@ -368,6 +368,76 @@ ], ]; +$expectedOptimizeCategoryAsFirstWhenContainingMainPlugin = [ + 'optimize_performance' => [ + 'title' => 'Optimize Performance', + 'plugins' => [ + 'imagify-plugin/imagify' => [ + 'logo' => [ + 'file' => 'logo-imagify.svg', + 'width' => '50%', + ], + 'title' => 'Speed Up Your Website With Lighter Images', + 'desc' => 'Imagify is the easiest WordPress image optimizer. It automatically compresses images, converts them to WebP and AVIF formats, and lets you resize and optimize with just one click!', + 'link' => 'https://imagify.io/', + 'cta' => [ + 'text' => 'Install', + 'url' => 'http://example.org/wp-admin/admin-post.php?action=install_imagify_from_partner_wp-rocket&_wpnonce=9a68f00b8d&_wp_http_referer=https%3A%2F%2Fexample.org%2Fwp-admin' + ], + ], + ], + ], + 'boost_traffic' => [ + 'title' => 'Boost Traffic', + 'plugins' => [ + 'seo-by-rank-math/rank-math' => [ + 'logo' => [ + 'file' => 'logo-rank-math.svg', + 'width' => '60%', + ], + 'title' => 'The Swiss Army Knife of SEO Tools', + 'desc' => 'Rank Math SEO is the Best WordPress SEO plugin with the features of many SEO and AI SEO tools in a single package to help multiply your SEO traffic.', + 'link' => 'https://rankmath.com/wordpress/plugin/seo-suite/', + 'cta' => [ + 'text' => 'Install', + 'url' => 'http://example.org/wp-admin/admin-post.php?action=plugin_family_install_seo-by-rank-math&_wpnonce=9a68f00b8d&plugin_to_install=seo-by-rank-math%2Frank-math' + ], + ], + ], + ], + 'protect_secure' => [ + 'title' => 'Protect & Secure', + 'plugins' => [ + 'backwpup/backwpup' => [ + 'logo' => [ + 'file' => 'logo-backwpup.svg', + 'width' => '60%', + ], + 'title' => 'The Easiest Way to Protect Your Website', + 'desc' => 'BackWPup is the most comprehensive and user-friendly backup & restore plugin for WordPress. Easily schedule automatic backups, securely store and restore with just a few clicks!', + 'link' => 'https://backwpup.com/', + 'cta' => [ + 'text' => 'Install', + 'url' => 'http://example.org/wp-admin/admin-post.php?action=plugin_family_install_backwpup&_wpnonce=9a68f00b8d&plugin_to_install=backwpup%2Fbackwpup' + ], + ], + 'uk-cookie-consent/uk-cookie-consent' => [ + 'logo' => [ + 'file' => 'logo-termly.svg', + 'width' => '50%', + ], + 'title' => 'GDPR/CCPA Cookie Consent Banner', + 'desc' => 'One of the easiest, most comprehensive, and popular cookie consent plugins available. Google Gold Certified Partner to quickly comply with data privacy laws from around the world.', + 'link' => 'https://termly.io/resources/articles/wordpress-cookies-guide/', + 'cta' => [ + 'text' => 'Install', + 'url' => 'http://example.org/wp-admin/admin-post.php?action=plugin_family_install_uk-cookie-consent&_wpnonce=9a68f00b8d&plugin_to_install=uk-cookie-consent%2Fuk-cookie-consent' + ], + ], + ], + ], +]; + return [ 'testShouldReturnEmptyArrayIfEmptyArrayParsed' => [ 'config' => [ @@ -422,5 +492,14 @@ 'active_plugin' => 'uk-cookie-consent/uk-cookie-consent.php', ], 'expected' => $expectedWithSecondOrLastPluginActiveInCategory, + ], + 'testShouldStillReturnOptimizeCategoryAsFirstWhenContainingMainPlugin' => [ + 'config' => [ + 'plugins' => $plugins, + 'main_plugin' => 'wp-rocket/wp-rocket', + 'order' => 'categorized', + 'active_plugin' => 'wp-rocket/wp-rocket.php', + ], + 'expected' => $expectedOptimizeCategoryAsFirstWhenContainingMainPlugin, ] ]; \ No newline at end of file From 749d4ebd63bd397806c13fe7969e377951218797 Mon Sep 17 00:00:00 2001 From: Michael Lee Date: Fri, 25 Oct 2024 12:33:24 +0100 Subject: [PATCH 47/49] phpcs fix --- src/Model/PluginFamily.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Model/PluginFamily.php b/src/Model/PluginFamily.php index dcf3073..a567f4d 100644 --- a/src/Model/PluginFamily.php +++ b/src/Model/PluginFamily.php @@ -60,7 +60,7 @@ public function filter_plugins_by_activation( array $plugins, string $main_plugi * to re-add them back using array_merge to be displayed after * plugins that are not installed or not activated. */ - if ( is_plugin_active( $plugin_path ) && $main_plugin.'.php' !== $plugin_path ) { + if ( is_plugin_active( $plugin_path ) && $main_plugin . '.php' !== $plugin_path ) { // set cta data of active plugins. $plugins[ $cat ]['plugins'][ $plugin ]['cta'] = [ 'text' => 'Activated', From 8f58f0d201f9b5a02370c65ec0c5cb0797a1ef97 Mon Sep 17 00:00:00 2001 From: Michael Lee Date: Fri, 25 Oct 2024 12:44:48 +0100 Subject: [PATCH 48/49] Updated README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 3afd066..0fa3e28 100644 --- a/README.md +++ b/README.md @@ -25,7 +25,7 @@ class View { } public function display_page() { - $plugin_family = $this->plugin_family->get_filtered_plugins( 'imagify-plugin/imagify' ); + $plugin_family = $this->plugin_family->get_filtered_plugins( 'imagify/imagify' ); $data = [ 'plugin_family' => $plugin_family['uncategorized'], From 806d2dc94cc1655365e73d76b9a772c33889f62d Mon Sep 17 00:00:00 2001 From: Michael Lee Date: Fri, 25 Oct 2024 12:52:36 +0100 Subject: [PATCH 49/49] Updated tests --- .../src/Model/PluginFamily/filterPluginsByActivation.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/Fixtures/src/Model/PluginFamily/filterPluginsByActivation.php b/tests/Fixtures/src/Model/PluginFamily/filterPluginsByActivation.php index d0f3dda..0bf34af 100644 --- a/tests/Fixtures/src/Model/PluginFamily/filterPluginsByActivation.php +++ b/tests/Fixtures/src/Model/PluginFamily/filterPluginsByActivation.php @@ -302,7 +302,7 @@ 'optimize_performance' => [ 'title' => 'Optimize Performance', 'plugins' => [ - 'imagify-plugin/imagify' => [ + 'imagify/imagify' => [ 'logo' => [ 'file' => 'logo-imagify.svg', 'width' => '50%', @@ -372,7 +372,7 @@ 'optimize_performance' => [ 'title' => 'Optimize Performance', 'plugins' => [ - 'imagify-plugin/imagify' => [ + 'imagify/imagify' => [ 'logo' => [ 'file' => 'logo-imagify.svg', 'width' => '50%',