diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 2d2d987ece12ce7c2b9add7b54428497da9394b7..1c663e8d2923b68cec44a60013e068e3bbcbb43b 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -1,154 +1,8 @@ variables: - WPDESK_CI_VERSION: 1.10.19-library - MYSQL_ROOT_PASSWORD: mysql - MYSQL_DATABASE: wptest - MYSQL_USER: mysql - MYSQL_PASSWORD: mysql - MYSQL_INNODB_LOG_BUFFER_SIZE: 32M - PHP_ERROR_REPORTING: E_ALL - COMPOSER_ALLOW_SUPERUSER: 1 - GIT_STRATEGY: fetch - ACCEPTANCE_ERROR_PATH: ${CI_PROJECT_DIR}/acceptance + DISABLE_ACCEPTANCE: "1" + DISABLE_FUNCTIONAL: "1" + IS_LIBRARY: 1 + DISABLE_PHP_5_5: 1 + DISABLE_CODECEPTION: 1 -stages: - - tools - - tests - -.template: &job-test-template - stage: tests - coverage: '/^\s*Lines:\s*\d+.\d+\%/' - -.template: &job-test-integration-template - <<: *job-test-template - services: - - mysql:5.6 - script: - - echo ${WPDESK_CI_VERSION} - - ls -l - - php --version - - cat /tmp/wordpress-develop/src/wp-includes/version.php - - cat /tmp/woocommerce/woocommerce.php - - composer update --no-progress - - if [[ -f tests/integration/prepare.sh ]]; then sh tests/integration/prepare.sh; fi - - vendor/bin/phpunit --configuration phpunit-integration.xml --coverage-text --colors=never - only: - - tags - -.template: &job-test-integration-template-fast - <<: *job-test-integration-template - script: - - echo ${WPDESK_CI_VERSION} - - ls -l - - php --version - - cat /tmp/wordpress-develop/src/wp-includes/version.php - - cat /tmp/woocommerce/woocommerce.php - - composer update --no-progress - - if [[ -f tests/integration/prepare.sh ]]; then sh tests/integration/prepare.sh; fi - - vendor/bin/phpunit --configuration phpunit-integration.xml --no-coverage - except: - - tags - only: - -.template: &job-test-unit-template - <<: *job-test-template - script: - - echo ${WPDESK_CI_VERSION} - - ls -l - - php --version - - cat /tmp/wordpress-develop/src/wp-includes/version.php - - cat /tmp/woocommerce/woocommerce.php - - composer update --no-progress - - vendor/bin/phpunit --configuration phpunit-unit.xml --coverage-text --colors=never - only: - - tags - -.template: &job-test-unit-template-fast - <<: *job-test-unit-template - script: - - echo ${WPDESK_CI_VERSION} - - ls -l - - php --version - - cat /tmp/wordpress-develop/src/wp-includes/version.php - - cat /tmp/woocommerce/woocommerce.php - - composer update --no-progress - - vendor/bin/phpunit --configuration phpunit-unit.xml --no-coverage - except: - - tags - only: - -before_script: - - cd ${CI_PROJECT_DIR} - -phpmetric metrics: - stage: tools - image: wpdesknet/phpunit-woocommerce:0-0 - allow_failure: true - when: manual - artifacts: - when: always - expire_in: 1 month - name: "metrics" - paths: - - ${CI_PROJECT_DIR}/phpmetric - script: - - echo ${WPDESK_CI_VERSION} - - composer require phpmetrics/phpmetrics - - composer update --no-progress - - php ./vendor/bin/phpmetrics --report-html=phpmetric . - -churn metrics: - stage: tools - image: wpdesknet/phpunit-woocommerce:0-0 - allow_failure: true - when: manual - script: - - echo ${WPDESK_CI_VERSION} - - composer require bmitch/churn-php - - composer update --no-progress - - vendor/bin/churn run src - -unit test lastest: - <<: *job-test-unit-template-fast - image: wpdesknet/phpunit-woocommerce:0-0 - -integration test lastest: - <<: *job-test-integration-template-fast - image: wpdesknet/phpunit-woocommerce:0-0 - -unit test lastest coverage: - <<: *job-test-unit-template - image: wpdesknet/phpunit-woocommerce:0-0 - -integration test lastest coverage: - <<: *job-test-integration-template - image: wpdesknet/phpunit-woocommerce:0-0 - -integration test php7-1 wc-1: - <<: *job-test-integration-template-fast - image: wpdesknet/phpunit-woocommerce:1-1 - -integration test php7 wc-2: - <<: *job-test-integration-template-fast - image: wpdesknet/phpunit-woocommerce:2-2 - -integration test php-7 wc-3: - <<: *job-test-integration-template-fast - image: wpdesknet/phpunit-woocommerce:2-3 - -integration test php5-6: - <<: *job-test-integration-template-fast - image: wpdesknet/phpunit-woocommerce:3-0 - -integration test php5-5: - <<: *job-test-integration-template-fast - image: wpdesknet/phpunit-woocommerce:4-0 - -integration test current woocommerce: - <<: *job-test-integration-template-fast - image: wpdesknet/phpunit-woocommerce:0-0 - allow_failure: true - before_script: - - cd /tmp - - rm -rf woocommerce - - git clone https://github.com/woocommerce/woocommerce.git - - cd ${CI_PROJECT_DIR} +include: 'https://gitlab.com/wpdesk/gitlab-ci/raw/master/gitlab-ci-1.2.yml' diff --git a/CHANGELOG.md b/CHANGELOG.md index 31863922e28691f3d6e9b2a3752a164ed652cc2d..5af358ae90081d473aab6d5e2976581421bb02a4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,7 +1,9 @@ -## [3.5.2] - 2023-02-10 - +## [3.6.0] - 2023-06-22 ### Changed +- Plugin info transient changed to auto loaded option (expiration 0) +## [3.5.2] - 2023-02-10 +### Changed - Removed arrows from user-facing messages. ## [3.5.1] - 2022-08-30 diff --git a/src/Basic_Requirement_Checker.php b/src/Basic_Requirement_Checker.php index e942fff8eb0b035898fe8b16a7cc20eabad5f70c..e96d7f4287d5dd3a1d7b3b9492e6668ae49ddce6 100644 --- a/src/Basic_Requirement_Checker.php +++ b/src/Basic_Requirement_Checker.php @@ -10,43 +10,70 @@ if ( ! class_exists( 'WPDesk_Basic_Requirement_Checker' ) ) { * have to be compatible with PHP 5.3.x */ class WPDesk_Basic_Requirement_Checker implements WPDesk_Requirement_Checker { + const EXTENSION_NAME_OPENSSL = 'openssl'; + const HOOK_ADMIN_NOTICES_ACTION = 'admin_notices'; + const HOOK_PLUGIN_DEACTIVATED_ACTION = 'deactivated_plugin'; + const HOOK_PLUGIN_ACTIVATED_ACTION = 'activated_plugin'; const PLUGIN_INFO_KEY_NICE_NAME = 'nice_name'; + const PLUGIN_INFO_KEY_NAME = 'name'; + const PLUGIN_INFO_VERSION = 'version'; + const PLUGIN_INFO_FAKE_REQUIRED_MINIMUM_VERSION = '0.0'; + const PLUGIN_INFO_APPEND_PLUGIN_DATA = 'required_version'; - const PLUGIN_INFO_TRANSIENT_NAME = 'require_plugins_data'; - const PLUGIN_INFO_TRANSIENT_EXPIRATION_TIME = 16; + + const PLUGIN_INFO_TRANSIENT_NAME = 'wpdesk_plugins_data'; + + const EXPIRATION_TRANSIENT_NAME = 'wpdesk_plugins_data_exp'; + + const CACHE_TIME = 300; /** @var string */ protected $plugin_name; + /** @var string */ private $plugin_file; + /** @var string */ private $min_php_version; + /** @var string */ private $min_wp_version; + /** @var string|null */ private $min_wc_version = null; + /** @var int|null */ private $min_openssl_version = null; + /** @var array */ protected $plugin_require; + /** @var bool */ protected $should_check_plugin_versions = false; + /** @var array */ private $module_require; + /** @var array */ private $setting_require; + /** @var array */ protected $notices; + /** @var @string */ private $text_domain; + /** + * @var mixed|true + */ + private $use_transients; /** * @param string $plugin_file @@ -54,11 +81,13 @@ if ( ! class_exists( 'WPDesk_Basic_Requirement_Checker' ) ) { * @param string $text_domain * @param string $php_version * @param string $wp_version + * @param bool $use_transients */ - public function __construct( $plugin_file, $plugin_name, $text_domain, $php_version, $wp_version ) { - $this->plugin_file = $plugin_file; - $this->plugin_name = $plugin_name; - $this->text_domain = $text_domain; + public function __construct( $plugin_file, $plugin_name, $text_domain, $php_version, $wp_version, $use_transients = true ) { + $this->plugin_file = $plugin_file; + $this->plugin_name = $plugin_name; + $this->text_domain = $text_domain; + $this->use_transients = $use_transients; $this->set_min_php_require( $php_version ); $this->set_min_wp_require( $wp_version ); @@ -321,32 +350,47 @@ if ( ! class_exists( 'WPDesk_Basic_Requirement_Checker' ) ) { /** * Check the plugins directory and retrieve all plugin files with plugin data. * + * @param bool $use_transients + * * @return array In format [ 'plugindir/pluginfile.php' => ['Name' => 'Plugin Name', 'Version' => '1.0.1', ...], ] */ - private static function retrieve_plugins_data_in_transient() { - static $never_executed = true; - if ( $never_executed ) { - $never_executed = false; - /** Required when WC starts later and these data should be in cache */ - add_filter( 'extra_plugin_headers', function ( $headers = array() ) { - $headers[] = 'WC tested up to'; - $headers[] = 'WC requires at least'; - $headers[] = 'Woo'; - - return array_unique( $headers ); - } ); + private static function retrieve_plugins_data_in_transient( $use_transients = true ) { + $current_time = time(); + if ( $use_transients) { + $plugins = get_transient( self::PLUGIN_INFO_TRANSIENT_NAME ); + $expiration_time = get_transient( self::EXPIRATION_TRANSIENT_NAME ); + } else { + $plugins = get_option( self::PLUGIN_INFO_TRANSIENT_NAME ); + $expiration_time = get_option( self::EXPIRATION_TRANSIENT_NAME ); } + $is_expired = ! $expiration_time || $current_time > $expiration_time; + + if ( $plugins === false || $is_expired ) { + static $never_executed = true; + if ( $never_executed ) { + $never_executed = false; + /** Required when WC starts later and these data should be in cache */ + add_filter( 'extra_plugin_headers', function( $headers = array() ) { + $headers[] = 'WC tested up to'; + $headers[] = 'WC requires at least'; + $headers[] = 'Woo'; + + return array_unique( $headers ); + } ); + } - $plugins = get_transient( self::PLUGIN_INFO_TRANSIENT_NAME ); - - if ( $plugins === false ) { if ( ! function_exists( 'get_plugins' ) ) { require_once ABSPATH . '/wp-admin/includes/plugin.php'; } $plugins = function_exists( 'get_plugins' ) ? get_plugins() : array(); - set_transient( self::PLUGIN_INFO_TRANSIENT_NAME, $plugins, - self::PLUGIN_INFO_TRANSIENT_EXPIRATION_TIME ); + if ( $use_transients ) { + set_transient( self::PLUGIN_INFO_TRANSIENT_NAME, $plugins, 0 ); + set_transient( self::EXPIRATION_TRANSIENT_NAME, $current_time + self::CACHE_TIME, 0 ); + } else { + update_option( self::PLUGIN_INFO_TRANSIENT_NAME, $plugins ); + update_option( self::EXPIRATION_TRANSIENT_NAME, $current_time + self::CACHE_TIME ); + } } return $plugins; @@ -358,9 +402,8 @@ if ( ! class_exists( 'WPDesk_Basic_Requirement_Checker' ) ) { * @return array In format [ 'plugindir/pluginfile.php' => ['Name' => 'Plugin Name', 'Version' => '1.0.1', 'required_version' => '1.0.2']... ] */ private function retrieve_required_plugins_data() { - $require_plugins = array(); - $plugins = self::retrieve_plugins_data_in_transient(); + $plugins = self::retrieve_plugins_data_in_transient( $this->use_transients ); if ( is_array( $plugins ) ) { if ( count( $plugins ) > 0 ) { if ( ! empty( $this->plugin_require ) ) { @@ -420,7 +463,7 @@ if ( ! class_exists( 'WPDesk_Basic_Requirement_Checker' ) ) { if ( function_exists( 'wp_nonce_url' ) && function_exists( 'wp_create_nonce' ) ) { $install_url = wp_nonce_url( $install_url, 'install-plugin_' . $slug ); } - add_filter( 'plugins_api', function ( $api, $action, $args ) use ( $plugin_info, $slug ) { + add_filter( 'plugins_api', function( $api, $action, $args ) use ( $plugin_info, $slug ) { if ( 'plugin_information' !== $action || false !== $api || ! isset( $args->slug ) || @@ -450,7 +493,7 @@ if ( ! class_exists( 'WPDesk_Basic_Requirement_Checker' ) ) { $nice_name = $plugin_info[ self::PLUGIN_INFO_KEY_NICE_NAME ]; if ( ! self::is_wp_plugin_active( $name ) ) { - if ( ! self::is_wp_plugin_installed( $name ) ) { + if ( ! self::is_wp_plugin_installed( $name, $this->use_transients ) ) { $install_url = $this->prepare_plugin_repository_install_url( $plugin_info ); return $this->prepare_notice_message( sprintf( wp_kses( __( 'The “%s” plugin requires free %s plugin. <a href="%s">Install %s</a>', @@ -491,11 +534,12 @@ if ( ! class_exists( 'WPDesk_Basic_Requirement_Checker' ) ) { * Checks if plugin is installed. Needs to be enabled in deferred way. * * @param string $plugin_file + * @param bool $use_transients * * @return bool */ - public static function is_wp_plugin_installed( $plugin_file ) { - $plugins_data = self::retrieve_plugins_data_in_transient(); + public static function is_wp_plugin_installed( $plugin_file, $use_transients = false ) { + $plugins_data = self::retrieve_plugins_data_in_transient( $use_transients ); return array_key_exists( $plugin_file, (array) $plugins_data ); } @@ -564,7 +608,10 @@ if ( ! class_exists( 'WPDesk_Basic_Requirement_Checker' ) ) { * @deprecated use render_notices or disable_plugin */ public function disable_plugin_render_notice() { - add_action( self::HOOK_ADMIN_NOTICES_ACTION, array( $this, 'handle_render_notices_action' ) ); + add_action( self::HOOK_ADMIN_NOTICES_ACTION, array( + $this, + 'handle_render_notices_action' + ) ); } /** @@ -573,7 +620,10 @@ if ( ! class_exists( 'WPDesk_Basic_Requirement_Checker' ) ) { * @return void */ public function render_notices() { - add_action( self::HOOK_ADMIN_NOTICES_ACTION, array( $this, 'handle_render_notices_action' ) ); + add_action( self::HOOK_ADMIN_NOTICES_ACTION, array( + $this, + 'handle_render_notices_action' + ) ); } /** @@ -582,7 +632,10 @@ if ( ! class_exists( 'WPDesk_Basic_Requirement_Checker' ) ) { * @return void */ public function disable_plugin() { - add_action( self::HOOK_ADMIN_NOTICES_ACTION, array( $this, 'handle_deactivate_action' ) ); + add_action( self::HOOK_ADMIN_NOTICES_ACTION, array( + $this, + 'handle_deactivate_action' + ) ); } /** @@ -594,7 +647,7 @@ if ( ! class_exists( 'WPDesk_Basic_Requirement_Checker' ) ) { if ( isset( $this->plugin_file ) ) { deactivate_plugins( plugin_basename( $this->plugin_file ) ); - delete_transient( self::PLUGIN_INFO_TRANSIENT_NAME ); + $this->clear_plugin_info_data(); } } @@ -604,8 +657,14 @@ if ( ! class_exists( 'WPDesk_Basic_Requirement_Checker' ) ) { * @return void */ public function transient_delete_on_plugin_version_changed() { - add_action( self::HOOK_PLUGIN_DEACTIVATED_ACTION, array( $this, 'handle_transient_delete_action' ) ); - add_action( self::HOOK_PLUGIN_ACTIVATED_ACTION, array( $this, 'handle_transient_delete_action' ) ); + add_action( self::HOOK_PLUGIN_DEACTIVATED_ACTION, array( + $this, + 'clear_plugin_info_data' + ) ); + add_action( self::HOOK_PLUGIN_ACTIVATED_ACTION, array( + $this, + 'clear_plugin_info_data' + ) ); } /** @@ -613,8 +672,11 @@ if ( ! class_exists( 'WPDesk_Basic_Requirement_Checker' ) ) { * * @return void */ - public function handle_transient_delete_action() { + public function clear_plugin_info_data() { delete_transient( self::PLUGIN_INFO_TRANSIENT_NAME ); + delete_transient( self::EXPIRATION_TRANSIENT_NAME ); + delete_option( self::PLUGIN_INFO_TRANSIENT_NAME ); + delete_option( self::EXPIRATION_TRANSIENT_NAME ); } /** @@ -629,5 +691,6 @@ if ( ! class_exists( 'WPDesk_Basic_Requirement_Checker' ) ) { echo $notice; } } + } } diff --git a/src/Basic_Requirement_Checker_Factory.php b/src/Basic_Requirement_Checker_Factory.php index e0755db9fcc679afbfb714602a56bccf2f451550..b79906028336143f1c3c9d52483d5f2be1d02faf 100644 --- a/src/Basic_Requirement_Checker_Factory.php +++ b/src/Basic_Requirement_Checker_Factory.php @@ -44,7 +44,8 @@ $plugin_name, $text_domain, $requirements['php'], - $requirements['wp'] + $requirements['wp'], + (bool) wp_using_ext_object_cache() ); if ( isset( $requirements['plugins'] ) ) { diff --git a/tests/unit/Test_Basic_Requirement_Checker_Factory.php b/tests/unit/Test_Basic_Requirement_Checker_Factory.php index d7f6183ca953a20be1b400136b9e5df7025da4d9..24418e8cfbfd7d3f37ab03361b28a3f295c39763 100644 --- a/tests/unit/Test_Basic_Requirement_Checker_Factory.php +++ b/tests/unit/Test_Basic_Requirement_Checker_Factory.php @@ -25,7 +25,9 @@ WP_Mock::wpFunction( 'get_locale' ) ->andReturn( $existing_locale ); - + + WP_Mock::wpFunction( 'wp_using_ext_object_cache')->andReturn( true ); + $factory = new WPDesk_Basic_Requirement_Checker_Factory(); $checker = $factory->create_from_requirement_array( 'whatever', 'whatever', $requirements ); @@ -41,7 +43,7 @@ WP_Mock::passthruFunction( 'wp_nonce_url' ); WP_Mock::passthruFunction( 'wp_create_nonce' ); WP_Mock::passthruFunction( 'admin_url' ); - + $this->assertFalse( $checker->are_requirements_met(), '2 plugins required and there should be none activated' ); $this->expectOutputRegex( '/Flexible Checkout Fields/' );