*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
declare (strict_types=1);
namespace WindPress\WindPress;
use WindPressPackages\EDD_SL\PluginUpdater;
use Exception;
use WIND_PRESS;
use WP_Upgrader;
use WindPress\WindPress\Admin\AdminPage;
use WindPress\WindPress\Api\Router as ApiRouter;
use WindPress\WindPress\Core\Runtime;
use WindPress\WindPress\Integration\Loader as IntegrationLoader;
use WindPress\WindPress\Utils\Common;
use WindPress\WindPress\Utils\Notice;
/**
* Manage the plugin lifecycle and provides a single point of entry to the plugin.
*
* @since 3.0.0
*/
final class Plugin
{
/**
* Easy Digital Downloads Software Licensing integration wrapper.
* Pro version only.
*
* @var PluginUpdater|null
*/
public $plugin_updater = null;
/**
* Stores the instance, implementing a Singleton pattern.
*/
private static self $instance;
/**
* The Singleton's constructor should always be private to prevent direct
* construction calls with the `new` operator.
*/
private function __construct()
{
}
/**
* Singletons should not be cloneable.
*/
private function __clone()
{
}
/**
* Singletons should not be restorable from strings.
*
* @throws Exception Cannot unserialize a singleton.
*/
public function __wakeup()
{
throw new Exception('Cannot unserialize a singleton.');
}
/**
* This is the static method that controls the access to the singleton
* instance. On the first run, it creates a singleton object and places it
* into the static property. On subsequent runs, it returns the client existing
* object stored in the static property.
*/
public static function get_instance() : self
{
if (!isset(self::$instance)) {
self::$instance = new self();
}
return self::$instance;
}
/**
* Boot the plugin.
*
* @link https://codex.wordpress.org/Plugin_API/Action_Reference
*/
public function boot() : void
{
\do_action('a!windpress/plugin:boot.start');
// (de)activation hooks.
\register_activation_hook(WIND_PRESS::FILE, fn() => $this->activate_plugin());
\register_deactivation_hook(WIND_PRESS::FILE, fn() => $this->deactivate_plugin());
// upgrade hooks.
\add_action('upgrader_process_complete', function (WP_Upgrader $wpUpgrader, array $options) : void {
if ($options['action'] === 'update' && $options['type'] === 'plugin') {
foreach ($options['plugins'] as $plugin) {
if ($plugin === \plugin_basename(WIND_PRESS::FILE)) {
$this->upgrade_plugin();
}
}
}
}, 10, 2);
$this->maybe_update_plugin();
\add_action('plugins_loaded', fn() => $this->plugins_loaded(), 9);
\add_action('init', fn() => $this->init_plugin());
\do_action('a!windpress/plugin:boot.end');
}
/**
* Handle the plugin's activation by (maybe) running database migrations
* and initializing the plugin configuration.
*/
private function activate_plugin() : void
{
\do_action('a!windpress/plugin:activate_plugin.start');
\update_option(WIND_PRESS::WP_OPTION . '_version', WIND_PRESS::VERSION);
$this->maybe_embedded_license();
\do_action('a!windpress/plugin:activate_plugin.end');
}
/**
* Handle plugin's deactivation by (maybe) cleaning up after ourselves.
*/
private function deactivate_plugin() : void
{
\do_action('a!windpress/plugin:deactivate_plugin.start');
\do_action('a!windpress/plugin:deactivate_plugin.end');
}
/**
* Handle the plugin's upgrade by (maybe) running database migrations.
*/
private function upgrade_plugin() : void
{
\do_action('a!windpress/plugin:upgrade_plugin.start');
\do_action('a!windpress/plugin:upgrade_plugin.end');
}
/**
* Initialize the plugin on WordPress' `init` hook.
*/
private function init_plugin() : void
{
\do_action('a!windpress/plugin:init_plugin.start');
// Load translations.
// load_plugin_textdomain(WIND_PRESS::TEXT_DOMAIN, false, dirname(plugin_basename(WIND_PRESS::FILE)) . '/languages/');
new ApiRouter();
Runtime::get_instance()->init();
// Instantiate the AdminPage class.
new AdminPage();
\do_action('a!windpress/plugin:init_plugin.end');
}
/**
* Initialize the plugin on WordPress' `plugins_loaded` hook.
*/
private function plugins_loaded() : void
{
\do_action('a!windpress/plugin:plugins_loaded.start');
IntegrationLoader::get_instance()->register_integrations();
if (\is_admin()) {
\add_action('admin_notices', static fn() => Notice::admin_notices());
\add_filter('plugin_action_links_' . \plugin_basename(WIND_PRESS::FILE), fn($links) => $this->plugin_action_links($links));
}
\do_action('a!windpress/plugin:plugins_loaded.end');
}
/**
* Add plugin action links.
*
* @param array $links Plugin action links.
* @return array Plugin action links.
*
* @todo Add settings link when the settings page is implemented.
*/
private function plugin_action_links(array $links) : array
{
$base_url = AdminPage::get_page_url();
\array_unshift($links, \sprintf('%s', \esc_url(\sprintf('%s#/settings', $base_url)), \esc_html__('Settings', 'windpress')));
if (!Common::is_updater_library_available()) {
\array_unshift($links, \sprintf('%s', \esc_url(Common::plugin_data('PluginURI') . '?utm_source=WordPress&utm_campaign=liteplugin&utm_medium=plugin-action-links&utm_content=Upgrade#pricing'), \esc_html__('Upgrade to Pro', 'windpress')));
}
return $links;
}
/**
* Initialize the plugin updater.
* Pro version only.
*
* @return PluginUpdater
*/
public function maybe_update_plugin()
{
if (!\class_exists(PluginUpdater::class)) {
return null;
}
if ($this->plugin_updater instanceof \WindPressPackages\EDD_SL\PluginUpdater) {
return $this->plugin_updater;
}
$license = \get_option(WIND_PRESS::WP_OPTION . '_license', ['key' => '', 'opt_in_pre_release' => \false]);
$this->plugin_updater = new PluginUpdater(WIND_PRESS::WP_OPTION, ['version' => WIND_PRESS::VERSION, 'license' => $license['key'] ? \trim($license['key']) : \false, 'beta' => $license['opt_in_pre_release'], 'plugin_file' => WIND_PRESS::FILE, 'item_id' => WIND_PRESS::EDD_STORE['item_id'], 'store_url' => WIND_PRESS::EDD_STORE['store_url'], 'author' => WIND_PRESS::EDD_STORE['author']]);
return $this->plugin_updater;
}
/**
* Check if the plugin distributed with an embedded license and activate the license.
* Pro version only.
*/
private function maybe_embedded_license() : void
{
if (!\class_exists(PluginUpdater::class)) {
return;
}
$license_file = \dirname(WIND_PRESS::FILE) . '/license-data.php';
if (!\file_exists($license_file)) {
return;
}
require_once $license_file;
$const_name = 'ROSUA_EMBEDDED_LICENSE_KEY_' . WIND_PRESS::EDD_STORE['item_id'];
if (!\defined($const_name)) {
return;
}
$license_key = \constant($const_name);
\update_option(WIND_PRESS::WP_OPTION . '_license', ['key' => $license_key, 'opt_in_pre_release' => \false]);
\wp_delete_file($license_file);
// activate the license.
$this->maybe_update_plugin()->activate($license_key);
}
}