PluginProbe
MainWP Dashboard: Self-hosted WordPress Management for Agencies / trunk
MainWP Dashboard: Self-hosted WordPress Management for Agencies vtrunk
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
mainwp / class / class-mainwp-api-manager.php

class-mainwp-api-manager.php in MainWP Dashboard: Self-hosted WordPress Management for Agencies trunk, at class/class-mainwp-api-manager.php

730 lines 28.7 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
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
13 namespace MainWP\Dashboard;
14
15 // Exit if accessed directly.
16 if ( ! defined( 'ABSPATH' ) ) {
17 exit;
18 }
19
20 /**
21 * Class MainWP_Api_Manager
22 *
23 * @package MainWP\Dashboard
24 */
25 class MainWP_Api_Manager { // phpcs:ignore Generic.Classes.OpeningBraceSameLine.ContentAfterBrace -- NOSONAR.
26
27 /**
28 * Extensions upgrade URL.
29 *
30 * @var string Default URL 'https://mainwp.com/'
31 */
32 private $upgrade_url = 'https://mainwp.com/';
33
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';
40
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;
47
48 /**
49 * MainWP installation domain name.
50 *
51 * @var string $domain Empty by default.
52 */
53 public $domain = '';
54
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() {
61
62 if ( is_null( static::$instance ) ) {
63 static::$instance = new self();
64 }
65
66 return static::$instance;
67 }
68
69 /**
70 * Cloning is forbidden.
71 *
72 * @since 1.2
73 */
74 public function __clone() {
75 }
76
77 /**
78 * Un-serializing instances of this class is forbidden.
79 *
80 * @since 1.2
81 */
82 public function __wakeup() {
83 }
84
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 }
95
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
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 public function get_activation_info( $ext_key ) {
122 if ( empty( $ext_key ) ) {
123 return array();
124 }
125
126 $info = get_option( $ext_key . '_APIManAdder' );
127
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 public function set_activation_info( $ext_key, $info ) {
208
209 if ( empty( $ext_key ) ) {
210 return false;
211 }
212
213 // Clear cached of all activations to reload for next loading.
214 update_option( 'mainwp_extensions_all_activation_cached', '' );
215
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 return MainWP_Utility::update_option( $ext_key . '_APIManAdder', $info );
239 }
240
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 }
265
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 }
277
278 $options = $this->get_activation_info( $ext_key );
279 if ( ! is_array( $options ) ) {
280 $options = array();
281 }
282
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 }
291
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.
304
305 $options = $this->get_activation_info( $api_slug );
306
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'] : '';
312
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 }
328
329 $return = array();
330
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 );
339
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 }
346
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 }
357
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 }
369
370 $error = $this->check_response_for_api_errors( $activate_results );
371 if ( ! empty( $error ) ) {
372 $return['error'] = $error;
373 }
374
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 }
385
386 return $return;
387 } else {
388 return array( 'result' => 'SUCCESS' );
389 }
390 }
391
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.
403
404 if ( true === $reset ) {
405 return true;
406 }
407 }
408
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 ) {
420
421 $options = $this->get_activation_info( $api_slug );
422 if ( ! is_array( $options ) ) {
423 $options = array();
424 }
425
426 $activation_status = isset( $options['activated_key'] ) ? $options['activated_key'] : '';
427
428 if ( empty( $api_key ) ) {
429 $options['api_key'] = '';
430 $this->set_activation_info( $api_slug, $options );
431 }
432
433 $return = array();
434
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.
446
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 }
455
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 }
462
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' );
475 }
476
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 }
490
491 return MainWP_Api_Manager_Key::instance()->verify_api_key(
492 array(
493 'api_key' => $api_key,
494 )
495 );
496 }
497
498
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 }
515
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 }
531
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 }
540
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.
552
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'] : '';
559
560 if ( ! isset( $options['product_item_id'] ) ) {
561 $options['product_item_id'] = 0; // to compatible.
562 }
563
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 );
575
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 }
582
583 $options['api_key'] = '';
584 $options['activated_key'] = 'Deactivated';
585
586 if ( ! isset( $options['product_item_id'] ) ) {
587 $options['product_item_id'] = 0; // to compatible.
588 }
589
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 }
608
609 $error = $this->check_response_for_api_errors( $activate_results );
610 if ( ! empty( $error ) ) {
611 $return['error'] = $error;
612 }
613
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' );
620 }
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' ) );
625 }
626 }
627
628 return array( 'result' => 'SUCCESS' );
629 }
630
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 }
642
643 if ( isset( $response['error'] ) ) {
644 return $response['error'];
645 }
646
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 }
682
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 }
695
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 }
714
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 }
728
729 // End of class.
730