PluginProbe ʕ •ᴥ•ʔ
Advanced Ads – Ad Manager & AdSense / 2.0.24
Advanced Ads – Ad Manager & AdSense v2.0.24
2.0.24 2.0.23 2.0.22 2.0.21 1.38.0 1.39.0 1.39.1 1.39.2 1.39.3 1.39.4 1.4.0 1.4.1 1.4.2 1.4.3 1.4.4 1.4.5 1.4.6 1.4.7 1.4.8 1.4.9 1.40.0 1.40.1 1.40.2 1.41.0 1.42.0 1.42.1 1.42.2 1.43.0 1.44.0 1.44.1 1.45.0 1.45.1 1.46.0 1.47.0 1.47.1 1.47.2 1.47.3 1.47.4 1.47.5 1.48.0 1.48.1 1.49.0 1.5.0 1.5.0.1 1.5.1 1.5.2 1.5.2.1 1.5.4 1.5.4.1 1.5.5 1.50.0 1.51.0 1.51.1 1.51.2 1.51.3 1.52.0 1.52.1 1.52.2 1.52.3 1.52.4 1.53.0 1.53.1 1.53.2 1.54.0 1.54.1 1.55.0 1.56.0 1.56.1 1.56.2 1.56.3 1.56.4 1.6 1.6.1 1.6.10 1.6.10.1 1.6.10.2 1.6.11 1.6.11.1 1.6.12 1.6.13 1.6.14 1.6.15 1.6.16 1.6.17 1.6.17.1 1.6.17.2 1.6.2 1.6.2.1 1.6.3 1.6.4 1.6.4.1 1.6.5 1.6.6 1.6.6.1 1.6.7 1.6.7.1 1.6.8 1.6.8.1 1.6.8.2 1.6.8.3 1.6.9 1.6.9.1 1.6.9.2 1.6.9.3 1.6.9.4 1.7 1.7.0.1 1.7.0.2 1.7.0.3 1.7.1 1.7.1.1 1.7.1.2 1.7.1.3 1.7.1.4 1.7.1.5 1.7.10 trunk 1.7.11 1.0.1 1.7.12 1.0.2 1.7.13 1.0.3 1.7.14 1.1.0 1.7.15 1.1.1 1.7.16 1.1.2 1.7.17 1.1.3 1.7.18 1.10 1.7.19 1.10.1 1.7.2 1.10.10 1.7.2.1 1.10.11 1.7.20 1.10.12 1.7.21 1.10.2 1.7.22 1.10.3 1.7.23 1.10.4 1.7.24 1.10.5 1.7.25 1.10.6 1.7.3 1.10.7 1.7.4 1.10.8 1.7.4.1 1.10.9 1.7.4.2 1.11 1.7.4.3 1.11.1 1.7.4.4 1.11.2 1.7.4.5 1.12 1.7.5 1.13 1.7.5.1 1.13.1 1.7.6 1.13.2 1.7.7 1.13.3 1.7.8 1.13.4 1.7.9 1.13.5 1.7.9.1 1.13.6 1.7.9.2 1.13.7 1.7.9.3 1.13.8 1.8 1.14 1.8.1 1.14.1 1.8.10 1.14.10 1.8.11 1.14.11 1.8.12 1.14.2 1.8.13 1.14.3 1.8.14 1.14.4 1.8.15 1.14.5 1.8.16 1.14.6 1.8.17 1.14.7 1.8.18 1.14.8 1.8.19 1.14.9 1.8.2 1.15 1.8.20 1.16 1.8.21 1.16.1 1.8.22 1.17 1.8.23 1.17.1 1.8.24 1.17.10 1.8.25 1.17.10-rc.1 1.8.26 1.17.11 1.8.27 1.17.12 1.8.28 1.17.12-rc.1 1.8.29 1.17.2 1.8.3 1.17.3 1.8.30 1.17.4 1.8.4 1.17.5 1.8.5 1.17.6 1.8.6 1.17.7 1.8.7 1.17.8 1.8.8 1.17.9 1.8.9 1.17.9-beta.1 1.9 1.18.0 2.0.0 1.19.0 2.0.1 1.19.1 2.0.10 1.2 2.0.11 1.2.1 2.0.12 1.2.2 2.0.13 1.2.3 2.0.14 1.2.4 2.0.15 1.2.5 2.0.16 1.2.6 2.0.17 1.2.7 2.0.18 1.20.0 2.0.19 1.20.0-rc.1 2.0.2 1.20.0-rc.2 2.0.20 1.20.1 2.0.3 1.20.2 2.0.4 1.20.3 2.0.5 1.21.0 2.0.6 1.21.1 2.0.7 1.22.0 2.0.8 1.22.1 2.0.9 1.22.2 1.23.0 1.23.1 1.23.2 1.24.0 1.24.1 1.24.2 1.25.0 1.25.1 1.26.0 1.27.0 1.28.0 1.29.0 1.29.1 1.3 1.3.1 1.3.10 1.3.11 1.3.12 1.3.13 1.3.14 1.3.15 1.3.16 1.3.17 1.3.18 1.3.2 1.3.3 1.3.4 1.3.5 1.3.6 1.3.7 1.3.8 1.3.9 1.30.0 1.30.1 1.30.2 1.30.2-rc.1 1.30.3 1.30.4 1.30.4-rc.1 1.30.5 1.31.0 1.31.1 1.32.0 1.32.0-rc.1 1.33.0 1.33.1 1.33.2 1.34.0 1.35.0 1.35.1 1.36.0 1.36.1 1.36.2 1.36.3 1.37.0 1.37.1 1.37.2
advanced-ads / admin / includes / class-licenses.php
advanced-ads / admin / includes Last commit date
ad-health-notices.php 4 weeks ago class-ad-network-ad-unit.php 5 months ago class-ad-network.php 1 year ago class-licenses.php 3 months ago class-notices.php 5 months ago class-overview-widgets.php 1 year ago class-plugins-screen-updates.php 2 months ago notices.php 5 months ago
class-licenses.php
688 lines
1 <?php // phpcs:ignoreFile
2 /**
3 * Handle add-on licenses
4 *
5 * @package AdvancedAds
6 * @author Advanced Ads <info@wpadvancedads.com>
7 * @since 1.x.x
8 */
9
10 use AdvancedAds\Constants;
11 use AdvancedAds\Utilities\Data;
12
13 defined( 'ABSPATH' ) || exit;
14
15 /**
16 * Handle add-on licenses
17 */
18 class Advanced_Ads_Admin_Licenses {
19 /**
20 * Advanced_Ads_Admin_Licenses constructor.
21 */
22 private function __construct() {
23 add_action( 'plugins_loaded', [ $this, 'wp_plugins_loaded' ] );
24
25 // todo: check if this is loaded late enough and all add-ons are registered already.
26 add_filter( 'upgrader_pre_download', [ $this, 'addon_upgrade_filter' ], 10, 3 );
27 }
28
29 /**
30 * Actions and filter available after all plugins are initialized
31 */
32 public function wp_plugins_loaded() {
33 add_action( 'http_api_debug', [ $this, 'update_license_after_version_info' ], 10, 5 );
34 }
35
36 /**
37 * Return an instance of this class.
38 *
39 * @return self object A single instance of this class.
40 */
41 public static function get_instance() {
42 static $instance;
43
44 // If the single instance hasn't been set, set it now.
45 if ( null === $instance ) {
46 $instance = new self();
47 }
48
49 return $instance;
50 }
51
52 /**
53 * Save license key
54 *
55 * @param string $addon string with add-on identifier.
56 * @param string $plugin_name name of the add-on.
57 * @param string $options_slug slug of the option in the database.
58 * @param string $license_key license key.
59 *
60 * @return string
61 * @since 1.2.0
62 */
63 public function activate_license( $addon = '', $plugin_name = '', $options_slug = '', $license_key = '' ) {
64 if ( '' === $addon || '' === $plugin_name || '' === $options_slug ) {
65 return __( 'Error while trying to register the license. Please contact support.', 'advanced-ads' );
66 }
67
68 $license_key = esc_attr( trim( $license_key ) );
69 if ( '' === $license_key ) {
70 return __( 'Please enter a valid license key', 'advanced-ads' );
71 }
72
73 if ( has_filter( 'advanced_ads_license_' . $options_slug ) ) {
74 return apply_filters( 'advanced_ads_license_' . $options_slug, false, __METHOD__, $plugin_name, $options_slug, $license_key );
75 }
76
77 /**
78 * We need to remove the mltlngg_get_url_translated filter added by Multilanguage by BestWebSoft, https://wordpress.org/plugins/multilanguage/
79 * it causes the URL to look much different than it originally is
80 * we are adding it again later
81 */
82 remove_filter( 'home_url', 'mltlngg_get_url_translated' );
83
84 $api_params = [
85 'edd_action' => 'activate_license',
86 'license' => $license_key,
87 'item_id' => Constants::ADDON_SLUGS_ID[ $options_slug ] ?? false,
88 'item_name' => rawurlencode( $plugin_name ),
89 'url' => home_url(),
90 ];
91
92 /**
93 * Re-add the filter removed from above
94 */
95 if ( function_exists( 'mltlngg_get_url_translated' ) ) {
96 add_filter( 'home_url', 'mltlngg_get_url_translated' );
97 }
98
99 // Call the custom API.
100 $response = wp_remote_post(
101 Constants::API_ENDPOINT,
102 [
103 'timeout' => 15,
104 'sslverify' => false,
105 'body' => $api_params,
106 ]
107 );
108
109 // show license debug output if constant is set.
110 if ( defined( 'ADVANCED_ADS_SHOW_LICENSE_RESPONSE' ) ) {
111 return '<p><strong>' . esc_html__( 'The license status does not change as long as ADVANCED_ADS_SHOW_LICENSE_RESPONSE is enabled in wp-config.php.', 'advanced-ads' ) . '</strong></p>' .
112 '<pre>' . print_r( $response, true ) . '</pre>'; // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_print_r
113 }
114
115 /**
116 * Send the user to our support when his request is blocked by our firewall
117 */
118 $error = $this->blocked_by_firewall( $response );
119 if ( $error ) {
120 return $error;
121 }
122
123 if ( is_wp_error( $response ) ) {
124 $body = wp_remote_retrieve_body( $response );
125 if ( $body ) {
126 return $body;
127 } else {
128 $curl = curl_version();
129
130 return __( 'License couldn’t be activated. Please try again later.', 'advanced-ads' ) . " (cURL {$curl['version']})";
131 }
132 }
133
134 $license_data = json_decode( wp_remote_retrieve_body( $response ) );
135 // save license status.
136 if ( ! empty( $license_data->license ) ) {
137 $this->clear_license_cache();
138 update_option( $options_slug . '-license-status', $license_data->license, false );
139 }
140 if ( ! empty( $license_data->expires ) ) {
141 $this->clear_license_cache();
142 update_option( $options_slug . '-license-expires', $license_data->expires, false );
143 }
144
145 // display activation problem.
146 if ( ! empty( $license_data->error ) ) {
147 // user friendly texts for errors.
148 $errors = [
149 'license_not_activable' => __( 'This is the bundle license key.', 'advanced-ads' ),
150 'item_name_mismatch' => __( 'This is not the correct key for this add-on.', 'advanced-ads' ),
151 'no_activations_left' => __( 'There are no activations left.', 'advanced-ads' )
152 . '&nbsp;'
153 . sprintf(
154 /* translators: %1$s is a starting link tag, %2$s is the closing one. */
155 __( 'You can manage activations in %1$syour account%2$s.', 'advanced-ads' ),
156 '<a href="https://wpadvancedads.com/account/?utm_source=advanced-ads&utm_medium=link&utm_campaign=settings-licenses-activations-left" target="_blank">',
157 '</a>'
158 ) . '&nbsp;'
159 . sprintf(
160 /* translators: %1$s is a starting link tag, %2$s is the closing one. */
161 __( '%1$sUpgrade%2$s for more activations.', 'advanced-ads' ),
162 '<a href="https://wpadvancedads.com/account/upgrades/?utm_source=advanced-ads&utm_medium=link&utm_campaign=settings-licenses-activations-left" target="_blank">',
163 '</a>'
164 ),
165 ];
166 $error = isset( $errors[ $license_data->error ] ) ? $errors[ $license_data->error ] : $license_data->error;
167 if ( 'expired' === $license_data->error ) {
168 return 'ex';
169 } else { // phpcs:ignore
170 if ( isset( $errors[ $license_data->error ] ) ) {
171 return $error;
172 } else {
173 return sprintf(
174 /* translators: %s is a string containing information about the issue. */
175 __( 'License is invalid. Reason: %s', 'advanced-ads' ),
176 $error
177 );
178 }
179 }
180 } else {
181 // reset license_expires admin notification.
182 Advanced_Ads_Admin_Notices::get_instance()->remove_from_queue( 'license_expires' ); // this one is no longer added, but we keep the check here in case it is still in the queue for some users.
183 Advanced_Ads_Admin_Notices::get_instance()->remove_from_queue( 'license_expired' ); // this one is no longer added, but we keep the check here in case it is still in the queue for some users.
184 Advanced_Ads_Admin_Notices::get_instance()->remove_from_queue( 'license_invalid' );
185 // save license key.
186 $licenses = $this->get_licenses();
187 $licenses[ $addon ] = $license_key;
188 $this->save_licenses( $licenses );
189 }
190
191 return 1;
192 }
193
194 /**
195 * Check if a request was blocked by our firewall
196 *
197 * @param array $response response from license call.
198 *
199 * @return mixed message or false
200 */
201 public function blocked_by_firewall( $response ) {
202 $response_code = wp_remote_retrieve_response_code( $response );
203 if ( 403 === $response_code ) {
204 $blocked_information = '';
205 if ( isset( $response['body'] ) ) {
206 // look for the IP address in this line: `<td><span>95.90.238.103</span></td>`.
207 $pattern = '/<span>([.0-9]*)<\/span>/';
208 $matches = [];
209 preg_match( $pattern, $response['body'], $matches );
210 $ip = isset( $matches[1] ) ? $matches[1] : '';
211 $blocked_information = 'IP: ' . $ip;
212 }
213
214 /* translators: %s is a list of server information like IP address. Just keep it as is. */
215 return sprintf( __( 'Your request was blocked by our firewall. Please send us the following information to unblock you: %s.', 'advanced-ads' ), $blocked_information );
216 }
217
218 return false;
219 }
220
221 /**
222 * Check if a specific license key was already activated for the current page
223 *
224 * @param string $license_key license key.
225 * @param string $plugin_name name of the add-on.
226 * @param string $options_slug slug of the option in the database.
227 *
228 * @return bool true if already activated
229 * @since 1.6.17
230 * @deprecated since version 1.7.2 because it only checks if a key is valid, not if the url registered with that key
231 */
232 public function check_license( $license_key = '', $plugin_name = '', $options_slug = '' ) {
233 if ( has_filter( 'advanced_ads_license_' . $options_slug ) ) {
234 return apply_filters( 'advanced_ads_license_' . $options_slug, false, __METHOD__, $plugin_name, $options_slug, $license_key );
235 }
236
237 $api_params = [
238 'edd_action' => 'check_license',
239 'license' => $license_key,
240 'item_id' => Constants::ADDON_SLUGS_ID[ $options_slug ] ?? false,
241 'item_name' => rawurlencode( $plugin_name ),
242 ];
243 $response = wp_remote_get(
244 add_query_arg( $api_params, 'https://wpadvancedads.com/' ),
245 [
246 'timeout' => 15,
247 'sslverify' => false,
248 ]
249 );
250 if ( is_wp_error( $response ) ) {
251 return false;
252 }
253 $license_data = json_decode( wp_remote_retrieve_body( $response ) );
254
255 // if this license is still valid.
256 if ( 'valid' === $license_data->license ) {
257 update_option( $options_slug . '-license-expires', $license_data->expires, false );
258 update_option( $options_slug . '-license-status', $license_data->license, false );
259
260 return true;
261 }
262
263 return false;
264 }
265
266 /**
267 * Deactivate license key
268 *
269 * @param string $addon string with add-on identifier.
270 * @param string $plugin_name name of the add-on.
271 * @param string $options_slug slug of the option in the database.
272 *
273 * @return string
274 * @since 1.6.11
275 */
276 public function deactivate_license( $addon = '', $plugin_name = '', $options_slug = '' ) {
277 if ( '' === $addon || '' === $plugin_name || '' === $options_slug ) {
278 return __( 'Error while trying to disable the license. Please contact support.', 'advanced-ads' );
279 }
280
281 $licenses = $this->get_licenses();
282 $license_key = isset( $licenses[ $addon ] ) ? $licenses[ $addon ] : '';
283 $short_circuit = $this->shortcuit_deactivation( $addon, $options_slug );
284
285 if ( false !== $short_circuit ) {
286 return true;
287 }
288
289 if ( has_filter( 'advanced_ads_license_' . $options_slug ) ) {
290 return apply_filters( 'advanced_ads_license_' . $options_slug, false, __METHOD__, $plugin_name, $options_slug, $license_key );
291 }
292
293 $api_params = [
294 'edd_action' => 'deactivate_license',
295 'license' => $license_key,
296 'item_id' => Constants::ADDON_SLUGS_ID[ $options_slug ] ?? false,
297 'item_name' => rawurlencode( $plugin_name ),
298 ];
299
300 // Send the remote request.
301 $response = wp_remote_post(
302 Constants::API_ENDPOINT,
303 [
304 'body' => $api_params,
305 'timeout' => 15,
306 'sslverify' => false,
307 ]
308 );
309
310 // show license debug output if constant is set.
311 if ( defined( 'ADVANCED_ADS_SHOW_LICENSE_RESPONSE' ) ) {
312 return '<p><strong>' . esc_html__( 'The license status does not change as long as ADVANCED_ADS_SHOW_LICENSE_RESPONSE is enabled in wp-config.php.', 'advanced-ads' ) . '</strong></p>' .
313 '<pre>' . print_r( $response, true ) . '</pre>'; // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_print_r
314 }
315
316 if ( is_wp_error( $response ) ) {
317 $body = wp_remote_retrieve_body( $response );
318 if ( $body ) {
319 return $body;
320 } else {
321 return __( 'License couldn’t be deactivated. Please try again later.', 'advanced-ads' );
322 }
323 }
324
325 $license_data = json_decode( wp_remote_retrieve_body( $response ) );
326
327 /**
328 * Send the user to our support when his request is blocked by our firewall
329 */
330 $error = $this->blocked_by_firewall( $response );
331 if ( $error ) {
332 return $error;
333 }
334
335 // remove data.
336 if ( 'deactivated' === $license_data->license ) {
337 delete_option( $options_slug . '-license-status' );
338 delete_option( $options_slug . '-license-expires' );
339 } elseif ( 'failed' === $license_data->license ) {
340 update_option( $options_slug . '-license-expires', $license_data->expires, false );
341 update_option( $options_slug . '-license-status', $license_data->license, false );
342
343 return 'ex';
344 } else {
345 return __( 'License couldn’t be deactivated. Please try again later.', 'advanced-ads' );
346 }
347
348 return 1;
349 }
350
351 /**
352 * Get license keys for all add-ons
353 *
354 * @return string[]
355 */
356 public function get_licenses() {
357 $licenses = get_option( ADVADS_SLUG . '-licenses', [] );
358 if ( empty( $licenses ) || ! is_array( $licenses ) ) {
359 $licenses = [];
360 }
361
362 return $licenses;
363 }
364
365 /**
366 * Save license keys for all add-ons
367 *
368 * @param array $licenses licenses.
369 */
370 public function save_licenses( $licenses = [] ) {
371 update_option( ADVADS_SLUG . '-licenses', $licenses );
372 }
373
374 /**
375 * Get license status of an add-on
376 *
377 * @param string $slug slug of the add-on.
378 *
379 * @return string|false license status, "valid", "invalid" or false if option doesn't exist.
380 */
381 public function get_license_status( $slug = '' ) {
382 return get_option( $slug . '-license-status', false );
383 }
384
385 /**
386 * If two or more add-ons use the same valid license this is probably an all-access customer
387 *
388 * @return bool
389 */
390 public function get_probably_all_access() {
391 $valid = array_filter(
392 $this->get_licenses(),
393 function ( $key ) {
394 return $this->get_license_status( ADVADS_SLUG . '-' . $key );
395 },
396 ARRAY_FILTER_USE_KEY
397 );
398
399 return [] !== $valid && max( array_count_values( $valid ) ) > 1;
400 }
401
402 /**
403 * Return the licence expiry time if it is equal for more than one add-on. That indicates it is likely an All Access license
404 *
405 * @return string|null
406 */
407 public function get_probably_all_access_expiry() {
408 /**
409 * Get expiry dates of all add-ons.
410 *
411 * @param string $key Add-on key.
412 *
413 * @return string|false the expiration date or false.
414 */
415 $expiry_counts = array_count_values(
416 array_map(
417 function ( $key ) {
418 return $this->get_license_expires( ADVADS_SLUG . '-' . $key );
419 },
420 array_keys( array_filter( $this->get_licenses() ) )
421 )
422 );
423
424 /**
425 * Remove all licenses that are used only once.
426 *
427 * @param int $count the count from array_count_values_above
428 *
429 * @return bool whether the count is greater 1
430 */
431 $all_access = array_filter(
432 $expiry_counts,
433 function ( $count ) {
434 return $count > 1;
435 }
436 );
437
438 // if there is an item in $all_access we can assume this is from All Access and return the expiry date.
439 return empty( $all_access ) ? null : key( $all_access );
440 }
441
442 /**
443 * Get license expired value of an add-on
444 *
445 * @param string $slug slug of the add-on.
446 *
447 * @return string $date expiry date of an add-on, empty string if no option exists
448 */
449 public function get_license_expires( $slug = '' ) {
450 return get_option( $slug . '-license-expires', '' );
451 }
452
453 /**
454 * Add custom messages to plugin updater
455 *
456 * @param bool $reply Whether to bail without returning the package. Default false.
457 * @param string $package The package file name.
458 * @param WP_Upgrader $updater The WP_Upgrader instance.
459 *
460 * @return string
461 *
462 * @todo check if this is still working.
463 */
464 public function addon_upgrade_filter( $reply, $package, $updater ) {
465 $key = null;
466 $value = null;
467
468 if ( isset( $updater->skin->plugin ) ) {
469 $key = 'path';
470 $value = $updater->skin->plugin;
471 } elseif ( isset( $updater->skin->plugin_info['Name'] ) ) {
472 $key = 'name';
473 $value = $updater->skin->plugin_info['Name'];
474 }
475
476 $add_on = $this->get_installed_add_on_by_key( $key, $value );
477 if ( ! $add_on || ! isset( $add_on['path'] ) ) {
478 return $reply;
479 }
480
481 $plugin_file = plugin_basename( $add_on['path'] );
482 if ( wp_doing_ajax() ) {
483 $update_link = wp_nonce_url( self_admin_url( 'update.php?action=upgrade-plugin&plugin=' ) . $plugin_file, 'upgrade-plugin_' . $plugin_file );
484 /* translators: %s plugin update link */
485 $updater->strings['download_failed'] = sprintf( __( 'Download failed. <a href="%s">Click here to try another method</a>.', 'advanced-ads' ), $update_link );
486 } else {
487 /* translators: %s download failed knowledgebase link */
488 $updater->strings['download_failed'] = sprintf( __( 'Download failed. <a href="%s" target="_blank">Click here to learn why</a>.', 'advanced-ads' ), 'https://wpadvancedads.com/manual/download-failed-updating-add-ons/#utm_source=advanced-ads&utm_medium=link&utm_campaign=download-failed' );
489 }
490
491 return $reply;
492 }
493
494 /**
495 * Search if a name is in the add-on array and return the add-on data of it
496 *
497 * @param string $key key to search for.
498 * @param string $value value to search for.
499 *
500 * @return array array with the add-on data
501 */
502 private function get_installed_add_on_by_key( $key, $value ) {
503 // Early bail!!
504 if ( empty( $key ) || empty( $value ) ) {
505 return null;
506 }
507
508 $add_ons = Data::get_addons();
509 if ( is_array( $add_ons ) ) {
510 foreach ( $add_ons as $add_on ) {
511 if ( $add_on[ $key ] === $value ) {
512 return $add_on;
513 }
514 }
515 }
516
517 return null;
518 }
519
520 /**
521 * Check if any license is valid
522 * can be used to display information for any Pro user only, like link to direct support
523 */
524 public static function any_license_valid() {
525 $add_ons = Data::get_addons();
526 if ( [] === $add_ons ) {
527 return false;
528 }
529
530 foreach ( $add_ons as $_add_on ) {
531 if ( 'slider-ads' === $_add_on['id'] ) {
532 continue;
533 }
534
535 $status = self::get_instance()->get_license_status( $_add_on['options_slug'] );
536
537 // check expiry date.
538 $expiry_date = self::get_instance()->get_license_expires( $_add_on['options_slug'] );
539
540 if (
541 ( $expiry_date && strtotime( $expiry_date ) > time() )
542 || 'valid' === $status || 'lifetime' === $expiry_date
543 ) {
544 return true;
545 }
546 }
547
548 return false;
549 }
550
551 /**
552 * Update the license status based on information retrieved from the version info check
553 *
554 * @param array|WP_Error $response HTTP response or WP_Error object.
555 * @param string $context Context under which the hook is fired.
556 * @param string $http HTTP transport used.
557 * @param array $parsed_args HTTP request arguments.
558 * @param string $url The request URL.
559 * @return array|WP_Error
560 */
561 public function update_license_after_version_info( $response, $context, $http, $parsed_args, $url ) {
562 // Early bail!!
563 if (
564 Constants::API_ENDPOINT !== $url
565 || (
566 empty( $parsed_args['body']['edd_action'] )
567 || 'get_version' !== $parsed_args['body']['edd_action']
568 )
569 || is_wp_error( $response )
570 ) {
571 return $response;
572 }
573
574 $params = json_decode( wp_remote_retrieve_body( $response ) );
575 if ( empty( $params->name ) ) {
576 return $response;
577 }
578
579 $new_license_status = null;
580 $new_expiry_date = null;
581
582 // Some of the conditions could happen at the same time,
583 // though due to different conditions in EDD we are safer to have multiple checks.
584 if ( isset( $params->valid_until ) ) {
585 if ( 'invalid' === $params->valid_until ) {
586 $new_license_status = 'invalid';
587 }
588 if ( 'lifetime' === $params->valid_until ) {
589 $new_license_status = 'valid';
590 $new_expiry_date = 'lifetime';
591 }
592
593 if ( is_int( $params->valid_until ) ) {
594 $new_expiry_date = (int) $params->valid_until;
595 if ( time() < $params->valid_until ) {
596 $new_license_status = 'valid';
597 }
598 }
599 } elseif ( empty( $params->download_link ) || empty( $params->package ) || isset( $params->msg ) ) {
600 // If either of these two parameters is missing then the user does not have a valid license according to our store
601 // If there is a "msg" parameter then the license did also not work for another reason.
602 $new_license_status = 'invalid';
603 }
604
605 if ( ! $new_license_status && ! $new_expiry_date ) {
606 return $response;
607 }
608
609 $add_ons = Data::get_addons();
610
611 // Look for the add-on with the appropriate license key.
612 foreach ( $add_ons as $_add_on ) {
613 if ( ! isset( $_add_on['name'] ) || $params->name !== $_add_on['name'] ) {
614 continue;
615 }
616
617 $options_slug = $_add_on['options_slug'];
618
619 if ( $new_license_status ) {
620 update_option( $options_slug . '-license-status', $new_license_status, false );
621 }
622
623 if ( $new_expiry_date ) {
624 if ( 'lifetime' !== $new_expiry_date ) {
625 $new_expiry_date = gmdate( 'Y-m-d 23:59:49', $new_expiry_date );
626 }
627 update_option( $options_slug . '-license-expires', $new_expiry_date, false );
628 }
629
630 // Return with the first match since there should only be one plugin per name.
631 return $response;
632 }
633
634 return $response;
635 }
636
637 /**
638 * Shortcuit deactivation
639 *
640 * @param string $addon string with add-on identifier.
641 * @param string $options_slug slug of the option in the database.
642 *
643 * @return false
644 */
645 private function shortcuit_deactivation( $addon, $options_slug ) {
646 $licenses = $this->get_filtered_licenses();
647 $license_key = isset( $licenses[ $addon ] ) ? $licenses[ $addon ] : '';
648 $counts = array_count_values( $licenses );
649
650 if ( $counts[ $license_key ] > 1 ) {
651 delete_option( $options_slug . '-license-status' );
652 delete_option( $options_slug . '-license-expires' );
653 return __( 'License deactivated. Please try again later.', 'advanced-ads' );
654 }
655
656 return false;
657 }
658
659 /**
660 * If two or more add-ons use the same valid license this is probably an all-access customer
661 *
662 * @return array
663 */
664 private function get_filtered_licenses() {
665 $filtered = array_filter(
666 $this->get_licenses(),
667 function ( $key ) {
668 return $this->get_license_status( ADVADS_SLUG . '-' . $key );
669 },
670 ARRAY_FILTER_USE_KEY
671 );
672
673 return ! is_array( $filtered ) ? [] : $filtered;
674 }
675
676 /**
677 * Clear the license cache
678 *
679 * @param string $slug slug of the add-on.
680 * @param string $license_key license key.
681 */
682 private function clear_license_cache() {
683 global $wpdb;
684
685 $wpdb->query( "DELETE FROM $wpdb->options WHERE option_name LIKE 'advads_edd_sl_%'" );
686 }
687 }
688