'] ) ) {
$latest_wc_versions = [];
// Reverse the array as WordPress supplies oldest version first, newest last.
foreach ( array_keys( array_reverse( $plugin_info['versions'] ) ) as $wc_version ) {
// Skip trunk, release candidates, betas and other non-final or irregular versions.
if (
is_string( $wc_version )
&& '' !== $wc_version
&& is_numeric( $wc_version[0] )
&& false === strpos( $wc_version, '-' )
) {
$latest_wc_versions[] = $wc_version;
}
}
set_transient( 'compat_checker_wc_versions', $latest_wc_versions, WEEK_IN_SECONDS );
}
}
}
return is_array( $latest_wc_versions ) ? $latest_wc_versions : [];
}
/**
* Get the L-n version of WooCommerce.
*
* @return string
*/
private function get_supported_wc_version() {
$latest_wc_versions = $this->get_latest_wc_versions();
if ( empty( $latest_wc_versions ) ) {
return '';
}
$latest_wc_version = current( $latest_wc_versions );
$supported_wc_version = $latest_wc_version;
$latest_semver = explode( '.', $latest_wc_version );
$supported_semver = explode( '.', (string) $this->min_wc_semver );
$supported_major = max( 0, (int) $latest_semver[0] - (int) $supported_semver[0] );
$supported_minor = isset( $supported_semver[1] ) ? (int) $supported_semver[1] : 0;
$previous_minor = null;
// Loop known WooCommerce versions from the most recent until we get the oldest supported one.
foreach ( $latest_wc_versions as $older_wc_version ) {
// As we loop through the versions, the latest one before we break the loop will be the minimum supported version.
$supported_wc_version = $older_wc_version;
$older_semver = explode( '.', $older_wc_version );
$older_major = (int) $older_semver[0];
$older_minor = isset( $older_semver[1] ) ? (int) $older_semver[1] : 0;
// if major is ignored, skip; if the minor hasn't changed (patch must be), skip.
if ( $older_major > $supported_major || $older_minor === $previous_minor ) {
continue;
}
// We reached the maximum number of supported minor versions.
if ( $supported_minor <= 0 ) {
break;
}
// Store the previous minor while we loop patch versions, which we ignore.
$previous_minor = $older_minor;
--$supported_minor;
}
return $supported_wc_version;
}
/**
* Check for WooCommerce upgrade recommendation.
*
* @return bool
*/
private function check_wc_upgrade_recommendation() {
// Bail on frontend requests or if there is no definied versions to compare.
if ( ! is_admin() || empty( $this->min_wc_semver ) || ! is_numeric( $this->min_wc_semver ) ) {
return;
}
$current_wc_version = $this->get_wc_version();
$supported_wc_version = $this->get_supported_wc_version();
if ( ! $this->compare_major_version( $current_wc_version, $supported_wc_version, '>=' ) ) {
add_action( 'admin_notices', [ $this, 'make_upgrade_recommendation' ] );
}
return true;
}
/**
* Add notices for WooCommerce not being installed or activated.
*/
public function wc_fail_load() {
$plugin_name = $this->plugin_data['Name'];
if ( $this->is_wc_installed() ) {
if ( ! current_user_can( 'activate_plugins' ) ) {
return;
}
$activation_url = wp_nonce_url( 'plugins.php?action=activate&plugin=' . self::WC_PLUGIN_FILE . '&plugin_status=all&paged=1&s', 'activate-plugin_' . self::WC_PLUGIN_FILE );
$message = sprintf(
/* translators: %1$s - Plugin Name, %2$s - activate WooCommerce link open, %3$s - activate WooCommerce link close. */
esc_html__( '%1$s requires WooCommerce to be activated. Please %2$sactivate WooCommerce%3$s.', 'woogrow-compat-checker' ),
'' . $plugin_name . '',
'',
''
);
$this->add_admin_notice(
'woocommerce-not-activated',
'error',
$message
);
} else {
if ( ! current_user_can( 'install_plugins' ) ) {
return;
}
$install_url = wp_nonce_url( self_admin_url( 'update.php?action=install-plugin&plugin=woocommerce' ), 'install-plugin_woocommerce' );
$message = sprintf(
/* translators: %1$s - Plugin Name, %2$s - install WooCommerce link open, %3$s - install WooCommerce link close. */
esc_html__( '%1$s requires WooCommerce to be installed and activated. Please %2$sinstall WooCommerce%3$s.', 'woogrow-compat-checker' ),
'' . $plugin_name . '',
'',
''
);
$this->add_admin_notice(
'woocommerce-not-installed',
'error',
$message
);
}
}
/**
* Add notices for out of date WooCommerce.
*/
public function wc_out_of_date() {
if ( ! current_user_can( 'update_plugins' ) ) {
return;
}
$plugin_name = $this->plugin_data['Name'];
$wc_version_required = ( 1 === substr_count( $this->plugin_data['RequiresWC'], '.' ) ) ? $this->plugin_data['RequiresWC'] . '.0' : $this->plugin_data['RequiresWC']; // Pad .0 if the min required WC version is not in semvar format.
$message = sprintf(
/* translators: %1$s - Plugin Name, %2$s - minimum WooCommerce version, %3$s - update WooCommerce link open, %4$s - update WooCommerce link close, %5$s - download minimum WooCommerce link open, %6$s - download minimum WooCommerce link close. */
esc_html__( '%1$s requires WooCommerce version %2$s or higher. Please %3$supdate WooCommerce%4$s to the latest version, or %5$sdownload the minimum required version »%6$s', 'woogrow-compat-checker' ),
'' . $plugin_name . '',
$wc_version_required,
'',
'',
'',
''
);
$this->add_admin_notice(
'woocommerce-out-of-date',
'error',
$message
);
}
/**
* Adds notice for untested WooCommerce.
*/
public function wc_untested() {
$plugin_name = $this->plugin_data['Name'];
$wc_version = $this->get_wc_version();
$plugin_version = $this->plugin_data['Version'];
$message = sprintf(
/* translators: %1$s - Plugin Name, %2$s - Plugin version, %3$s - WooCommerce version number */
esc_html__( '%1$s - version %2$s is untested with WooCommerce %3$s.', 'woogrow-compat-checker' ),
'' . $plugin_name . '',
$plugin_version,
$wc_version
);
$this->add_admin_notice(
'woocommerce-untested',
'warning is-dismissible',
$message
);
}
/**
* Adds notice for WooCommerce upgrade recommendation.
*/
public function make_upgrade_recommendation() {
// Bail if the user does not have the update plugins capability.
if ( ! current_user_can( 'update_plugins' ) ) {
return;
}
$plugin_name = $this->plugin_data['Name'];
$current_wc_version = $this->get_wc_version();
$message = sprintf(
/* translators: Placeholders: %1$s - plugin name, %2$s - WooCommerce version number, %3$s - opening HTML link tag, %4$s - closing HTML link tag */
esc_html__( 'Heads up! %1$s will soon discontinue support for WooCommerce %2$s. Please %3$supdate WooCommerce%4$s to take advantage of the latest updates and features.', 'woogrow-compat-checker' ),
'' . $plugin_name . '',
$current_wc_version,
'',
''
);
$this->add_admin_notice(
'woocommerce-upgrade-recommendation',
'warning is-dismissible',
$message
);
}
/**
* Run all compatibility checks.
*/
protected function run_checks() {
try {
$this->check_wc_installation_and_activation();
$this->check_wc_version();
$this->check_wc_upgrade_recommendation();
return true;
} catch ( IncompatibleException $e ) {
return false;
}
}
}