PluginProbe
MainWP Dashboard: Self-hosted WordPress Management for Agencies / 4.0.5
MainWP Dashboard: Self-hosted WordPress Management for Agencies v4.0.5
6.2 6.1.8 6.1.7 6.1.6 6.1.5 6.1.4 6.1.3 6.1.2 6.1.1 6.1 6.0.12 6.0.11 4.6.0.1 5.0 5.0.1 5.0.2 5.0.3 5.0.3.1 5.0.3.2 5.1 5.1.1 5.2 5.2.1 5.2.2 5.3 All 153 releases
← All changes | class/class-mainwp-api-manager.php +291 -648 6.14.0.5 View file →
@@ -1,729 +1,372 @@
1 1 <?php
2 -/**
3 - * MainWP API Manager
4 - *
5 - * This class handles MainWP Extensions API licensing.
6 - *
7 - * @package MainWP/MainWP API Manager
8 - * @author Todd Lahman LLC
9 - * @copyright Copyright (c) Todd Lahman LLC
10 - * @since 1.0.0
11 - */
12 2
13 -namespace MainWP\Dashboard;
3 +class MainWP_Api_Manager {
14 4
15 -// Exit if accessed directly.
16 -if ( ! defined( 'ABSPATH' ) ) {
17 - exit;
18 -}
5 + private $upgrade_url = 'https://mainwp.com/';
6 + private $renew_license_url = 'https://mainwp.com/my-account';
7 + public $domain = '';
19 8
20 -/**
21 - * Class MainWP_Api_Manager
22 - *
23 - * @package MainWP\Dashboard
24 - */
25 -class MainWP_Api_Manager { // phpcs:ignore Generic.Classes.OpeningBraceSameLine.ContentAfterBrace -- NOSONAR.
9 + /**
10 + * @var The single instance of the class
11 + */
12 + protected static $_instance = null;
26 13
27 - /**
28 - * Extensions upgrade URL.
29 - *
30 - * @var string Default URL 'https://mainwp.com/'
31 - */
32 - private $upgrade_url = 'https://mainwp.com/';
14 + public static function instance() {
33 15
34 - /**
35 - * Extensions license renewal URL.
36 - *
37 - * @var string Default 'https://mainwp.com/my-account'
38 - */
39 - private $renew_license_url = 'https://mainwp.com/my-account';
16 + if ( is_null( self::$_instance ) ) {
17 + self::$_instance = new self();
18 + }
40 19
41 - /**
42 - * Protected static variable to hold the single instance of the class.
43 - *
44 - * @var mixed Default null
45 - */
46 - protected static $instance = null;
20 + return self::$_instance;
21 + }
47 22
48 - /**
49 - * MainWP installation domain name.
50 - *
51 - * @var string $domain Empty by default.
52 - */
53 - public $domain = '';
23 + /**
24 + * Cloning is forbidden.
25 + *
26 + * @since 1.2
27 + */
28 + private function __clone() {
54 29
55 - /**
56 - * Return the single instance of the class.
57 - *
58 - * @return mixed $instance The single instance of the class.
59 - */
60 - public static function instance() {
30 + }
61 31
62 - if ( is_null( static::$instance ) ) {
63 - static::$instance = new self();
64 - }
32 + /**
33 + * Unserializing instances of this class is forbidden.
34 + *
35 + * @since 1.2
36 + */
37 + private function __wakeup() {
65 38
66 - return static::$instance;
67 - }
39 + }
68 40
69 - /**
70 - * Cloning is forbidden.
71 - *
72 - * @since 1.2
73 - */
74 - public function __clone() {
75 - }
41 + public function __construct() {
42 + $this->domain = str_ireplace( array( 'http://', 'https://' ), '', home_url() );
43 + }
76 44
77 - /**
78 - * Un-serializing instances of this class is forbidden.
79 - *
80 - * @since 1.2
81 - */
82 - public function __wakeup() {
83 - }
45 + public function get_domain() {
46 + return $this->domain;
47 + }
84 48
85 - /**
86 - * MainWP_Api_Manager constructor.
87 - *
88 - * Run each time the class is called.
89 - *
90 - * Replace HTTP protocol to HTTPS.
91 - */
92 - public function __construct() {
93 - $this->domain = str_ireplace( array( 'http://', 'https://' ), '', home_url() );
94 - }
49 + public function getUpgradeUrl() {
50 + $url = apply_filters( 'mainwp_api_manager_upgrade_url', $this->upgrade_url );
51 + return $url;
52 + }
95 53
96 - /**
97 - * Get Upgrade URL.
98 - *
99 - * @return string Activation upgrade URL.
100 - */
101 - public function get_upgrade_url() {
102 - return apply_filters( 'mainwp_api_manager_upgrade_url', $this->upgrade_url );
103 - }
104 54
105 - /**
106 - * Get domain URL.
107 - *
108 - * @return string domain URL.
109 - */
110 - public function get_domain() {
111 - return $this->domain;
112 - }
113 -
114 - /**
115 - * Get activation info.
116 - *
117 - * @param mixed $ext_key extension key.
118 - *
119 - * @return mixed get_option() get activation information.
120 - */
121 55 public function get_activation_info( $ext_key ) {
122 - if ( empty( $ext_key ) ) {
56 + if (empty($ext_key))
123 57 return array();
124 - }
125 58
126 - $info = get_option( $ext_key . '_APIManAdder' );
59 + return get_option( $ext_key . '_APIManAdder' );
60 + }
127 61
128 - // MWP-1546: per-extension license keys were historically stored as
129 - // plaintext inside the option array's 'api_key' field. New writes
130 - // (set_activation_info below) replace that field with a
131 - // {encrypted_val, file_key} envelope produced by the
132 - // mainwp_encrypt_key_value filter (MainWP_Keys_Manager). On read,
133 - // the matching mainwp_decrypt_key_value filter reverses the
134 - // envelope.
135 - //
136 - // Encrypt-on-first-read migration: if the stored row still carries
137 - // a plaintext api_key string (legacy installs upgraded from before
138 - // this change), rewrite it as the encrypted envelope right now.
139 - // Existing dashboards migrate transparently as each extension's
140 - // option is touched, without waiting for an unrelated activation
141 - // event. We persist via update_option directly rather than calling
142 - // set_activation_info to avoid churning the activations_cached
143 - // option on every legacy read.
144 - if ( is_array( $info ) && ! empty( $info['api_key'] ) && is_string( $info['api_key'] ) ) {
145 - $rewritten = static::encrypt_activation_info( $ext_key, $info );
146 - if ( is_array( $rewritten )
147 - && isset( $rewritten['api_key'] )
148 - && is_array( $rewritten['api_key'] )
149 - && ! empty( $rewritten['api_key']['encrypted_val'] ) ) {
150 - MainWP_Utility::update_option( $ext_key . '_APIManAdder', $rewritten );
151 - }
152 - }
153 -
154 - return static::decrypt_activation_info( $info );
155 - }
156 -
157 - /**
158 - * Reverse the api_key encryption applied by set_activation_info().
159 - *
160 - * Returns the input unchanged when api_key is missing, empty, or a
161 - * plaintext string (legacy format). Falls back to the original value
162 - * if the mainwp_decrypt_key_value filter cannot recover a string, so
163 - * a missing keyfile cannot orphan a license activation.
164 - *
165 - * @param mixed $info Raw option value as returned by get_option().
166 - * @return mixed Same shape as $info, with 'api_key' decrypted to plaintext.
167 - */
168 - public static function decrypt_activation_info( $info ) {
169 - if ( ! is_array( $info ) || empty( $info['api_key'] ) ) {
170 - return $info;
171 - }
172 - if ( ! is_array( $info['api_key'] ) ) {
173 - return $info; // Legacy plaintext string, no envelope to reverse.
174 - }
175 - if ( empty( $info['api_key']['encrypted_val'] ) ) {
176 - // Malformed envelope (array but missing encrypted_val). Drop the
177 - // unreadable value rather than returning the raw array; callers
178 - // (api-handler.php readers, the hooks filter) do not is_string-
179 - // guard the result and would forward the array to the licensing
180 - // API as http_build_query garbage. Mirrors the decrypt-failure
181 - // branch below.
182 - $info['api_key'] = '';
183 - return $info;
184 - }
185 - $decrypted = apply_filters( 'mainwp_decrypt_key_value', false, $info['api_key'], '' );
186 - if ( is_string( $decrypted ) && '' !== $decrypted ) {
187 - $info['api_key'] = $decrypted;
188 - } else {
189 - // Decrypt failed (e.g. missing keyfile). Drop the unreadable
190 - // ciphertext so callers see an empty string rather than the
191 - // raw envelope array, which they would treat as truthy and
192 - // forward to the licensing API as garbage.
193 - $info['api_key'] = '';
194 - }
195 - return $info;
196 - }
197 -
198 - /**
199 - * Store activation info.
200 - *
201 - * @param mixed $ext_key Extension key.
202 - * @param mixed $info Activation information.
203 - *
204 - * @return mixed Set activation info.
205 - * @uses \MainWP\Dashboard\MainWP_Utility::update_option()
206 - */
207 62 public function set_activation_info( $ext_key, $info ) {
208 63
209 - if ( empty( $ext_key ) ) {
64 + if (empty($ext_key))
210 65 return false;
211 - }
212 66
213 - // Clear cached of all activations to reload for next loading.
214 - update_option( 'mainwp_extensions_all_activation_cached', '' );
67 + update_option('mainwp_extensions_all_activation_cached', ''); // clear cached of all activations to reload for next loading
215 68
216 - // MWP-1546: encrypt the 'api_key' field at rest using the same
217 - // mainwp_encrypt_key_value filter that 3rd-party API keys use. Other
218 - // array members (activated_key, deactivate_checkbox, product_id,
219 - // instance_id, software_version, mainwp_version, product_item_id)
220 - // are not credentials and stay plaintext for backwards compatibility
221 - // with any reader that consumes them directly.
222 - $info = static::encrypt_activation_info( $ext_key, $info );
223 -
224 - // Codex follow-up: fail closed when encryption did not produce an
225 - // envelope. encrypt_activation_info() returns the input unchanged
226 - // when the mainwp_encrypt_key_value filter fails (missing keyfile,
227 - // un-writable uploads dir, etc.), which would leave api_key as a
228 - // plaintext string and silently downgrade this write back to the
229 - // pre-MWP-1546 leak path. Refuse the write and let the caller
230 - // surface the error rather than persisting plaintext credentials.
231 - if ( is_array( $info )
232 - && isset( $info['api_key'] )
233 - && is_string( $info['api_key'] )
234 - && '' !== $info['api_key'] ) {
235 - return false;
236 - }
237 -
238 69 return MainWP_Utility::update_option( $ext_key . '_APIManAdder', $info );
239 - }
70 + }
240 71
241 - /**
242 - * Encrypt the api_key field of an activation-info array via the
243 - * mainwp_encrypt_key_value filter (MainWP_Keys_Manager). Replaces the
244 - * plaintext string with the {encrypted_val, file_key} envelope.
245 - *
246 - * @param string $ext_key Extension slug; included in the keyfile prefix.
247 - * @param mixed $info Activation info as supplied by callers.
248 - * @return mixed Same shape as $info, with 'api_key' replaced by the
249 - * encryption envelope (or unchanged if encryption fails).
250 - */
251 - public static function encrypt_activation_info( $ext_key, $info ) {
252 - if ( ! is_array( $info ) ) {
253 - return $info;
254 - }
255 - if ( empty( $info['api_key'] ) || ! is_string( $info['api_key'] ) ) {
256 - return $info;
257 - }
258 - $prefix = 'extension_' . sanitize_key( $ext_key ) . '_';
259 - $envelope = apply_filters( 'mainwp_encrypt_key_value', false, $info['api_key'], $prefix, false );
260 - if ( is_array( $envelope ) && ! empty( $envelope['encrypted_val'] ) ) {
261 - $info['api_key'] = $envelope;
262 - }
263 - return $info;
264 - }
72 + public function license_key_activation( $api, $api_key, $api_email ) {
265 73
266 - /**
267 - * Remove activation info.
268 - *
269 - * @param mixed $ext_key Extension key.
270 - *
271 - * @return mixed Remove activation info.
272 - */
273 - public function remove_activation_info( $ext_key ) {
274 - if ( empty( $ext_key ) ) {
275 - return;
276 - }
74 + $options = $this->get_activation_info( $api );
277 75
278 - $options = $this->get_activation_info( $ext_key );
279 - if ( ! is_array( $options ) ) {
280 - $options = array();
281 - }
76 + if ( !is_array( $options ) ) {
77 + $options = array();
78 + }
79 + $current_api_key = isset( $options[ 'api_key' ] ) ? $options[ 'api_key' ] : '';
80 + $current_activation_email = isset( $options[ 'activation_email' ] ) ? $options[ 'activation_email' ] : '';
81 + $activation_status = isset( $options[ 'activated_key' ] ) ? $options[ 'activated_key' ] : '';
282 82
283 - if ( isset( $options['api_key'] ) ) {
284 - $options['api_key'] = '';
285 - }
286 - if ( isset( $options['activated_key'] ) ) {
287 - $options['activated_key'] = 'Deactivated';
288 - }
289 - $this->set_activation_info( $ext_key, $options );
290 - }
83 + if ( $activation_status == 'Deactivated' || $activation_status == '' || $api_key == '' || $api_email == '' || $current_api_key != $api_key ) {
84 + if ( $current_api_key != $api_key ) {
85 + $reset = $this->replace_license_key( array(
86 + 'email' => $current_activation_email,
87 + 'licence_key' => $current_api_key,
88 + 'product_id' => $options[ 'product_id' ],
89 + 'instance' => $options[ 'instance_id' ],
90 + 'platform' => $this->domain,
91 + ) );
92 + if ( !$reset ) {
93 + return array( 'error' => __( 'The license could not be deactivated.', 'mainwp' ) );
94 + }
95 + }
291 96
292 - /**
293 - * Check API Key & API Email again MainWP Servers.
294 - *
295 - * @param array $api_slug Extension activation info.
296 - * @param string $api_key API license key.
297 - *
298 - * @return array Activation info.
299 - *
300 - * @uses \MainWP\Dashboard\MainWP_Api_Manager_Key::activate()
301 - * @uses \MainWP\Dashboard\MainWP_Utility::update_option()
302 - */
303 - public function license_key_activation( $api_slug, $api_key ) { // phpcs:ignore -- NOSONAR - complex.
97 + $return = array();
304 98
305 - $options = $this->get_activation_info( $api_slug );
99 + $args = array(
100 + 'email' => $api_email,
101 + 'licence_key' => $api_key,
102 + 'product_id' => $options[ 'product_id' ],
103 + 'instance' => $options[ 'instance_id' ],
104 + 'software_version' => $options[ 'software_version' ],
105 + 'platform' => $this->domain,
106 + );
306 107
307 - if ( ! is_array( $options ) ) {
308 - $options = array();
309 - }
310 - $current_api_key = isset( $options['api_key'] ) ? $options['api_key'] : '';
311 - $activation_status = isset( $options['activated_key'] ) ? $options['activated_key'] : '';
108 + $activate_results = json_decode( MainWP_Api_Manager_Key::instance()->activate( $args ), true );
312 109
313 - if ( 'Deactivated' === $activation_status || '' === $activation_status || '' === $api_key || $current_api_key !== $api_key ) {
314 - if ( $current_api_key !== $api_key ) {
315 - $reset = $this->replace_license_key(
316 - array(
317 - 'api_key' => $api_key,
318 - 'product_id' => $options['product_id'],
319 - 'instance' => $options['instance_id'],
320 - 'software_version' => $options['software_version'],
321 - 'software_slug' => $api_slug,
322 - )
323 - );
324 - if ( ! $reset ) {
325 - return array( 'error' => esc_html__( 'The license could not be deactivated.', 'mainwp' ) );
326 - }
327 - }
110 + if ( $activate_results[ 'activated' ] == true ) {
111 + $return[ 'result' ] = 'SUCCESS';
112 + $mess = isset( $activate_results[ 'message' ] ) ? $activate_results[ 'message' ] : '';
113 + $return[ 'message' ] = __( 'The extension has been activated. ', 'mainwp' ) . $mess;
114 + $options[ 'api_key' ] = $api_key;
115 + $options[ 'activation_email' ] = $api_email;
116 + $options[ 'activated_key' ] = 'Activated';
117 + $options[ 'deactivate_checkbox' ] = 'off';
118 + }
328 119
329 - $return = array();
120 + if ( $activate_results == false ) {
121 + $apisslverify = get_option( 'mainwp_api_sslVerifyCertificate' );
122 + if ( $apisslverify == 1 ) {
123 + MainWP_Utility::update_option( 'mainwp_api_sslVerifyCertificate', 0 );
124 + $return[ 'retry_action' ] = 1;
125 + } else {
126 + $return[ 'error' ] = __( 'Connection failed to the License Key API server. Try again later.', 'mainwp' );
127 + }
128 + $options[ 'api_key' ] = '';
129 + $options[ 'activation_email' ] = '';
130 + $options[ 'activated_key' ] = 'Deactivated';
131 + }
330 132
331 - $args = array(
332 - 'api_key' => $api_key,
333 - 'product_id' => $options['product_id'],
334 - 'instance' => $options['instance_id'],
335 - 'software_version' => $options['software_version'],
336 - 'object' => $this->domain,
337 - 'software_slug' => $api_slug,
338 - );
133 + $error = $this->check_response_for_api_errors( $activate_results );
134 + if ( !empty( $error ) )
135 + $return[ 'error' ] = $error;
339 136
340 - $activate_results = MainWP_Api_Manager_Key::instance()->activate( $args );
341 - if ( ! empty( $activate_results ) ) {
342 - $activate_results = json_decode( $activate_results, true );
343 - } else {
344 - $activate_results = array();
345 - }
137 + $this->set_activation_info( $api, $options );
346 138
347 - if ( true === $activate_results['activated'] ) {
348 - $return['result'] = 'SUCCESS';
349 - $mess = isset( $activate_results['message'] ) ? $activate_results['message'] : '';
350 - $return['message'] = esc_html__( 'The extension has been activated. ', 'mainwp' ) . $mess;
351 - $options['api_key'] = $api_key;
352 - $options['activated_key'] = 'Activated';
353 - $options['deactivate_checkbox'] = 'off';
354 - $options['mainwp_version'] = MainWP_System::instance()->get_dashboard_version();
355 - MainWP_Utility::instance()->get_set_deactivated_licenses_alerted( $api_slug, 0, 'set' ); // so next time deactived it will alerted.
356 - }
139 + return $return;
140 + } else {
141 + return array( 'result' => 'SUCCESS' );
142 + }
143 + }
357 144
358 - if ( false === $activate_results ) {
359 - $apisslverify = get_option( 'mainwp_api_sslVerifyCertificate' );
360 - if ( 1 === $apisslverify ) {
361 - MainWP_Utility::update_option( 'mainwp_api_sslVerifyCertificate', 0 );
362 - $return['retry_action'] = 1;
363 - } else {
364 - $return['error'] = esc_html__( 'Connection failed to the License Key API server. Try again later.', 'mainwp' );
365 - }
366 - $options['api_key'] = '';
367 - $options['activated_key'] = 'Deactivated';
368 - }
145 + // Deactivate the current license key before activating the new license key
146 + private function replace_license_key( $args ) {
147 + $reset = MainWP_Api_Manager_Key::instance()->deactivate( $args ); // reset license key activation
369 148
370 - $error = $this->check_response_for_api_errors( $activate_results );
371 - if ( ! empty( $error ) ) {
372 - $return['error'] = $error;
373 - }
149 + if ( $reset == true ) {
150 + return true;
151 + }
152 + }
374 153
375 - // MWP-1546 follow-up: surface the fail-closed write so the user is not
376 - // told the activation succeeded when only the upstream half landed.
377 - // The license slot was already consumed at mainwp.com; without the
378 - // local persist the dashboard will offer to re-activate and burn a
379 - // second slot. The encrypt filter only fails on broken installs
380 - // (missing keyfile, un-writable uploads/mainwp/pk/), but when it
381 - // does the operator needs to know.
382 - if ( false === $this->set_activation_info( $api_slug, $options ) ) {
383 - $return['error'] = esc_html__( 'License activated upstream but local state could not be saved. Check uploads/mainwp/pk/ permissions and try the activation again.', 'mainwp' );
384 - }
154 + public function license_key_deactivation( $api ) {
385 155
386 - return $return;
387 - } else {
388 - return array( 'result' => 'SUCCESS' );
389 - }
390 - }
156 + $options = $this->get_activation_info( $api );
157 + if ( !is_array( $options ) ) {
158 + $options = array();
159 + }
391 160
392 - /**
393 - * Deactivate the current license key before activating the new license key.
394 - *
395 - * @param array $args Request arguments.
396 - *
397 - * @return bool True on success, false on failure.
398 - *
399 - * @uses \MainWP\Dashboard\MainWP_Api_Manager_Key::deactivate()
400 - */
401 - private function replace_license_key( $args ) {
402 - $reset = MainWP_Api_Manager_Key::instance()->deactivate( $args ); // reset license key activation.
161 + $activation_status = isset( $options[ 'activated_key' ] ) ? $options[ 'activated_key' ] : '';
162 + $current_api_key = isset( $options[ 'api_key' ] ) ? $options[ 'api_key' ] : '';
163 + $current_activation_email = isset( $options[ 'activation_email' ] ) ? $options[ 'activation_email' ] : '';
403 164
404 - if ( true === $reset ) {
405 - return true;
406 - }
407 - }
165 + $return = array();
408 166
409 - /**
410 - * Deactivate license Key.
411 - *
412 - * @param array $api_slug Extension activation info.
413 - * @param array $api_key Extension activation api key.
414 - *
415 - * @return array Deactivation info.
416 - *
417 - * @uses \MainWP\Dashboard\MainWP_Api_Manager_Key::deactivate()
418 - */
419 - public function license_key_deactivation( $api_slug, $api_key ) {
167 + if ( $activation_status == 'Activated' && $current_api_key != '' && $current_activation_email != '' ) {
168 + $activate_results = MainWP_Api_Manager_Key::instance()->deactivate( array(
169 + 'email' => $current_activation_email,
170 + 'licence_key' => $current_api_key,
171 + 'product_id' => $options[ 'product_id' ],
172 + 'instance' => $options[ 'instance_id' ],
173 + 'platform' => $this->domain,
174 + ) ); // reset license key activation
420 175
421 - $options = $this->get_activation_info( $api_slug );
422 - if ( ! is_array( $options ) ) {
423 - $options = array();
424 - }
176 + $activate_results = json_decode( $activate_results, true );
177 + if ( $activate_results['deactivated'] == true || (isset( $activate_results['activated'] ) && $activate_results['activated'] == 'inactive')) {
178 + $options[ 'api_key' ] = '';
179 + $options[ 'activation_email' ] = '';
180 + $options[ 'activated_key' ] = 'Deactivated';
181 + $options[ 'deactivate_checkbox' ] = 'on';
182 + $return[ 'result' ] = 'SUCCESS';
183 + $return[ 'activations_remaining' ] = $activate_results[ 'activations_remaining' ];
184 + }
425 185
426 - $activation_status = isset( $options['activated_key'] ) ? $options['activated_key'] : '';
186 + $error = $this->check_response_for_api_errors( $activate_results );
187 + if ( !empty( $error ) )
188 + $return[ 'error' ] = $error;
427 189
428 - if ( empty( $api_key ) ) {
429 - $options['api_key'] = '';
430 - $this->set_activation_info( $api_slug, $options );
431 - }
190 + $this->set_activation_info( $api, $options );
432 191
433 - $return = array();
192 + return $return;
193 + }
194 + update_option('mainwp_extensions_all_activation_cached', ''); // to fix: clear cached of all activations to reload for next loading
195 + return array( 'result' => 'SUCCESS' );
196 + }
434 197
435 - if ( 'Activated' === $activation_status && '' !== $api_key ) {
436 - $activate_results = MainWP_Api_Manager_Key::instance()->deactivate(
437 - array(
438 - 'product_id' => $options['product_id'],
439 - 'instance' => $options['instance_id'],
440 - 'api_key' => $api_key,
441 - 'object' => $this->domain,
442 - 'software_version' => $options['software_version'],
443 - 'software_slug' => $api_slug,
444 - )
445 - ); // reset license key activation.
198 + public function test_login_api( $username, $password ) {
199 + if ( empty( $username ) || empty( $password ) ) {
200 + return false;
201 + }
446 202
447 - $activate_results = json_decode( $activate_results, true );
448 - if ( isset( $activate_results['deactivated'] ) && true === $activate_results['deactivated'] ) {
449 - $options['api_key'] = '';
450 - $options['activated_key'] = 'Deactivated';
451 - $options['deactivate_checkbox'] = 'on';
452 - $return['result'] = 'SUCCESS';
453 - $return['activations_remaining'] = $activate_results['activations_remaining'];
454 - }
203 + return MainWP_Api_Manager_Key::instance()->testloginapi( array(
204 + 'username' => $username,
205 + 'password' => $password,
206 + ) );
207 + }
455 208
456 - $error = $this->check_response_for_api_errors( $activate_results );
457 - if ( ! empty( $error ) ) {
458 - $return['error'] = $error;
459 - $options['api_key'] = '';
460 - $options['activated_key'] = 'Deactivated';
461 - }
209 + public function purchase_software( $username, $password, $productId ) {
210 + if ( empty( $username ) || empty( $password ) ) {
211 + return false;
212 + }
462 213
463 - // MWP-1546 follow-up: surface the fail-closed write. The slot was
464 - // already released at mainwp.com; without the local persist the
465 - // dashboard would still display the extension as Activated.
466 - if ( false === $this->set_activation_info( $api_slug, $options ) ) {
467 - $return['error'] = esc_html__( 'License deactivated upstream but local state could not be cleared. Check uploads/mainwp/pk/ permissions.', 'mainwp' );
468 - }
469 -
470 - return $return;
471 - }
472 - // to fix: clear cached of all activations to reload for next loading.
473 - update_option( 'mainwp_extensions_all_activation_cached', '' );
474 - return array( 'result' => 'SUCCESS' );
214 + return MainWP_Api_Manager_Key::instance()->purchasesoftware( array(
215 + 'username' => $username,
216 + 'password' => $password,
217 + 'product_id' => $productId
218 + ) );
475 219 }
476 220
477 - /**
478 - * Test the users MainWP.com Login details against MainWP Server.
479 - *
480 - * @param string $api_key MainWP api key.
481 - *
482 - * @return mixed Login test result.
483 - *
484 - * @uses \MainWP\Dashboard\MainWP_Api_Manager_Key::verify_api_key()
485 - */
486 - public function verify_mainwp_api( $api_key ) {
487 - if ( empty( $api_key ) ) {
488 - return false;
489 - }
221 + public function get_purchased_software( $username, $password, $productId = "", $no_register = false ) {
222 + if ( empty( $username ) || empty( $password ) ) {
223 + return false;
224 + }
490 225
491 - return MainWP_Api_Manager_Key::instance()->verify_api_key(
492 - array(
493 - 'api_key' => $api_key,
494 - )
495 - );
496 - }
226 + return MainWP_Api_Manager_Key::instance()->getpurchasedsoftware( array(
227 + 'username' => $username,
228 + 'password' => $password,
229 + 'product_id' => $productId,
230 + 'noauth' => $no_register ? 1 : 0
231 + ) );
232 + }
497 233
234 + public function grab_license_key( $api, $username, $password ) {
498 235
499 - /**
500 - * Check if the user purchased the software.
501 - *
502 - * @param string $productId extension (product) ID.
503 - *
504 - * @return mixed purchase_software() purchase extensions.
505 - *
506 - * @uses \MainWP\Dashboard\MainWP_Api_Manager_Key::purchase_software()
507 - */
508 - public function purchase_software( $productId ) {
509 - return MainWP_Api_Manager_Key::instance()->purchase_software(
510 - array(
511 - 'product_id' => $productId,
512 - )
513 - );
514 - }
236 + $options = $this->get_activation_info( $api );
237 + if ( !is_array( $options ) ) {
238 + $options = array();
239 + }
240 + $activation_status = isset( $options[ 'activated_key' ] ) ? $options[ 'activated_key' ] : '';
515 241
516 - /**
517 - * Get users purchased extensions.
518 - *
519 - * @param string $api_key api key.
520 - * @param string $productId extension (product) ID.
521 - * @param bool $no_register registration request.
522 - *
523 - * @return array Purchased extensions.
524 - *
525 - * @uses \MainWP\Dashboard\MainWP_Api_Manager_Key::get_purchased_software()
526 - */
527 - public function get_purchased_extension( $api_key, $productId = '', $no_register = false ) {
528 - if ( empty( $api_key ) ) {
529 - return false;
530 - }
242 + $api_key = isset( $options[ 'api_key' ] ) ? $options[ 'api_key' ] : '';
243 + $api_email = isset( $options[ 'activation_email' ] ) ? $options[ 'activation_email' ] : '';
531 244
532 - return MainWP_Api_Manager_Key::instance()->get_purchased_software(
533 - array(
534 - 'product_id' => $productId,
535 - 'api_key' => $api_key,
536 - 'noauth' => $no_register ? 1 : 0,
537 - )
538 - );
539 - }
245 + if ( $activation_status == 'Deactivated' || $activation_status == '' || $api_key == '' || $api_email == '' ) {
246 + $return = array();
247 + if ( $username != '' && $password != '' ) {
540 248
541 - /**
542 - * Grab users associate MainWP License key for the selected Extension.
543 - *
544 - * @param array $api_slug Extension activation info.
545 - * @param string $master_api_key MainWP master api key.
546 - *
547 - * @return mixed Activation info.
548 - *
549 - * @uses \MainWP\Dashboard\MainWP_Api_Manager_Key::grab_api_key()
550 - */
551 - public function grab_license_key( $api_slug, $master_api_key ) { // phpcs:ignore -- NOSONAR - Current complexity is the only way to achieve desired results, pull request solutions appreciated.
249 + $args = array(
250 + 'username' => $username,
251 + 'password' => $password,
252 + 'product_id' => isset( $options[ 'product_id' ] ) ? $options[ 'product_id' ] : '',
253 + 'instance' => isset( $options[ 'instance_id' ] ) ? $options[ 'instance_id' ] : '',
254 + 'software_version' => isset( $options[ 'software_version' ] ) ? $options[ 'software_version' ] : '',
255 + 'platform' => $this->domain,
256 + );
552 257
553 - $options = $this->get_activation_info( $api_slug );
554 - if ( ! is_array( $options ) ) {
555 - $options = array();
556 - }
557 - $activation_status = isset( $options['activated_key'] ) ? $options['activated_key'] : '';
558 - $api_key = isset( $options['api_key'] ) ? $options['api_key'] : '';
258 + $activate_results = json_decode( MainWP_Api_Manager_Key::instance()->grabapikey( $args ), true );
259 + $options[ 'api_key' ] = '';
260 + $options[ 'activation_email' ] = '';
261 + $options[ 'activated_key' ] = 'Deactivated';
559 262
560 - if ( ! isset( $options['product_item_id'] ) ) {
561 - $options['product_item_id'] = 0; // to compatible.
562 - }
263 + if ( is_array( $activate_results ) && isset( $activate_results[ 'activated' ] ) && ( $activate_results[ 'activated' ] == true ) && !empty( $activate_results[ 'api_key' ] ) ) {
264 + $return[ 'result' ] = 'SUCCESS';
265 + $mess = isset( $activate_results[ 'message' ] ) ? $activate_results[ 'message' ] : '';
266 + $return[ 'message' ] = __( 'Extension activated. ', 'mainwp' ) . $mess;
267 + $options[ 'api_key' ] = $return[ 'api_key' ] = $activate_results[ 'api_key' ];
268 + $options[ 'activation_email' ] = $return[ 'activation_email' ] = $activate_results[ 'activation_email' ];
269 + $options[ 'activated_key' ] = 'Activated';
270 + $options[ 'deactivate_checkbox' ] = 'off';
271 + } else {
563 272
564 - if ( 'Deactivated' === $activation_status || '' === $activation_status || '' === $api_key || empty( $options['product_item_id'] ) ) {
565 - $return = array();
566 - if ( ! empty( $master_api_key ) ) {
567 - $args = array(
568 - 'api_key' => $master_api_key,
569 - 'product_id' => isset( $options['product_id'] ) ? $options['product_id'] : '',
570 - 'instance' => isset( $options['instance_id'] ) ? $options['instance_id'] : '',
571 - 'software_version' => isset( $options['software_version'] ) ? $options['software_version'] : '',
572 - 'object' => $this->domain,
573 - 'software_slug' => $api_slug,
574 - );
273 + if ( $activate_results == false ) {
274 + $return[ 'error' ] = __( 'Connection with the API license server could not be established. Please, try again later.', "mainwp" );
275 + } else if ( isset( $activate_results[ 'error' ] ) ) {
276 + $return[ 'error' ] = $activate_results[ 'error' ];
277 + } else if ( empty( $activate_results[ 'api_key' ] ) ) {
278 + $return[ 'error' ] = __( 'License key could not be found.', 'mainwp' );
279 + } else {
280 + $return[ 'error' ] = __( 'An undefined error occurred. Please try again later or contact MainWP Support.', 'mainwp' );
281 + }
282 + }
575 283
576 - $activate_results = MainWP_Api_Manager_Key::instance()->grab_api_key( $args );
577 - if ( ! empty( $activate_results ) ) {
578 - $activate_results = json_decode( $activate_results, true );
579 - } else {
580 - $activate_results = array();
581 - }
284 + $error = $this->check_response_for_api_errors( $activate_results );
285 + if ( !empty( $error ) )
286 + $return[ 'error' ] = $error;
582 287
583 - $options['api_key'] = '';
584 - $options['activated_key'] = 'Deactivated';
288 + $this->set_activation_info( $api, $options );
585 289
586 - if ( ! isset( $options['product_item_id'] ) ) {
587 - $options['product_item_id'] = 0; // to compatible.
588 - }
290 + return $return;
291 + } else {
292 + return array( 'error' => __( 'Username and Password are required in order to grab extensions API keys.', 'mainwp' ) );
293 + }
294 + }
589 295
590 - if ( is_array( $activate_results ) && isset( $activate_results['activated'] ) && ( true === $activate_results['activated'] ) && ! empty( $activate_results['api_key'] ) ) {
591 - $return['result'] = 'SUCCESS';
592 - $mess = isset( $activate_results['message'] ) ? $activate_results['message'] : '';
593 - $return['message'] = esc_html__( 'Extension activated. ', 'mainwp' ) . $mess;
594 - $options['api_key'] = $activate_results['api_key'];
595 - $return['api_key'] = $activate_results['api_key'];
596 - $options['activated_key'] = 'Activated';
597 - $options['product_item_id'] = isset( $activate_results['product_item_id'] ) ? intval( $activate_results['product_item_id'] ) : 0;
598 - $options['deactivate_checkbox'] = 'off';
599 - } elseif ( false === $activate_results ) {
600 - $return['error'] = esc_html__( 'Connection with the API license server could not be established. Please, try again later.', 'mainwp' );
601 - } elseif ( isset( $activate_results['error'] ) ) {
602 - $return['error'] = $activate_results['error'];
603 - } elseif ( empty( $activate_results['api_key'] ) ) {
604 - $return['error'] = esc_html__( 'License key could not be found.', 'mainwp' );
605 - } else {
606 - $return['error'] = esc_html__( 'An undefined error occurred. Please try again later.', 'mainwp' );
607 - }
296 + return array( 'result' => 'SUCCESS' );
297 + }
608 298
609 - $error = $this->check_response_for_api_errors( $activate_results );
610 - if ( ! empty( $error ) ) {
611 - $return['error'] = $error;
612 - }
299 + public function check_response_for_api_errors( $response ) {
300 + if ( !is_array( $response ) || !isset( $response[ 'code' ] ) )
301 + return false;
613 302
614 - // MWP-1546 follow-up: surface the fail-closed write. The grab
615 - // call may have produced a fresh license key upstream; if the
616 - // local persist fails the dashboard would lose track of it
617 - // entirely.
618 - if ( false === $this->set_activation_info( $api_slug, $options ) ) {
619 - $return['error'] = esc_html__( 'License retrieved upstream but local state could not be saved. Check uploads/mainwp/pk/ permissions and try again.', 'mainwp' );
303 + $error = '';
304 + switch ( $response[ 'code' ] ) {
305 + case '100':
306 + $error = __( 'Invalid request! Please try to deactivate and re-activate the extension on the WP > Plugins page and try to activate API key again.', 'mainwp' );
307 + break;
308 + case '102':
309 + $error = __( 'Activation error! Download permission for this product could not be found.', 'mainwp' );
310 + break;
311 + case '101':
312 + $error = __( 'Activation error! Matching API key could not be found.', 'mainwp' );
313 + break;
314 + case '103':
315 + case '104':
316 + $error = __( 'Invalid Instance ID! Please try to deactivate and re-activate the extension on the WP > Plugins page and try to activate API key again.', 'mainwp' );
317 + break;
318 + case '105':
319 + case '106':
320 + $error = isset( $response[ 'error' ] ) ? $response[ 'error' ] : '';
321 + $info = isset( $response[ 'additional info' ] ) ? ' ' . $response[ 'additional info' ] : '';
322 + $error = $error . $info;
323 + break;
324 + case '900' :
325 + $error = __( 'Your membership is on hold. Reactivate your membership to activate MainWP extensions', 'mainwp' );
326 + break;
327 + case '901' :
328 + $error = __( 'Your membership has been canceled. Reactivate your membership to activate MainWP extensions', 'mainwp' );
329 + break;
330 + case '902' :
331 + $error = __( 'Your membership has expired. Reactivate your membership to activate MainWP extensions', 'mainwp' );
332 + break;
620 333 }
621 -
622 - return $return;
623 - } else {
624 - return array( 'error' => esc_html__( 'MainWP API key are required in order to grab extensions API keys.', 'mainwp' ) );
334 + return $error;
625 335 }
626 - }
627 336
628 - return array( 'result' => 'SUCCESS' );
629 - }
337 + public function check_response_for_intall_errors( $response, $software_title = "" ) {
338 + if ( !is_array( $response ) || !isset( $response[ 'error' ] ) )
339 + return false;
630 340
631 - /**
632 - * Check if $response contains any api errors.
633 - *
634 - * @param array $response Response array.
635 - *
636 - * @return string $error Error message.
637 - */
638 - public function check_response_for_api_errors( $response ) { //phpcs:ignore -- complex.
639 - if ( ! is_array( $response ) || ! isset( $response['code'] ) ) {
640 - return false;
641 - }
341 + switch ( $response[ 'error' ] ) {
342 + case 'subscription_on_hold':
343 + return __( 'Your membership is on hold. Reactivate your membership to install MainWP extensions.', 'mainwp' );
344 + break;
345 + case 'subscription_cancelled':
346 + return __( 'Your membership has been canceled. Reactivate your membership to install MainWP extensions.', 'mainwp' );
347 + break;
348 + case 'subscription_expired':
349 + return __( 'Your membership has expired. Reactivate your membership to install MainWP extensions.', 'mainwp' );
350 + break;
351 + default : //download_revoked
352 + return sprintf( __( 'Download permission for %s has been revoked possibly due to a license key or membership expiring. You can reactivate or purchase a license key from your account <a href="%s" target="_blank">dashboard</a>.', 'mainwp' ), $software_title, $this->renew_license_url );
353 + break;
354 + }
355 + return false;
356 + }
642 357
643 - if ( isset( $response['error'] ) ) {
644 - return $response['error'];
645 - }
358 + public function update_check( $args ) {
359 + $args[ 'domain' ] = $this->domain;
646 360
647 - $error = '';
648 - switch ( $response['code'] ) {
649 - case '100':
650 - $error = esc_html__( 'Activation error! Please try to deactivate and re-activate the extension on the WP > Plugins page and try to activate API key again.', 'mainwp' );
651 - break;
652 - case '102':
653 - $error = esc_html__( 'Activation error! Download permission for this product could not be found.', 'mainwp' );
654 - break;
655 - case '101':
656 - $error = esc_html__( 'Activation error! Matching API key could not be found.', 'mainwp' );
657 - break;
658 - case '103':
659 - case '104':
660 - $error = esc_html__( 'Invalid Instance ID! Please try to deactivate and re-activate the extension on the WP > Plugins page and try to activate API key again.', 'mainwp' );
661 - break;
662 - case '105':
663 - case '106':
664 - $error = isset( $response['error'] ) ? $response['error'] : '';
665 - $info = isset( $response['additional info'] ) ? ' ' . $response['additional info'] : '';
666 - $error = $error . $info;
667 - break;
668 - case '900':
669 - $error = esc_html__( 'Your membership is on hold. Reactivate your membership to activate MainWP extensions', 'mainwp' );
670 - break;
671 - case '901':
672 - $error = esc_html__( 'Your membership has been canceled. Reactivate your membership to activate MainWP extensions', 'mainwp' );
673 - break;
674 - case '902':
675 - $error = esc_html__( 'Your membership has expired. Reactivate your membership to activate MainWP extensions', 'mainwp' );
676 - break;
677 - default:
678 - break;
679 - }
680 - return $error;
681 - }
361 + return MainWP_Api_Manager_Plugin_Update::instance()->update_check( $args );
362 + }
682 363
683 - /**
684 - * Check if $response contains any install errors.
685 - *
686 - * @param array $response Response array.
687 - * @param string $software_title Extension title.
688 - *
689 - * @return string $return Installation Error messages.
690 - */
691 - public function check_response_for_intall_errors( $response, $software_title = '' ) {
692 - if ( ! is_array( $response ) || ! isset( $response['error'] ) ) {
693 - return false;
694 - }
364 + public function request_plugin_information( $args ) {
365 + $args[ 'domain' ] = $this->domain;
695 366
696 - $return = false;
697 - switch ( $response['error'] ) {
698 - case 'subscription_on_hold':
699 - $return = esc_html__( 'Your membership is on hold. Reactivate your membership to install MainWP extensions.', 'mainwp' );
700 - break;
701 - case 'subscription_cancelled':
702 - $return = esc_html__( 'Your membership has been canceled. Reactivate your membership to install MainWP extensions.', 'mainwp' );
703 - break;
704 - case 'subscription_expired':
705 - $return = esc_html__( 'Your membership has expired. Reactivate your membership to install MainWP extensions.', 'mainwp' );
706 - break;
707 - default: // download_revoked.
708 - /* translators: 1: Extension/software title, 2: URL to account dashboard */
709 - $return = sprintf( esc_html__( 'Download permission for %1$s has been revoked possibly due to a license key or membership expiring. You can reactivate or purchase a license key from your account <a href="%2$s" target="_blank">dashboard</a>.', 'mainwp' ), $software_title, $this->renew_license_url );
710 - break;
711 - }
712 - return $return;
713 - }
367 + return MainWP_Api_Manager_Plugin_Update::instance()->request( $args );
368 + }
714 369
715 - /**
716 - * Request plugin information
717 - *
718 - * @param array $args Request arguments.
719 - *
720 - * @return array Plugin info.
721 - *
722 - * @uses MainWP_Api_Manager_Plugin_Update::request()
723 - */
724 - public function request_extension_information( $args ) {
725 - return MainWP_Api_Manager_Plugin_Update::instance()->request( $args );
726 - }
727 370 }
728 371
729 -// End of class.
372 +// End of class