first commit
This commit is contained in:
@@ -0,0 +1,98 @@
|
||||
<?php
|
||||
|
||||
class WPML_Cache_Directory {
|
||||
|
||||
const DIR_PERMISSIONS = 0775;
|
||||
const MAIN_DIRECTORY_NAME = 'wpml';
|
||||
const NOTICE_GROUP = 'wpml-cache-directory';
|
||||
const NOTICE_INVALID_CACHE = 'invalid-cache';
|
||||
private $cache_disabled = false;
|
||||
|
||||
/**
|
||||
* @var WPML_WP_API
|
||||
*/
|
||||
private $wp_api;
|
||||
|
||||
/**
|
||||
* @var WP_Filesystem_Direct
|
||||
*/
|
||||
private $filesystem;
|
||||
|
||||
/**
|
||||
* WPML_Cache_Directory constructor.
|
||||
*
|
||||
* @param WPML_WP_API $wp_api
|
||||
*/
|
||||
public function __construct( WPML_WP_API $wp_api ) {
|
||||
$this->wp_api = $wp_api;
|
||||
$this->filesystem = $wp_api->get_wp_filesystem_direct();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
private function get_main_directory_path() {
|
||||
$main_directory_path = null;
|
||||
$cache_path_root = $this->wp_api->constant( 'WPML_CACHE_PATH_ROOT' );
|
||||
|
||||
if ( $cache_path_root ) {
|
||||
$main_directory_path = trailingslashit( $cache_path_root ) . self::MAIN_DIRECTORY_NAME;
|
||||
return trailingslashit( $main_directory_path );
|
||||
}else {
|
||||
$upload_dir = wp_upload_dir();
|
||||
|
||||
if ( empty( $upload_dir['error'] ) ) {
|
||||
$base_dir = $upload_dir['basedir'];
|
||||
$main_directory_path = trailingslashit( $base_dir ) . 'cache/' . self::MAIN_DIRECTORY_NAME;
|
||||
return trailingslashit( $main_directory_path );
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* The function `wp_mkdir_p` will create directories recursively
|
||||
*
|
||||
* @param string $absolute_path
|
||||
*
|
||||
* @return string|bool absolute path or false if we can't have a writable and readable directory
|
||||
*/
|
||||
private function maybe_create_directory( $absolute_path ) {
|
||||
$result = true;
|
||||
|
||||
if ( ! $this->filesystem->is_dir( $absolute_path ) ) {
|
||||
$result = wp_mkdir_p( $absolute_path );
|
||||
}
|
||||
|
||||
return $result ? $absolute_path : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $relative_path
|
||||
*
|
||||
* @return string|bool absolute path or false if we can't have a writable and readable directory
|
||||
*/
|
||||
public function get( $relative_path = '' ) {
|
||||
$absolute_path = false;
|
||||
$main_directory_path = $this->maybe_create_directory( $this->get_main_directory_path() );
|
||||
|
||||
if ( $main_directory_path ) {
|
||||
$absolute_path = trailingslashit( $main_directory_path . ltrim( $relative_path, '/\\' ) );
|
||||
$absolute_path = $this->maybe_create_directory( $absolute_path );
|
||||
}
|
||||
|
||||
return $absolute_path;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $relative_path
|
||||
*/
|
||||
public function remove( $relative_path = '' ) {
|
||||
$main_directory_path = $this->get_main_directory_path();
|
||||
if ( $main_directory_path ) {
|
||||
$absolute_path = trailingslashit( $main_directory_path . ltrim( $relative_path, '/\\' ) );
|
||||
$this->filesystem->delete( $absolute_path, true );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
|
||||
class WPML_Core_Version_Check {
|
||||
|
||||
public static function is_ok( $package_file_path ) {
|
||||
|
||||
$is_ok = false;
|
||||
|
||||
/** @var array $bundle */
|
||||
$bundle = json_decode( file_get_contents( $package_file_path ), true );
|
||||
if ( defined( 'ICL_SITEPRESS_VERSION' ) && is_array( $bundle ) ) {
|
||||
$core_version_stripped = ICL_SITEPRESS_VERSION;
|
||||
$dev_or_beta_pos = strpos( ICL_SITEPRESS_VERSION, '-' );
|
||||
if ( $dev_or_beta_pos > 0 ) {
|
||||
$core_version_stripped = substr( ICL_SITEPRESS_VERSION, 0, $dev_or_beta_pos );
|
||||
}
|
||||
if ( version_compare( $core_version_stripped, $bundle['sitepress-multilingual-cms'], '>=' ) ) {
|
||||
$is_ok = true;
|
||||
}
|
||||
}
|
||||
|
||||
return $is_ok;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,357 @@
|
||||
<?php
|
||||
/*
|
||||
Module Name: WPML Dependency Check Module
|
||||
Description: This is not a plugin! This module must be included in other plugins (WPML and add-ons) to handle compatibility checks
|
||||
Author: OnTheGoSystems
|
||||
Author URI: http://www.onthegosystems.com/
|
||||
Version: 2.1
|
||||
*/
|
||||
|
||||
/** @noinspection PhpUndefinedClassInspection */
|
||||
class WPML_Dependencies {
|
||||
protected static $instance;
|
||||
private $admin_notice;
|
||||
private $current_product;
|
||||
private $current_version = array();
|
||||
private $expected_versions = array();
|
||||
private $installed_plugins = array();
|
||||
private $invalid_plugins = array();
|
||||
private $valid_plugins = array();
|
||||
private $validation_results = array();
|
||||
|
||||
public $data_key = 'wpml_dependencies:';
|
||||
public $needs_validation_key = 'wpml_dependencies:needs_validation';
|
||||
|
||||
private function __construct() {
|
||||
if ( null === self::$instance ) {
|
||||
$this->remove_old_admin_notices();
|
||||
$this->init_hooks();
|
||||
}
|
||||
}
|
||||
|
||||
private function collect_data() {
|
||||
$active_plugins = wp_get_active_and_valid_plugins();
|
||||
$this->init_bundle( $active_plugins );
|
||||
foreach ( $active_plugins as $plugin ) {
|
||||
$this->add_installed_plugin( $plugin );
|
||||
}
|
||||
}
|
||||
|
||||
protected function remove_old_admin_notices() {
|
||||
if ( class_exists( 'WPML_Bundle_Check' ) ) {
|
||||
global $WPML_Bundle_Check;
|
||||
|
||||
remove_action( 'admin_notices', array( $WPML_Bundle_Check, 'admin_notices_action' ) );
|
||||
}
|
||||
}
|
||||
|
||||
private function init_hooks() {
|
||||
add_action( 'init', array( $this, 'init_plugins_action' ) );
|
||||
add_action( 'extra_plugin_headers', array( $this, 'extra_plugin_headers_action' ) );
|
||||
add_action( 'admin_notices', array( $this, 'admin_notices_action' ) );
|
||||
add_action( 'activated_plugin', array( $this, 'activated_plugin_action' ) );
|
||||
add_action( 'deactivated_plugin', array( $this, 'deactivated_plugin_action' ) );
|
||||
add_action( 'upgrader_process_complete', array( $this, 'upgrader_process_complete_action' ), 10, 2 );
|
||||
add_action( 'load-plugins.php', array( $this, 'run_validation_on_plugins_page' ) );
|
||||
}
|
||||
|
||||
public function run_validation_on_plugins_page() {
|
||||
$this->reset_validation();
|
||||
}
|
||||
|
||||
public function activated_plugin_action() {
|
||||
$this->reset_validation();
|
||||
}
|
||||
|
||||
public function deactivated_plugin_action() {
|
||||
$this->reset_validation();
|
||||
}
|
||||
|
||||
public function upgrader_process_complete_action( $upgrader_object, $options ) {
|
||||
if ( 'update' === $options['action'] && 'plugin' === $options['type'] ) {
|
||||
$this->reset_validation();
|
||||
}
|
||||
}
|
||||
|
||||
private function reset_validation() {
|
||||
update_option( $this->needs_validation_key, true );
|
||||
$this->validate_plugins();
|
||||
}
|
||||
|
||||
private function flag_as_validated() {
|
||||
update_option( $this->needs_validation_key, false );
|
||||
}
|
||||
|
||||
private function needs_validation() {
|
||||
return get_option( $this->needs_validation_key );
|
||||
}
|
||||
|
||||
public function admin_notices_action() {
|
||||
$this->maybe_init_admin_notice();
|
||||
if ( $this->admin_notice && ( is_admin() && ! $this->is_doing_ajax_cron_or_xmlrpc() ) ) {
|
||||
echo $this->admin_notice;
|
||||
}
|
||||
}
|
||||
|
||||
private function is_doing_ajax_cron_or_xmlrpc() {
|
||||
return ( $this->is_doing_ajax() || $this->is_doing_cron() || $this->is_doing_xmlrpc() );
|
||||
}
|
||||
|
||||
private function is_doing_ajax() {
|
||||
return ( defined( 'DOING_AJAX' ) && DOING_AJAX );
|
||||
}
|
||||
|
||||
private function is_doing_cron() {
|
||||
return ( defined( 'DOING_CRON' ) && DOING_CRON );
|
||||
}
|
||||
|
||||
private function is_doing_xmlrpc() {
|
||||
return ( defined( 'XMLRPC_REQUEST' ) && XMLRPC_REQUEST );
|
||||
}
|
||||
|
||||
public function extra_plugin_headers_action( array $extra_headers = array() ) {
|
||||
$new_extra_header = array(
|
||||
'PluginSlug' => 'Plugin Slug',
|
||||
);
|
||||
|
||||
return array_merge( $new_extra_header, (array) $extra_headers );
|
||||
}
|
||||
|
||||
/**
|
||||
* @return WPML_Dependencies
|
||||
*/
|
||||
public static function get_instance() {
|
||||
if ( null === self::$instance ) {
|
||||
self::$instance = new WPML_Dependencies();
|
||||
}
|
||||
|
||||
return self::$instance;
|
||||
}
|
||||
|
||||
public function get_plugins() {
|
||||
return $this->installed_plugins;
|
||||
}
|
||||
|
||||
public function init_plugins_action() {
|
||||
if ( $this->needs_validation() && is_admin() && ! $this->is_doing_ajax_cron_or_xmlrpc() ) {
|
||||
$this->init_plugins();
|
||||
$this->validate_plugins();
|
||||
$this->flag_as_validated();
|
||||
}
|
||||
}
|
||||
|
||||
private function init_plugins() {
|
||||
if ( ! $this->installed_plugins ) {
|
||||
if ( ! function_exists( 'get_plugin_data' ) ) {
|
||||
/** @noinspection PhpIncludeInspection */
|
||||
include_once ABSPATH . '/wp-admin/includes/plugin.php';
|
||||
}
|
||||
if ( function_exists( 'get_plugin_data' ) ) {
|
||||
$this->collect_data();
|
||||
}
|
||||
}
|
||||
update_option( $this->data_key . 'installed_plugins', $this->installed_plugins );
|
||||
}
|
||||
|
||||
private function init_bundle( array $active_plugins ) {
|
||||
|
||||
foreach ( $active_plugins as $plugin_file ) {
|
||||
$filename = dirname( $plugin_file ) . '/wpml-dependencies.json';
|
||||
if ( file_exists( $filename ) ) {
|
||||
$data = file_get_contents( $filename );
|
||||
$bundle = json_decode( $data, true );
|
||||
$this->set_expected_versions( $bundle );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function add_installed_plugin( $plugin ) {
|
||||
$data = get_plugin_data( $plugin );
|
||||
$plugin_dir = realpath( dirname( $plugin ) );
|
||||
|
||||
$wp_plugin_dir = realpath( WP_PLUGIN_DIR ) . DIRECTORY_SEPARATOR;
|
||||
if ( false !== $plugin_dir && $wp_plugin_dir !== $plugin_dir ) {
|
||||
$plugin_folder = str_replace( $wp_plugin_dir, '', $plugin_dir );
|
||||
$plugin_slug = $this->guess_plugin_slug( $data, $plugin_folder );
|
||||
|
||||
if ( $this->is_valid_plugin( $plugin_slug ) ) {
|
||||
$this->installed_plugins[ $plugin_slug ] = $data['Version'];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function set_expected_versions( array $bundle ) {
|
||||
foreach ( $bundle as $plugin => $version ) {
|
||||
if ( ! array_key_exists( $plugin, $this->expected_versions ) ) {
|
||||
$this->expected_versions[ $plugin ] = $version;
|
||||
} else {
|
||||
if ( version_compare( $this->expected_versions[ $plugin ], $version, '<' ) ) {
|
||||
$this->expected_versions[ $plugin ] = $version;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function guess_plugin_slug( $plugin_data, $plugin_folder ) {
|
||||
$plugin_slug = null;
|
||||
$plugin_slug = $plugin_folder;
|
||||
if ( array_key_exists( 'Plugin Slug', $plugin_data ) && $plugin_data['Plugin Slug'] ) {
|
||||
$plugin_slug = $plugin_data['Plugin Slug'];
|
||||
}
|
||||
|
||||
return $plugin_slug;
|
||||
}
|
||||
|
||||
private function validate_plugins() {
|
||||
$validation_results = $this->get_plugins_validation();
|
||||
|
||||
$this->valid_plugins = array();
|
||||
$this->invalid_plugins = array();
|
||||
foreach ( $validation_results as $plugin => $validation_result ) {
|
||||
if ( true === $validation_result ) {
|
||||
$this->valid_plugins[] = $plugin;
|
||||
} else {
|
||||
$this->invalid_plugins[] = $plugin;
|
||||
}
|
||||
}
|
||||
|
||||
update_option( $this->data_key . 'valid_plugins', $this->valid_plugins );
|
||||
update_option( $this->data_key . 'invalid_plugins', $this->invalid_plugins );
|
||||
update_option( $this->data_key . 'expected_versions', $this->expected_versions );
|
||||
}
|
||||
|
||||
public function get_plugins_validation() {
|
||||
foreach ( $this->installed_plugins as $plugin => $version ) {
|
||||
$this->current_product = $plugin;
|
||||
if ( $this->is_valid_plugin() ) {
|
||||
$this->current_version = $version;
|
||||
$validation_result = $this->is_plugin_version_valid();
|
||||
$this->validation_results[ $plugin ] = $validation_result;
|
||||
}
|
||||
}
|
||||
|
||||
return $this->validation_results;
|
||||
}
|
||||
|
||||
private function is_valid_plugin( $product = false ) {
|
||||
$result = false;
|
||||
|
||||
if ( ! $product ) {
|
||||
$product = $this->current_product;
|
||||
}
|
||||
if ( $product ) {
|
||||
$versions = $this->get_expected_versions();
|
||||
$result = array_key_exists( $product, $versions );
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
public function is_plugin_version_valid() {
|
||||
$expected_version = $this->filter_version( $this->get_expected_product_version() );
|
||||
|
||||
return $expected_version ? version_compare( $this->filter_version( $this->current_version ), $expected_version, '>=' ) : null;
|
||||
}
|
||||
|
||||
private function filter_version( $version ) {
|
||||
return preg_replace( '#[^\d.].*#', '', $version );
|
||||
}
|
||||
|
||||
public function get_expected_versions() {
|
||||
return $this->expected_versions;
|
||||
}
|
||||
|
||||
private function get_expected_product_version( $product = false ) {
|
||||
$result = null;
|
||||
|
||||
if ( ! $product ) {
|
||||
$product = $this->current_product;
|
||||
}
|
||||
if ( $product ) {
|
||||
$versions = $this->get_expected_versions();
|
||||
|
||||
$result = isset( $versions[ $product ] ) ? $versions[ $product ] : null;
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
private function maybe_init_admin_notice() {
|
||||
$this->admin_notice = null;
|
||||
$this->installed_plugins = get_option( $this->data_key . 'installed_plugins', [] );
|
||||
$this->invalid_plugins = get_option( $this->data_key . 'invalid_plugins', [] );
|
||||
$this->expected_versions = get_option( $this->data_key . 'expected_versions', [] );
|
||||
$this->valid_plugins = get_option( $this->data_key . 'valid_plugins', [] );
|
||||
|
||||
if ( $this->has_invalid_plugins() ) {
|
||||
$notice_paragraphs = array();
|
||||
|
||||
$notice_paragraphs[] = $this->get_invalid_plugins_report_header();
|
||||
$notice_paragraphs[] = $this->get_invalid_plugins_report_list();
|
||||
$notice_paragraphs[] = $this->get_invalid_plugins_report_footer();
|
||||
|
||||
$this->admin_notice = '<div class="error wpml-admin-notice">';
|
||||
$this->admin_notice .= '<h3>' . __( 'WPML Update is Incomplete', 'sitepress' ) . '</h3>';
|
||||
$this->admin_notice .= '<p>' . implode( '</p><p>', $notice_paragraphs ) . '</p>';
|
||||
$this->admin_notice .= '</div>';
|
||||
}
|
||||
}
|
||||
|
||||
public function has_invalid_plugins() {
|
||||
return count( $this->invalid_plugins );
|
||||
}
|
||||
|
||||
private function get_invalid_plugins_report_header() {
|
||||
if ( $this->has_valid_plugins() ) {
|
||||
if ( count( $this->valid_plugins ) === 1 ) {
|
||||
$paragraph = __( 'You are running updated %s, but the following component is not updated:', 'sitepress' );
|
||||
$paragraph = sprintf( $paragraph, '<strong>' . $this->valid_plugins[0] . '</strong>' );
|
||||
} else {
|
||||
$paragraph = __( 'You are running updated %s and %s, but the following components are not updated:', 'sitepress' );
|
||||
$first_valid_plugins = implode( ', ', array_slice( $this->valid_plugins, 0, - 1 ) );
|
||||
$last_valid_plugin = array_slice( $this->valid_plugins, - 1 );
|
||||
$paragraph = sprintf( $paragraph, '<strong>' . $first_valid_plugins . '</strong>', '<strong>' . $last_valid_plugin[0] . '</strong>' );
|
||||
}
|
||||
} else {
|
||||
$paragraph = __( 'The following components are not updated:', 'sitepress' );
|
||||
}
|
||||
|
||||
return $paragraph;
|
||||
}
|
||||
|
||||
private function get_invalid_plugins_report_list() {
|
||||
/* translators: %s: Version number */
|
||||
$required_version = __( 'required version: %s', 'sitepress' );
|
||||
$invalid_plugins_list = '<ul class="ul-disc">';
|
||||
foreach ( $this->invalid_plugins as $invalid_plugin ) {
|
||||
$plugin_name_html = '<li data-installed-version="' . $this->installed_plugins[ $invalid_plugin ] . '">';
|
||||
$required_version_string = '';
|
||||
if ( isset( $this->expected_versions[ $invalid_plugin ] ) ) {
|
||||
$required_version_string = ' (' . sprintf( $required_version, $this->expected_versions[ $invalid_plugin ] ) . ')';
|
||||
}
|
||||
$plugin_name_html .= $invalid_plugin . $required_version_string;
|
||||
$plugin_name_html .= '</li>';
|
||||
|
||||
$invalid_plugins_list .= $plugin_name_html;
|
||||
}
|
||||
$invalid_plugins_list .= '</ul>';
|
||||
|
||||
return $invalid_plugins_list;
|
||||
}
|
||||
|
||||
private function get_invalid_plugins_report_footer() {
|
||||
$wpml_org_url = '<a href="https://wpml.org/account/" title="WPML.org account">' . __( 'WPML.org account', 'sitepress' ) . '</a>';
|
||||
|
||||
$notice_paragraph = __( 'Your site will not work as it should in this configuration', 'sitepress' );
|
||||
$notice_paragraph .= ' ';
|
||||
$notice_paragraph .= __( 'Please update all components which you are using.', 'sitepress' );
|
||||
$notice_paragraph .= ' ';
|
||||
$notice_paragraph .= sprintf( __( 'For WPML components you can receive updates from your %s or automatically, after you register WPML.', 'sitepress' ), $wpml_org_url );
|
||||
|
||||
return $notice_paragraph;
|
||||
}
|
||||
|
||||
private function has_valid_plugins() {
|
||||
return $this->valid_plugins && count( $this->valid_plugins );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,98 @@
|
||||
<?php
|
||||
/**
|
||||
* WPML_PHP_Version_Check class file.
|
||||
*
|
||||
* @package WPML\LibDependencies
|
||||
*/
|
||||
|
||||
if ( ! class_exists( 'WPML_PHP_Version_Check' ) ) {
|
||||
|
||||
/**
|
||||
* Class WPML_PHP_Version_Check
|
||||
*/
|
||||
class WPML_PHP_Version_Check {
|
||||
|
||||
/**
|
||||
* Required php version.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $required_php_version;
|
||||
|
||||
/**
|
||||
* Plugin name.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $plugin_name;
|
||||
|
||||
/**
|
||||
* Plugin file.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $plugin_file;
|
||||
|
||||
/**
|
||||
* Text domain.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $text_domain;
|
||||
|
||||
/**
|
||||
* WPML_PHP_Version_Check constructor.
|
||||
*
|
||||
* @param string $required_version Required php version.
|
||||
* @param string $plugin_name Plugin name.
|
||||
* @param string $plugin_file Plugin file.
|
||||
* @param string $text_domain Text domain.
|
||||
*/
|
||||
public function __construct( $required_version, $plugin_name, $plugin_file, $text_domain ) {
|
||||
$this->required_php_version = $required_version;
|
||||
$this->plugin_name = $plugin_name;
|
||||
$this->plugin_file = $plugin_file;
|
||||
$this->text_domain = $text_domain;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check php version.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function is_ok() {
|
||||
if ( version_compare( $this->required_php_version, phpversion(), '>' ) ) {
|
||||
add_action( 'admin_notices', array( $this, 'php_requirement_message' ) );
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Show notice with php requirement.
|
||||
*/
|
||||
public function php_requirement_message() {
|
||||
load_plugin_textdomain( $this->text_domain, false, dirname( plugin_basename( $this->plugin_file ) ) . '/locale' );
|
||||
|
||||
$errata_page_link = 'https://wpml.org/errata/parse-error-syntax-error-unexpected-t_class-and-other-errors-when-using-php-versions-older-than-5-6/';
|
||||
|
||||
// phpcs:disable WordPress.WP.I18n.NonSingularStringLiteralDomain
|
||||
/* translators: 1: Current PHP version number, 2: Plugin version, 3: Minimum required PHP version number */
|
||||
$message = sprintf( __( 'Your server is running PHP version %1$s but %2$s requires at least %3$s.', $this->text_domain ), phpversion(), $this->plugin_name, $this->required_php_version );
|
||||
|
||||
$message .= '<br>';
|
||||
/* translators: Link to errata page */
|
||||
$message .= sprintf( __( 'You can find version of the plugin suitable for your environment <a href="%s">here</a>.', $this->text_domain ), $errata_page_link );
|
||||
// phpcs:enable WordPress.WP.I18n.NonSingularStringLiteralDomain
|
||||
?>
|
||||
<div class="message error">
|
||||
<p>
|
||||
<?php echo wp_kses_post( $message ); ?>
|
||||
</p>
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user