PluginProbe
WindPress – Tailwind CSS integration for WordPress / trunk
WindPress – Tailwind CSS integration for WordPress vtrunk
3.2.88 3.2.87 3.2.86 3.2.85 3.2.84 3.2.83 3.2.82 3.2.81 trunk 3.0.0 3.0.1 3.0.10 3.0.11 3.0.12 3.0.13 3.0.14 3.0.15 3.0.16 3.0.17 3.0.2 3.0.3 3.0.4 3.0.5 3.0.6 3.0.7 All 142 releases
windpress / src / Plugin.php

Plugin.php in WindPress – Tailwind CSS integration for WordPress trunk, at src/Plugin.php

278 lines 10.1 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 /*
4 * This file is part of the WindPress package.
5 *
6 * (c) Joshua Gugun Siagian <suabahasa@gmail.com>
7 *
8 * For the full copyright and license information, please view the LICENSE
9 * file that was distributed with this source code.
10 */
11 declare (strict_types=1);
12 namespace WindPress\WindPress;
13
14 use EasyDigitalDownloads\Updater\Registry;
15 use Exception;
16 use WIND_PRESS;
17 use WindPress\WindPress\Abilities\Loader as AbilitiesLoader;
18 use WindPress\WindPress\Admin\AdminPage;
19 use WindPress\WindPress\Api\Router as ApiRouter;
20 use WindPress\WindPress\Core\Runtime;
21 use WindPress\WindPress\Integration\Loader as IntegrationLoader;
22 use WindPress\WindPress\Licensing\Manager as LicenseManager;
23 use WindPress\WindPress\Upgrade\UpgradeManager;
24 use WindPress\WindPress\Utils\Cache as UtilsCache;
25 use WindPress\WindPress\Utils\Common;
26 use WindPress\WindPress\Utils\Notice;
27 use WP_Upgrader;
28 /**
29 * Manage the plugin lifecycle and provides a single point of entry to the plugin.
30 *
31 * @since 3.0.0
32 */
33 final class Plugin
34 {
35 /**
36 * Easy Digital Downloads Software Licensing integration manager.
37 * Pro version only.
38 *
39 * @var LicenseManager|null
40 */
41 public $plugin_updater = null;
42 /**
43 * Stores the instance, implementing a Singleton pattern.
44 */
45 private static self $instance;
46 /**
47 * The Singleton's constructor should always be private to prevent direct
48 * construction calls with the `new` operator.
49 */
50 private function __construct()
51 {
52 }
53 /**
54 * Singletons should not be cloneable.
55 */
56 private function __clone()
57 {
58 }
59 /**
60 * Singletons should not be restorable from strings.
61 *
62 * @throws Exception Cannot unserialize a singleton.
63 */
64 public function __wakeup()
65 {
66 throw new Exception('Cannot unserialize a singleton.');
67 }
68 /**
69 * This is the static method that controls the access to the singleton
70 * instance. On the first run, it creates a singleton object and places it
71 * into the static property. On subsequent runs, it returns the client existing
72 * object stored in the static property.
73 */
74 public static function get_instance(): self
75 {
76 if (!isset(self::$instance)) {
77 self::$instance = new self();
78 }
79 return self::$instance;
80 }
81 /**
82 * Boot the plugin.
83 *
84 * @link https://codex.wordpress.org/Plugin_API/Action_Reference
85 */
86 public function boot(): void
87 {
88 do_action('a!windpress/plugin:boot.start');
89 $this->boot_license_sdk();
90 // (de)activation hooks.
91 register_activation_hook(WIND_PRESS::FILE, fn() => $this->activate_plugin());
92 register_deactivation_hook(WIND_PRESS::FILE, fn() => $this->deactivate_plugin());
93 // upgrade hooks.
94 add_action('upgrader_process_complete', function (WP_Upgrader $wpUpgrader, array $options): void {
95 if ($options['action'] === 'update' && $options['type'] === 'plugin') {
96 foreach ($options['plugins'] as $plugin) {
97 if ($plugin === plugin_basename(WIND_PRESS::FILE)) {
98 $this->upgrade_plugin();
99 }
100 }
101 }
102 }, 10, 2);
103 add_action('plugins_loaded', fn() => $this->plugins_loaded(), 9);
104 add_action('init', fn() => $this->init_plugin());
105 do_action('a!windpress/plugin:boot.end');
106 }
107 /**
108 * Get the initialized license manager.
109 * Pro version only.
110 */
111 public function maybe_update_plugin(): ?LicenseManager
112 {
113 return $this->plugin_updater instanceof LicenseManager ? $this->plugin_updater : null;
114 }
115 public static function is_pro_edition(): bool
116 {
117 return is_file(self::get_license_sdk_path());
118 }
119 /**
120 * Handle the plugin's activation by (maybe) running database migrations
121 * and initializing the plugin configuration.
122 */
123 private function activate_plugin(): void
124 {
125 do_action('a!windpress/plugin:activate_plugin.start');
126 update_option(WIND_PRESS::WP_OPTION . '_version', WIND_PRESS::VERSION);
127 if ($this->plugin_updater instanceof LicenseManager) {
128 $this->maybe_embedded_license();
129 $this->plugin_updater->clear_cache();
130 }
131 do_action('a!windpress/plugin:activate_plugin.end');
132 }
133 /**
134 * Handle plugin's deactivation by (maybe) cleaning up after ourselves.
135 */
136 private function deactivate_plugin(): void
137 {
138 do_action('a!windpress/plugin:deactivate_plugin.start');
139 do_action('a!windpress/plugin:deactivate_plugin.end');
140 }
141 /**
142 * Handle the plugin's upgrade by (maybe) running database migrations.
143 */
144 private function upgrade_plugin(): void
145 {
146 do_action('a!windpress/plugin:upgrade_plugin.start');
147 UpgradeManager::get_instance()->run();
148 do_action('a!windpress/plugin:upgrade_plugin.end');
149 }
150 /**
151 * Initialize the plugin on WordPress' `init` hook.
152 */
153 private function init_plugin(): void
154 {
155 do_action('a!windpress/plugin:init_plugin.start');
156 // Load translations.
157 if (defined('WindPressDeps\WIND_PRESS_LOAD_TEXT_DOMAIN') && constant('WIND_PRESS_LOAD_TEXT_DOMAIN')) {
158 load_plugin_textdomain(WIND_PRESS::TEXT_DOMAIN, \false, dirname(plugin_basename(WIND_PRESS::FILE)) . '/languages/');
159 }
160 new ApiRouter();
161 Runtime::get_instance()->init();
162 // Instantiate the AdminPage class.
163 new AdminPage();
164 UtilsCache::exclude_optimization();
165 // Initialize Abilities API integration
166 AbilitiesLoader::get_instance()->init();
167 do_action('a!windpress/plugin:init_plugin.end');
168 }
169 /**
170 * Initialize the plugin on WordPress' `plugins_loaded` hook.
171 */
172 private function plugins_loaded(): void
173 {
174 do_action('a!windpress/plugin:plugins_loaded.start');
175 IntegrationLoader::get_instance()->register_integrations();
176 if (is_admin()) {
177 add_action('admin_notices', static fn() => Notice::admin_notices());
178 add_filter('plugin_action_links_' . plugin_basename(WIND_PRESS::FILE), fn($links) => $this->plugin_action_links($links));
179 }
180 do_action('a!windpress/plugin:plugins_loaded.end');
181 }
182 /**
183 * Add plugin action links.
184 *
185 * @param array $links Plugin action links.
186 * @return array Plugin action links.
187 *
188 * @todo Add settings link when the settings page is implemented.
189 */
190 private function plugin_action_links(array $links): array
191 {
192 $base_url = AdminPage::get_page_url();
193 array_unshift($links, sprintf('<a href="%s">%s</a>', esc_url(sprintf('%s#/settings', $base_url)), esc_html__('Settings', 'windpress')));
194 if (!Common::is_updater_library_available()) {
195 array_unshift($links, sprintf('<a href="%s" style="color:#067b34;font-weight:600;" target="_blank">%s</a>', 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')));
196 }
197 return $links;
198 }
199 /**
200 * Register the plugin with EDD's official Software Licensing SDK.
201 */
202 private function boot_license_sdk(): void
203 {
204 $sdk_path = self::get_license_sdk_path();
205 if (!is_file($sdk_path)) {
206 return;
207 }
208 $this->plugin_updater = new LicenseManager();
209 add_action('init', [$this->plugin_updater, 'boot_updater']);
210 add_action('edd_sl_sdk_registry', function ($registry): void {
211 $this->register_license_integration($registry);
212 });
213 require_once $sdk_path;
214 // Plugin activation can happen after the SDK initialization hooks ran.
215 if (did_action('after_setup_theme') && class_exists(Registry::class)) {
216 $this->register_license_integration(Registry::instance());
217 }
218 }
219 /**
220 * @param mixed $registry
221 */
222 private function register_license_integration($registry): void
223 {
224 if (!$registry instanceof Registry) {
225 return;
226 }
227 if (!$registry->offsetExists(LicenseManager::INTEGRATION_ID)) {
228 $registry->register(LicenseManager::get_integration_args());
229 }
230 $handler = $registry->offsetGet(LicenseManager::INTEGRATION_ID);
231 if (is_object($handler) && method_exists($handler, 'auto_updater')) {
232 // The SDK registry does not pass wp_override or beta through in
233 // version 1.0.3, so Manager boots the official updater directly.
234 remove_action('init', [$handler, 'auto_updater']);
235 }
236 }
237 private static function get_license_sdk_path(): string
238 {
239 return dirname(WIND_PRESS::FILE) . '/vendor/easy-digital-downloads/edd-sl-sdk/edd-sl-sdk.php';
240 }
241 /**
242 * Check if the plugin distributed with an embedded license and activate the license.
243 * Pro version only.
244 */
245 private function maybe_embedded_license(): void
246 {
247 if (!$this->plugin_updater instanceof LicenseManager) {
248 return;
249 }
250 $license_file = dirname(WIND_PRESS::FILE) . '/license-data.php';
251 if (!file_exists($license_file)) {
252 return;
253 }
254 require_once $license_file;
255 $const_names = [
256 'WIND_PRESS_EMBEDDED_LICENSE_KEY_' . WIND_PRESS::EDD_STORE['item_id'],
257 'JOOOSI_EMBEDDED_LICENSE_KEY_' . WIND_PRESS::EDD_STORE['item_id'],
258 // Preserve the embedded-license constant used by previous releases.
259 'ROSUA_EMBEDDED_LICENSE_KEY_' . WIND_PRESS::EDD_STORE['item_id'],
260 ];
261 $const_name = null;
262 foreach ($const_names as $candidate) {
263 if (defined($candidate)) {
264 $const_name = $candidate;
265 break;
266 }
267 }
268 if ($const_name === null) {
269 return;
270 }
271 $license_key = constant($const_name);
272 update_option(WIND_PRESS::WP_OPTION . '_license', ['key' => $license_key, 'opt_in_pre_release' => \false]);
273 wp_delete_file($license_file);
274 // activate the license.
275 $this->plugin_updater->activate((string) $license_key);
276 }
277 }
278