PluginProbe
WindPress – Tailwind CSS integration for WordPress / 3.2.87
WindPress – Tailwind CSS integration for WordPress v3.2.87
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 / Licensing / Manager.php

Manager.php in WindPress – Tailwind CSS integration for WordPress 3.2.87, at src/Licensing/Manager.php

210 lines 8.4 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\Licensing;
13
14 use EasyDigitalDownloads\Updater\Licensing\License;
15 use EasyDigitalDownloads\Updater\Messenger;
16 use EasyDigitalDownloads\Updater\Requests\API;
17 use EasyDigitalDownloads\Updater\Updaters\Plugin as PluginUpdater;
18 use WIND_PRESS;
19 use WP_Error;
20 /**
21 * Bridges WindPress's existing license UI to the official EDD Software
22 * Licensing SDK and initializes its WordPress plugin updater.
23 */
24 final class Manager
25 {
26 public const INTEGRATION_ID = 'windpress';
27 public const OPTION_NAME = 'windpress_license_key';
28 private const MIGRATION_OPTION = 'windpress_edd_sl_sdk_migrated';
29 private License $license;
30 public function __construct()
31 {
32 $this->license = new License(self::INTEGRATION_ID, self::get_integration_args(), new Messenger());
33 $this->migrate_legacy_license();
34 }
35 /**
36 * Arguments shared by the SDK registry and the compatibility bridge.
37 *
38 * @return array<string, mixed>
39 */
40 public static function get_integration_args(): array
41 {
42 return ['id' => self::INTEGRATION_ID, 'url' => WIND_PRESS::EDD_STORE['store_url'], 'item_id' => WIND_PRESS::EDD_STORE['item_id'], 'version' => WIND_PRESS::VERSION, 'file' => WIND_PRESS::FILE, 'option_name' => self::OPTION_NAME, 'weekly_check' => \true];
43 }
44 /**
45 * Initialize the official updater with WindPress's pre-release behavior
46 * and WordPress.org override preserved.
47 */
48 public function boot_updater(): void
49 {
50 if (!current_user_can('manage_options') && !wp_doing_cron()) {
51 return;
52 }
53 $license_key = $this->get_license_key();
54 if ($license_key === '') {
55 return;
56 }
57 new PluginUpdater(WIND_PRESS::EDD_STORE['store_url'], ['file' => WIND_PRESS::FILE, 'item_id' => WIND_PRESS::EDD_STORE['item_id'], 'version' => WIND_PRESS::VERSION, 'license' => $license_key, 'beta' => $this->is_pre_release_enabled(), 'allow_tracking' => $this->license->get_allow_tracking(), 'wp_override' => \true], new Messenger());
58 }
59 public function get_license_key(): string
60 {
61 return trim((string) $this->license->get_license_key());
62 }
63 public function is_activated(): bool
64 {
65 if ($this->get_license_key() === '') {
66 return \false;
67 }
68 $status = get_option($this->license->get_status_option_name());
69 return is_object($status) && ($status->success ?? \true) !== \false && in_array($status->license ?? '', ['active', 'valid'], \true);
70 }
71 /**
72 * Activate and persist a license using the official SDK request client.
73 *
74 * @return object|WP_Error
75 */
76 public function activate(string $license_key)
77 {
78 $license_key = trim($license_key);
79 if ($license_key === '') {
80 return new WP_Error('missing', __('Enter a license key.', 'windpress'));
81 }
82 $old_license_key = $this->get_license_key();
83 $license_data = $this->request('activate_license', $license_key);
84 if (is_wp_error($license_data)) {
85 return $license_data;
86 }
87 update_option(self::OPTION_NAME, $license_key);
88 $this->license->save($license_data);
89 $this->clear_cache([$old_license_key, $license_key]);
90 return $license_data;
91 }
92 /**
93 * Deactivate and remove the currently stored license.
94 *
95 * @return object|WP_Error
96 */
97 public function deactivate()
98 {
99 $license_key = $this->get_license_key();
100 if ($license_key === '') {
101 delete_option($this->license->get_status_option_name());
102 return (object) ['success' => \true, 'license' => 'inactive'];
103 }
104 $license_data = $this->request('deactivate_license', $license_key);
105 if (is_wp_error($license_data)) {
106 return $license_data;
107 }
108 delete_option(self::OPTION_NAME);
109 delete_option($this->license->get_status_option_name());
110 $this->clear_cache([$license_key]);
111 return $license_data;
112 }
113 /**
114 * Clear update data after activation, deactivation, or plugin activation.
115 *
116 * @param array<int, string>|null $license_keys
117 */
118 public function clear_cache(?array $license_keys = null): void
119 {
120 $license_keys = $license_keys ?? [$this->get_license_key()];
121 $slug = basename(dirname(WIND_PRESS::FILE));
122 $beta = (int) $this->is_pre_release_enabled();
123 foreach (array_unique($license_keys) as $license_key) {
124 $cache_keys = [
125 // Official EDD SDK cache key.
126 md5(wp_json_encode([$slug, $license_key, $beta])),
127 // Rosua updater cache key used by previous WindPress releases.
128 md5(serialize($slug . $license_key . $beta)),
129 ];
130 foreach (array_unique($cache_keys) as $cache_key) {
131 delete_option('edd_sl_' . $cache_key);
132 }
133 }
134 delete_transient(WIND_PRESS::WP_OPTION . '_license_seed');
135 delete_site_transient('update_plugins');
136 }
137 public function error_message(string $code): string
138 {
139 switch ($code) {
140 case 'expired':
141 return __('Your license key has expired.', 'windpress');
142 case 'disabled':
143 case 'revoked':
144 return __('Your license key has been disabled.', 'windpress');
145 case 'inactive':
146 case 'site_inactive':
147 return __('Your license is not active for this website.', 'windpress');
148 case 'no_activations_left':
149 return __('Your license key has reached its activation limit.', 'windpress');
150 case 'missing_url':
151 return __('The license does not exist or the website URL was not provided.', 'windpress');
152 case 'key_mismatch':
153 case 'missing':
154 case 'invalid':
155 case 'invalid_item_id':
156 case 'item_name_mismatch':
157 return __('Invalid license key.', 'windpress');
158 default:
159 return __('The license server rejected the request.', 'windpress');
160 }
161 }
162 /**
163 * @return object|WP_Error
164 */
165 private function request(string $action, string $license_key)
166 {
167 $api = new API(WIND_PRESS::EDD_STORE['store_url']);
168 $license_data = $api->make_request(['edd_action' => $action, 'license' => $license_key, 'item_id' => WIND_PRESS::EDD_STORE['item_id']]);
169 if (!is_object($license_data)) {
170 return new WP_Error('license_server_unavailable', __('The license server could not be reached.', 'windpress'));
171 }
172 if (empty($license_data->success)) {
173 $code = (string) ($license_data->error ?? $license_data->license ?? 'invalid');
174 return new WP_Error($code, $this->error_message($code));
175 }
176 return $license_data;
177 }
178 private function is_pre_release_enabled(): bool
179 {
180 $legacy_license = get_option(WIND_PRESS::WP_OPTION . '_license', []);
181 return is_array($legacy_license) && !empty($legacy_license['opt_in_pre_release']);
182 }
183 /**
184 * Copy license data from the Rosua updater options without changing or
185 * deleting them, so upgraded installations keep their activation state.
186 */
187 private function migrate_legacy_license(): void
188 {
189 if (get_option(self::MIGRATION_OPTION, \false)) {
190 return;
191 }
192 $missing = new \stdClass();
193 $license_key = get_option(self::OPTION_NAME, $missing);
194 if ($license_key === $missing || trim((string) $license_key) === '') {
195 $legacy_license = get_option(WIND_PRESS::WP_OPTION . '_license', []);
196 $legacy_key = is_array($legacy_license) ? trim((string) ($legacy_license['key'] ?? '')) : '';
197 if ($legacy_key !== '') {
198 update_option(self::OPTION_NAME, $legacy_key);
199 }
200 }
201 if (get_option($this->license->get_status_option_name(), $missing) === $missing) {
202 $legacy_status = get_transient(WIND_PRESS::WP_OPTION . '_license_seed');
203 if (is_object($legacy_status) && !empty($legacy_status->license)) {
204 $this->license->save($legacy_status);
205 }
206 }
207 update_option(self::MIGRATION_OPTION, \true);
208 }
209 }
210