geno/wp-content/plugins/ti-woocommerce-wishlist/includes/pluginextend.helper.php
2024-02-01 11:54:18 +00:00

696 lines
17 KiB
PHP

<?php
/**
* Dependency plugin class
*
* @since 1.0.0
* @package TInvWishlist
*/
// If this file is called directly, abort.
if (!defined('ABSPATH')) {
die;
}
/**
* Dependency plugin class
*/
class TInvWL_PluginExtend
{
/**
* Plugin name
*
* @var string
*/
public $_name;
/**
* Plugin transient name
*
* @var string
*/
private $transient;
/**
* Plugin dependency array
*
* @var array
*/
private $dependency;
/**
* Current dependency name
*
* @var string
*/
private $dependency_current;
/**
* Current dependency nice name
*
* @var string
*/
private $dependency_current_nice_name;
/**
* Plugin path dir
*
* @var string
*/
private $plugin_path;
/**
* Cached plugin data
*
* @var array
*/
private $plugin_data;
/**
* Plugin error message
*
* @var array
*/
public $message;
/**
* Constructor
*
* @param string $plugin Plugin transient name, or can use Plugin root file.
* @param string $root_file Plugin root file, or can use Plugin transient name.
* @param string $plugin_name Plugin name.
*/
public function __construct($plugin, $root_file = null, $plugin_name = TINVWL_PREFIX)
{
$this->_name = $plugin_name;
if (empty($plugin)) {
$this->transient = plugin_basename($root_file);
$this->plugin_path = trailingslashit(plugin_dir_path(dirname($root_file)));
} else {
$this->transient = $plugin;
$this->plugin_path = trailingslashit(dirname(TINVWL_PATH));
}
$this->dependency = array();
$this->plugin_data = array();
$this->message = array();
}
/**
* Run hooks dependency
*/
public function run()
{
if ('plugins.php' === basename($_SERVER['PHP_SELF']) && !(defined('WP_CLI') && WP_CLI)) { // @codingStandardsIgnoreLine WordPress.VIP.SuperGlobalInputUsage.AccessDetected
add_action('admin_notices', array($this, 'admin_notices'));
$plugins = $this->get_dependency_plugins();
foreach (array_keys($plugins) as $plugin) {
add_filter('plugin_action_links_' . $plugin, array($this, 'plugin_action_links_maybe_deactivate'));
add_filter('network_admin_plugin_action_links_' . $plugin, array(
$this,
'plugin_action_links_maybe_deactivate',
));
}
add_action('after_plugin_row_' . $this->transient, array($this, 'plugin_row'), 10);
} else {
add_action('update_option_active_sitewide_plugins', array($this, 'maybe_deactivate'), 10, 2);
add_action('update_option_active_plugins', array($this, 'maybe_deactivate'), 10, 2);
}
}
/**
* Set dependency plugin transient name
*
* @param string $plugin Plugin transient name.
* @param string $nice_name Plugin nice name.
*
* @return \TInvWL_PluginExtend
*/
public function set_dependency($plugin, $nice_name)
{
$this->dependency_current = $plugin;
$this->dependency_current_nice_name = $nice_name;
return $this;
}
/**
* Reset current dependency plugin transient name
*
* @return \TInvWL_PluginExtend
*/
public function reset_dependency()
{
$this->dependency_current = null;
return $this;
}
/**
* Set dependency version by index rules
*
* @param integer $index Index rules.
* 0 Min version.
* 1 Max version.
* 2 Need plugin verion.
* 3 Conflict plugin verion.
* @param string $version Version dependency.
*
* @return boolean
*/
private function set_dependency_version($index, $version = '1.0.0')
{
if (empty($this->dependency_current)) {
return false;
}
if (empty($version)) {
$this->dependency[$this->dependency_current][$index] = null;
} else {
$this->dependency[$this->dependency_current][$index] = $version;
}
$this->dependency[$this->dependency_current]['nice_name'] = $this->dependency_current_nice_name;
}
/**
* Set minimal dependency version
*
* @param string $version Version dependency.
*
* @return \TInvWL_PluginExtend
*/
public function min($version = '1.0.0')
{
if ('*' === $version) {
$version = '';
}
$this->set_dependency_version(0, $version);
return $this;
}
/**
* Set maximum dependency version
*
* @param string $version Version dependency.
*
* @return \TInvWL_PluginExtend
*/
public function max($version = '1.0.0')
{
if ('*' === $version) {
$version = '';
}
$this->set_dependency_version(1, $version);
return $this;
}
/**
* Set need plugin dependency version
*
* @param string $version Version dependency. Can use '*' for check any version.
*
* @return \TInvWL_PluginExtend
*/
public function need($version = '*')
{
$this->set_dependency_version(2, $version);
return $this;
}
/**
* Set conflict plugin dependency version
*
* @param string $version Version dependency. Can use '*' for check any version.
*
* @return \TInvWL_PluginExtend
*/
public function conflict($version = '*')
{
$this->set_dependency_version(3, $version);
return $this;
}
/**
* Get dependency array
*
* @param string $plugin Plugin transient name.
*
* @return array
*/
private function get_dependency($plugin)
{
if (array_key_exists($plugin, $this->dependency)) {
return $this->dependency[$plugin];
}
return array();
}
/**
* Get dependency version from array.
*
* @param string $plugin Plugin transient name.
* @param integer $index Index rules.
* 0 Min version.
* 1 Max version.
* 2 Need plugin verion.
* 3 Conflict plugin verion.
*
* @return array
*/
private function get_dep_ver($plugin, $index)
{
$dependency = $this->get_dependency($plugin);
if (array_key_exists($index, $dependency)) {
return $dependency[$index];
}
return null;
}
/**
* List dependency plugins
*
* @return array
*/
private function get_dependency_plugins()
{
return $this->dependency;
}
/**
* Check all dependency.
*
* @return boolean
*/
public function status_dependency()
{
$this->message = array();
$plugins = $this->get_dependency_plugins();
$status = true;
foreach ($plugins as $plugin => $data) {
if (is_plugin_active($plugin) && !$this->is_plugin_at_conflict_version($plugin)) {
$status = $this->set_message('conflict', $data['nice_name']);
} elseif (!is_plugin_active($plugin) || !$this->is_plugin_at_need_version($plugin)) {
$status = $this->set_message('need', $data['nice_name']);
} elseif (is_plugin_active($plugin) && !$this->is_plugin_at_min_version($plugin)) {
$status = $this->set_message('upgrade', $data['nice_name']);
} elseif (is_plugin_active($plugin) && !$this->is_plugin_at_max_version($plugin)) {
$status = $this->set_message('downgrade', $plugin);
} elseif (!is_plugin_active($plugin)) {
$status = $this->set_message('activate', $data['nice_name']);
}
}
return $status;
}
/**
* Check plugin minimal version dependency.
*
* @param string $plugin Plugin transient name.
*
* @return boolean
*/
private function is_plugin_at_min_version($plugin)
{
return $this->is_plugin_at_version($plugin, 0);
}
/**
* Check plugin maximal version dependency.
*
* @param string $plugin Plugin transient name.
*
* @return boolean
*/
private function is_plugin_at_max_version($plugin)
{
return $this->is_plugin_at_version($plugin, 1);
}
/**
* Check plugin need version dependency.
*
* @param string $plugin Plugin transient name.
*
* @return boolean
*/
private function is_plugin_at_need_version($plugin)
{
return $this->is_plugin_at_version($plugin, 2);
}
/**
* Check plugin conflict version dependency.
*
* @param string $plugin Plugin transient name.
*
* @return boolean
*/
private function is_plugin_at_conflict_version($plugin)
{
return $this->is_plugin_at_version($plugin, 3);
}
/**
* Check plugin version dependency.
*
* @param string $plugin Plugin transient name.
*
* @param integer $i Index rules.
* 0 Min version.
* 1 Max version.
* 2 Need plugin verion.
* 3 Conflict plugin verion.
*
* @return boolean
*/
private function is_plugin_at_version($plugin, $i = 0)
{
switch ($i) {
case 3:
$type = 'ne';
$i = 3;
break;
case 2:
$type = 'eq';
$i = 2;
break;
case 1:
$type = 'le';
$i = 1;
break;
case 0:
default:
$type = 'ge';
$i = 0;
}
$version = $this->get_dep_ver($plugin, $i);
if (is_null($version)) {
return true;
}
$version_plugin = $this->get_plugin_data($plugin, 'Version');
if ('*' === $version) {
if (3 === $i) {
return empty($version_plugin);
} else {
return !empty($version_plugin);
}
}
return version_compare($version_plugin, $version, $type);
}
/**
* Get error messages
*
* @param boolean $first Get first or all error messages.
*
* @return string
*/
public function get_messages($first = false)
{
if ($first) {
$message = array_shift($this->message);
$this->message = array();
return $message;
}
$message = '<p>' . implode('</p><p>', $this->message) . '</p>';
$this->message = array();
return $message;
}
/**
* Deactivation plugin
*
* @param string $old_value Not used.
* @param string $value Not used.
*
* @return string
*/
public function maybe_deactivate($old_value, $value)
{
if (!$this->status_dependency()) {
self::deactivate_self($this->transient);
if (defined('WP_CLI') && WP_CLI) {
$plugins = $this->get_dependency_plugins();
$this->get_messages();
foreach ($plugins as $plugin => $data) {
if (!is_plugin_active($plugin) || !$this->is_plugin_at_need_version($plugin)) {
return WP_CLI::error($this->get_message('deactivate', $data['nice_name']));
} elseif (is_plugin_active($plugin) && !$this->is_plugin_at_min_version($plugin)) {
return WP_CLI::error($this->get_message('deactivate', $data['nice_name']));
} elseif (is_plugin_active($plugin) && !$this->is_plugin_at_max_version($plugin)) {
return WP_CLI::error($this->get_message('deactivate', $data['nice_name']));
}
}
}
}
}
/**
* Deactivation plugin
*
* @param string $actions Not used.
*
* @return string
*/
public function plugin_action_links_maybe_deactivate($actions)
{
if (!$this->status_dependency()) {
self::deactivate_self($this->transient);
}
return $actions;
}
/**
* Return message in plugin lists table
*
* @param string $file Plugin file path.
*/
public function plugin_row($file)
{
if (!$this->status_dependency()) {
$wp_list_table = _get_list_table('WP_Plugins_List_Table');
?>
<tr class="plugin-update-tr installer-plugin-update-tr">
<td colspan="<?php echo $wp_list_table->get_column_count(); // WPCS: xss ok. ?>"
class="plugin-update colspanchange">
<div class="notice inline notice-warning notice-alt">
<p class="installer-q-icon">
<?php echo $this->get_messages(true); // WPCS: xss ok. ?>
</p>
</div>
</td>
</tr>
<?php
}
}
/**
* Deactivation plugin
*
* @param string $file Plugin file path.
* @param boolean $network_wide Network wide.
*/
public static function deactivate_self($file, $network_wide = false)
{
if (is_multisite()) {
$network_wide = is_plugin_active_for_network($file);
}
deactivate_plugins($file, true, $network_wide);
}
/**
* Set message
*
* @param string $type Type error message.
* @param string $plugin Plugin transient name.
*
* @return boolean
*/
private function set_message($type, $plugin)
{
$current = $this->get_plugin_data('current', 'Name') ? $this->get_plugin_data('current', 'Name') : $this->transient;
$version = $this->get_plugin_data('current', 'Version');
$plugname = $this->get_plugin_data($plugin, 'Name') ? $this->get_plugin_data($plugin, 'Name') : $plugin;
$message = '';
switch ($type) {
case 'deactivate':
$version = $this->get_dep_ver($plugin, 0);
$message = __('%2$s %3$s is required for %1$s. Deactivating %1$s.', 'ti-woocommerce-wishlist');
if (empty($version)) {
$version = $this->get_dep_ver($plugin, 1);
}
if (empty($version)) {
$version = $this->get_dep_ver($plugin, 2);
}
if (empty($version)) {
$version = $this->get_dep_ver($plugin, 3);
$message = __('%1$s is confilcted with %2$s %3$s. Deactivating %1$s.', 'ti-woocommerce-wishlist');
}
if ('*' === $version) {
$version = $this->get_plugin_data($plugin, 'Version');
}
break;
case 'upgrade':
case 'update':
$version = $this->get_dep_ver($plugin, 0);
$message = __('%2$s %3$s is required. Please update it before activating this plugin.', 'ti-woocommerce-wishlist');
break;
case 'downgrade':
case 'downdate':
$version = $this->get_dep_ver($plugin, 1);
$message = __('%2$s %3$s is required. Please downgrade it before activating this plugin.', 'ti-woocommerce-wishlist');
break;
case 'need':
$version = '*' === $this->get_dep_ver($plugin, 2) ? $this->get_plugin_data($plugin, 'Version') : $this->get_dep_ver($plugin, 2);
$message = __('%2$s %3$s is required. Please activate it before activating this plugin.', 'ti-woocommerce-wishlist');
break;
case 'conflict':
$version = '*' === $this->get_dep_ver($plugin, 3) ? $this->get_plugin_data($plugin, 'Version') : $this->get_dep_ver($plugin, 3);
$message = __('%1$s is conflicted with %2$s %3$s. Please disable it before activating this plugin.', 'ti-woocommerce-wishlist');
break;
case 'activate':
$version = $this->get_dep_ver($plugin, 1);
$message = __('%1$s %3$s is required. Please activate it before activating this plugin.', 'ti-woocommerce-wishlist');
break;
} // End switch().
if (empty($message)) {
return true;
}
if (!empty($version)) {
$version = '(v' . $version . ')';
}
$message = sprintf($message, $current, $plugname, $version);
$this->message[] = $message;
return false;
}
/**
* Get message
*
* @param string $type Type error message.
* @param string $plugin Plugin transient name.
*
* @return boolean
*/
private function get_message($type, $plugin)
{
$current = $this->get_plugin_data('current', 'Name') ? $this->get_plugin_data('current', 'Name') : $this->transient;
$version = $this->get_plugin_data('current', 'Version');
$plugname = $this->get_plugin_data($plugin, 'Name') ? $this->get_plugin_data($plugin, 'Name') : $plugin;
$message = '';
switch ($type) {
case 'deactivate':
$version = $this->get_dep_ver($plugin, 0);
$message = __('%2$s %3$s is required for %1$s. Deactivating %1$s.', 'ti-woocommerce-wishlist');
if (empty($version)) {
$version = $this->get_dep_ver($plugin, 1);
}
if (empty($version)) {
$version = $this->get_dep_ver($plugin, 2);
}
if (empty($version)) {
$version = $this->get_dep_ver($plugin, 3);
$message = __('%1$s is conflicted with %2$s %3$s. Deactivating %1$s.', 'ti-woocommerce-wishlist');
}
if ('*' === $version) {
$version = $this->get_plugin_data($plugin, 'Version');
}
break;
case 'upgrade':
case 'update':
$version = $this->get_dep_ver($plugin, 0);
$message = __('%2$s %3$s is required. Please update it before activating this plugin.', 'ti-woocommerce-wishlist');
break;
case 'downgrade':
case 'downdate':
$version = $this->get_dep_ver($plugin, 1);
$message = __('%2$s %3$s is required. Please downgrade it before activating this plugin.', 'ti-woocommerce-wishlist');
break;
case 'need':
$version = '*' === $this->get_dep_ver($plugin, 2) ? $this->get_plugin_data($plugin, 'Version') : $this->get_dep_ver($plugin, 2);
$message = __('%2$s %3$s is required. Please activate it before activating this plugin.', 'ti-woocommerce-wishlist');
break;
case 'conflict':
$version = '*' === $this->get_dep_ver($plugin, 3) ? $this->get_plugin_data($plugin, 'Version') : $this->get_dep_ver($plugin, 3);
$message = __('%1$s is conflicted with %2$s %3$s. Please disable it before activating this plugin.', 'ti-woocommerce-wishlist');
break;
case 'activate':
$version = $this->get_dep_ver($plugin, 1);
$message = __('%1$s %3$s is required. Please activate it before activating this plugin.', 'ti-woocommerce-wishlist');
break;
} // End switch().
if (!empty($version)) {
$version = '(v' . $version . ')';
}
return sprintf($message, $current, $plugname, $version);
}
/**
* Add error admin notice
*/
public function admin_notices()
{
if (!$this->status_dependency()) {
printf('<div class="error is-dismissible">%s</div>', $this->get_messages()); // WPCS: xss ok.
}
}
/**
* Get plugin info
*
* @param string $plugin Plugin transient name.
* @param string $attr Plugin attribute name.
*
* @return mixed
*/
public function get_plugin_data($plugin, $attr = null)
{
if ('current' === $plugin) {
$plugin = $this->transient;
}
$plugin_path = $this->plugin_path . $plugin;
if (!array_key_exists($plugin, $this->plugin_data)) {
require_once(ABSPATH . 'wp-admin/includes/plugin.php');
$plugin_data = array_filter(@get_plugin_data($plugin_path, false, false)); // @codingStandardsIgnoreLine Generic.PHP.NoSilencedErrors.Discouraged
if (empty($plugin_data)) {
$plugin_data = null;
}
$this->plugin_data[$plugin] = $plugin_data;
}
if (empty($attr)) {
return $this->plugin_data[$plugin];
}
if (array_key_exists($attr, (array)$this->plugin_data[$plugin])) {
return $this->plugin_data[$plugin][$attr];
}
return null;
}
}