'premmerce-product-comparison/premmerce-product-comparison.php', PremmerceToolkitPlugin::class => 'premmerce-woocommerce-toolkit/premmerce-toolkit.php', ); private $textDomains = array( ProductComparisonPlugin::class => 'premmerce-product-comparison', PremmerceToolkitPlugin::class => 'premmerce-toolkit', ); /** * @var array */ private $instances = array(); /** * @var array */ private $addonsStatuses = array(); /** * Container constructor. * * @param FileManager $fileManager */ public function __construct(FileManager $fileManager) { $this->addonsBasePath = $fileManager->getPluginDirectory() . $this->addonsDirname; $this->addonsRelativePath = $fileManager->getPluginName() . '/' . $this->addonsDirname; } public function init() { $this->addonsStatuses = $this->getOptions(); add_action('plugins_loaded', array($this, 'runActive')); add_filter('plugin_action_links', function ($actions, $plugin, $data) { $plugins = array_flip($this->addons); if (in_array($plugin, $this->addons) && $this->isActive($plugins[ $plugin ])) { unset($actions['activate']); $actions[] = '

' . sprintf(__('Please deactivate %s addon before activating this plugin', 'premmerce'), $data['Title']) . '

'; } return $actions; }, 10, 3); add_action('admin_post_premmerce_addon_action', function () { $class = urldecode($_POST['slug']); $action = urldecode($_POST['addon_action']); if ($this->exists($class)) { switch ($action) { case 'activate': $this->activate(array($class)); break; case 'deactivate': $this->deactivate(array($class)); break; } } wp_redirect($_SERVER['HTTP_REFERER']); die; }); } /** * @return array */ public function getAddons() { return $this->addons; } /** * @param string $class * * @return mixed */ public function get($class) { if ($this->exists($class)) { return $this->instantiate($class); } } public function exists($class) { return array_key_exists($class, $this->addons); } /** * @param string $plugin * * @return string */ public function getPluginFullPath($plugin) { return $this->addonsBasePath . '/' . $plugin; } /** * Run active plugins */ public function runActive() { foreach ($this->getActivePlugins() as $class) { $plugin = $this->addons[ $class ]; if (!is_plugin_active($plugin)) { $this->callAddonMethod($class, 'run'); } else { //deactivate addon if same plugin is active $this->setStatus(array($class), false); } } } /** * Activate plugins * * @param array $addons */ public function activate(array $addons) { foreach ($addons as $addon) { if (!$this->isActive($addon)) { $this->callAddonMethod($addon, 'activate'); } } $this->setStatus($addons, true); } /** * Deactivate plugins * * @param array $plugins */ public function deactivate(array $plugins) { foreach ($plugins as $plugin) { if ($this->isActive($plugin)) { $this->callAddonMethod($plugin, 'deactivate'); } } $this->setStatus($plugins, false); } /** * @param string $plugin * @param string $method * * @return mixed */ private function callAddonMethod($plugin, $method) { if ($plugin = $this->get($plugin)) { if (method_exists($plugin, $method)) { call_user_func(array($plugin, $method)); } }; return $plugin; } /** * Set status to array of plugins * * @param array $plugins * @param bool $status */ private function setStatus(array $plugins, $status) { $options = $this->addonsStatuses; foreach ($plugins as $plugin) { $options[ $plugin ] = $status; } update_option(self::OPTION, $options); } /** * Check that plugin is active * * @param $plugin * * @return mixed */ public function isActive($plugin) { return $this->addonsStatuses[ $plugin ]; } /** * Get data from plugin annotations * * @param string $plugin * * @return array */ public function getPluginData($plugin) { $pluginFullPath = $this->getPluginFullPath($plugin); $default = array( 'Name' => 'Plugin Name', 'PluginURI' => 'Plugin URI', 'Version' => 'Version', 'Description' => 'Description', 'Author' => 'Author', 'AuthorURI' => 'Author URI', 'TextDomain' => 'Text Domain', 'DomainPath' => 'Domain Path', ); $data = get_file_data($pluginFullPath, $default, 'plugin'); return $data; } /** * Array of active plugins * * @return array */ private function getActivePlugins() { $options = $this->getOptions(); $options = array_filter($options); return array_keys($options); } /** * Cleaned plugins options merged with defaults * * @return array */ private function getOptions() { $all = $this->getDefaults(); $options = get_option(self::OPTION, array()); foreach ($options as $key => $status) { if (!array_key_exists($key, $all)) { unset($options[ $key ]); } } $options = array_merge($all, $options); return array_merge($all, $options); } /** * Default option for handled plugins * @return array */ private function getDefaults() { $all = array_keys($this->getAddons()); $keys = array_fill(0, count($all), false); $all = array_combine($all, $keys); return $all; } /** * @param $class * * @return mixed */ private function instantiate($class) { $path = $this->addons[ $class ]; if (!isset($this->instances[ $path ])) { $fullPath = $this->getPluginFullPath($path); $this->loadAddonTextDomain($class); $autoloadPath = dirname($fullPath) . '/vendor/autoload.php'; if (file_exists($autoloadPath)) { require_once $autoloadPath; } $plugin = new $class($fullPath); $this->instances[ $path ] = $plugin; } return $this->instances[ $path ]; } private function loadAddonTextDomain($class) { if (isset($this->textDomains[ $class ])) { $domain = $this->textDomains[ $class ]; $path = $this->addons[ $class ]; $lang = $this->addonsRelativePath . '/' . dirname($path) . '/languages'; load_plugin_textdomain($domain, false, $lang); } } }