| 1 |
<?php |
| 2 |
/** |
| 3 |
* Charitable Addons Directory. |
| 4 |
* |
| 5 |
* @package Charitable/Classes/Charitable_Addons_Directory |
| 6 |
* @author David Bisset |
| 7 |
* @copyright Copyright (c) 2022, WP Charitable LLC |
| 8 |
* @license http://opensource.org/licenses/gpl-2.0.php GNU Public License |
| 9 |
* @since 1.0.0 |
| 10 |
* @version 1.0.0 |
| 11 |
*/ |
| 12 |
|
| 13 |
// Exit if accessed directly. |
| 14 |
if ( ! defined( 'ABSPATH' ) ) { |
| 15 |
exit; |
| 16 |
} |
| 17 |
|
| 18 |
if ( ! class_exists( 'Charitable_Addons_Directory' ) ) : |
| 19 |
|
| 20 |
/** |
| 21 |
* Charitable_Addons_Directory |
| 22 |
* |
| 23 |
* @final |
| 24 |
* @since 1.0.0 |
| 25 |
*/ |
| 26 |
final class Charitable_Addons_Directory { |
| 27 |
|
| 28 |
/* @var string */ |
| 29 |
const UPDATE_URL = 'https://wpcharitable.com'; |
| 30 |
|
| 31 |
/** |
| 32 |
* The single instance of this class. |
| 33 |
* |
| 34 |
* @var Charitable_Addons_Directory|null |
| 35 |
*/ |
| 36 |
private static $instance = null; |
| 37 |
|
| 38 |
/** |
| 39 |
* All the stored licenses. |
| 40 |
* |
| 41 |
* @var array |
| 42 |
*/ |
| 43 |
private $licenses; |
| 44 |
|
| 45 |
/** |
| 46 |
* Determine if the plugin/addon installations are allowed. |
| 47 |
* |
| 48 |
* @since 1.6.7 |
| 49 |
* |
| 50 |
* @var bool |
| 51 |
*/ |
| 52 |
private $can_install; |
| 53 |
|
| 54 |
/** |
| 55 |
* Create object instance. |
| 56 |
* |
| 57 |
* @since 1.0.0 |
| 58 |
*/ |
| 59 |
private function __construct() { |
| 60 |
|
| 61 |
// Maybe load addons page. |
| 62 |
add_action( 'admin_init', array ( $this, 'init' ) ); |
| 63 |
|
| 64 |
do_action( 'charitable_addons_directory_settings_start', $this ); |
| 65 |
|
| 66 |
add_action( 'admin_enqueue_scripts', array( $this, 'charitable_admin_scripts' ) ); |
| 67 |
|
| 68 |
// Add callbacks for content. |
| 69 |
add_action( 'charitable_addons_directory_section', array( $this, 'addons_directory_content' ) ); |
| 70 |
|
| 71 |
} |
| 72 |
|
| 73 |
/** |
| 74 |
* Init. |
| 75 |
* |
| 76 |
* @since 1.6.7 |
| 77 |
*/ |
| 78 |
public function init() { |
| 79 |
|
| 80 |
$this->can_install = charitable_can_install( 'addon' ); |
| 81 |
|
| 82 |
} |
| 83 |
|
| 84 |
public function charitable_admin_scripts() { |
| 85 |
|
| 86 |
if ( defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ) { |
| 87 |
$suffix = ''; |
| 88 |
$version = ''; |
| 89 |
} else { |
| 90 |
$suffix = '.min'; |
| 91 |
$version = charitable()->get_version(); |
| 92 |
} |
| 93 |
|
| 94 |
$assets_dir = charitable()->get_path( 'assets', false ); |
| 95 |
|
| 96 |
$strings = [ |
| 97 |
'addon_activate' => esc_html__( 'Activate', 'charitable' ), |
| 98 |
'addon_activated' => esc_html__( 'Activated', 'charitable' ), |
| 99 |
'addon_active' => esc_html__( 'Active', 'charitable' ), |
| 100 |
'addon_deactivate' => esc_html__( 'Deactivate', 'charitable' ), |
| 101 |
'addon_inactive' => esc_html__( 'Inactive', 'charitable' ), |
| 102 |
'addon_install' => esc_html__( 'Install Addon', 'charitable' ), |
| 103 |
'addon_error' => sprintf( |
| 104 |
wp_kses( /* translators: %1$s - An addon download URL, %2$s - Link to manual installation guide. */ |
| 105 |
__( 'Could not install the addon. Please <a href="%1$s" target="_blank" rel="noopener noreferrer">download it from wpcharitable.com</a> and <a href="%2$s" target="_blank" rel="noopener noreferrer">install it manually</a>.', 'charitable' ), |
| 106 |
[ |
| 107 |
'a' => [ |
| 108 |
'href' => true, |
| 109 |
'target' => true, |
| 110 |
'rel' => true, |
| 111 |
], |
| 112 |
] |
| 113 |
), |
| 114 |
'https://wpcharitable.com/account/licenses/', |
| 115 |
'https://wpcharitable.com/docs/how-to-manually-install-addons-in-charitable/' |
| 116 |
), |
| 117 |
'plugin_error' => esc_html__( 'Could not install the plugin automatically. Please download and install it manually.', 'charitable' ), |
| 118 |
'addon_search' => esc_html__( 'Searching Addons', 'charitable' ), |
| 119 |
'ajax_url' => admin_url( 'admin-ajax.php' ), |
| 120 |
'admin_url' => admin_url(), |
| 121 |
'cancel' => esc_html__( 'Cancel', 'charitable' ), |
| 122 |
'close' => esc_html__( 'Close', 'charitable' ), |
| 123 |
'plugin_install_activate_btn' => esc_html__( 'Install and Activate', 'charitable' ), |
| 124 |
'plugin_install_activate_confirm' => esc_html__( 'needs to be installed and activated to import its forms. Would you like us to install and activate it for you?', 'charitable' ), |
| 125 |
'plugin_activate_btn' => esc_html__( 'Activate', 'charitable' ), |
| 126 |
'plugin_activate_confirm' => esc_html__( 'needs to be activated to import its forms. Would you like us to activate it for you?', 'charitable' ), |
| 127 |
'connecting' => esc_html__( 'Connecting...', 'charitable' ), |
| 128 |
'save_refresh' => esc_html__( 'Save and Refresh', 'charitable' ), |
| 129 |
'server_error' => esc_html__( 'Unfortunately there was a server connection error.', 'charitable' ), |
| 130 |
'testing' => esc_html__( 'Testing', 'charitable' ), |
| 131 |
'upgrade_completed' => esc_html__( 'Upgrade was successfully completed!', 'charitable' ), |
| 132 |
'edit_license' => esc_html__( 'To edit the License Key, please first click the Deactivate Key button. Please note that deactivating this key will remove access to updates, addons, and support.', 'charitable' ), |
| 133 |
'something_went_wrong' => esc_html__( 'Something went wrong', 'charitable' ), |
| 134 |
'success' => esc_html__( 'Success', 'charitable' ), |
| 135 |
'loading' => esc_html__( 'Loading...', 'charitable' ), |
| 136 |
'use_simple_contact_form' => esc_html__( 'Use Simple Contact Form Template', 'charitable' ), |
| 137 |
'error_select_template' => esc_html__( 'Something went wrong while applying the template.', 'charitable' ), |
| 138 |
'nonce' => wp_create_nonce( 'charitable-admin' ), |
| 139 |
]; |
| 140 |
|
| 141 |
|
| 142 |
wp_enqueue_script( |
| 143 |
'listjs', |
| 144 |
$assets_dir . 'js/libraries/list.min.js', |
| 145 |
[ 'jquery' ], |
| 146 |
$version, |
| 147 |
false |
| 148 |
); |
| 149 |
|
| 150 |
wp_register_style( |
| 151 |
'charitable-admin-addons-directory', |
| 152 |
$assets_dir . 'css/charitable-admin-addons-directory' . $suffix . '.css', |
| 153 |
array(), |
| 154 |
$version |
| 155 |
); |
| 156 |
wp_enqueue_style( 'charitable-admin-addons-directory' ); |
| 157 |
|
| 158 |
wp_register_script( |
| 159 |
'charitable-admin-addon-directory', |
| 160 |
$assets_dir . 'js/charitable-admin-addon-directory' . $suffix . '.js', |
| 161 |
array( 'jquery' ), |
| 162 |
$version, |
| 163 |
true |
| 164 |
); |
| 165 |
|
| 166 |
wp_enqueue_script( 'charitable-admin-addon-directory' ); |
| 167 |
|
| 168 |
wp_localize_script( |
| 169 |
'charitable-admin-addon-directory', |
| 170 |
'charitable_admin', |
| 171 |
$strings |
| 172 |
); |
| 173 |
|
| 174 |
} |
| 175 |
|
| 176 |
/** |
| 177 |
* Returns and/or create the single instance of this class. |
| 178 |
* |
| 179 |
* @since 1.2.0 |
| 180 |
* |
| 181 |
* @return Charitable_Addons_Directory |
| 182 |
*/ |
| 183 |
public static function get_instance() { |
| 184 |
if ( is_null( self::$instance ) ) { |
| 185 |
self::$instance = new self(); |
| 186 |
} |
| 187 |
|
| 188 |
return self::$instance; |
| 189 |
} |
| 190 |
|
| 191 |
/** |
| 192 |
* Attemps to confirm if the current license is a legacy one, even if we have a plan_id / slug (which normally came from newer license) |
| 193 |
* |
| 194 |
* @since 1.7.0.4 |
| 195 |
* |
| 196 |
* @return Charitable_Addons_Directory |
| 197 |
*/ |
| 198 |
public static function is_current_plan_legacy() { |
| 199 |
|
| 200 |
$settings = get_option( 'charitable_settings' ); |
| 201 |
|
| 202 |
// always check the v2 settings first. |
| 203 |
$plan_id = isset( $settings['licenses']['charitable-v2'][ 'plan_id' ] ) ? intval( $settings['licenses']['charitable-v2'][ 'plan_id' ] ) : false; |
| 204 |
$valid = isset( $settings['licenses']['charitable-v2'][ 'valid' ] ) ? trim( esc_html( $settings['licenses']['charitable-v2'][ 'valid' ] ) ) : false; |
| 205 |
|
| 206 |
if ( false === $valid || '' === $valid ) { |
| 207 |
// try looking at the "legacy" license for a plan_id |
| 208 |
if ( isset( $settings['licenses']['charitable'] ) ) { |
| 209 |
$plan_id = isset( $settings['licenses']['charitable'][ 'plan_id' ] ) ? intval( $settings['licenses']['charitable'][ 'plan_id' ] ) : false; |
| 210 |
$valid = isset( $settings['licenses']['charitable'][ 'valid' ] ) ? trim( esc_html( $settings['licenses']['charitable'][ 'valid' ] ) ) : false; |
| 211 |
|
| 212 |
if ( $plan_id ) { |
| 213 |
return true; |
| 214 |
} |
| 215 |
} |
| 216 |
|
| 217 |
// try looking for an install that just installed an addon license only, which would be another example of a "legacy" license |
| 218 |
if ( ! empty( $settings['licenses'] ) ) { |
| 219 |
$addon_licenses = $settings['licenses']; |
| 220 |
if ( isset( $addon_licenses['charitable'] ) ) { |
| 221 |
unset( $addon_licenses['charitable'] ); |
| 222 |
} |
| 223 |
if ( isset( $addon_licenses['charitable_pro'] ) ) { |
| 224 |
unset( $addon_licenses['charitable_pro'] ); |
| 225 |
} |
| 226 |
foreach ( $addon_licenses as $addon_license ) { |
| 227 |
if ( isset( $addon_license['valid'] ) && 1 === intval( $addon_license['valid'] ) ) { |
| 228 |
return true; |
| 229 |
} |
| 230 |
} |
| 231 |
} |
| 232 |
|
| 233 |
} |
| 234 |
|
| 235 |
return false; |
| 236 |
|
| 237 |
} |
| 238 |
|
| 239 |
/** |
| 240 |
* Returns and/or create the single instance of this class. |
| 241 |
* |
| 242 |
* @since 1.2.0 |
| 243 |
* |
| 244 |
* @return Charitable_Addons_Directory |
| 245 |
*/ |
| 246 |
public static function get_current_plan_slug() { |
| 247 |
|
| 248 |
$settings = get_option( 'charitable_settings' ); |
| 249 |
|
| 250 |
// always check the v2 settings first. |
| 251 |
$plan_id = isset( $settings['licenses']['charitable-v2'][ 'plan_id' ] ) ? intval( $settings['licenses']['charitable-v2'][ 'plan_id' ] ) : false; |
| 252 |
$valid = isset( $settings['licenses']['charitable-v2'][ 'valid' ] ) ? trim( esc_html( $settings['licenses']['charitable-v2'][ 'valid' ] ) ) : false; |
| 253 |
|
| 254 |
if ( false === $valid || '' === $valid ) { |
| 255 |
// try looking at the "legacy" license for a plan_id |
| 256 |
if ( isset( $settings['licenses']['charitable'] ) ) { |
| 257 |
$plan_id = isset( $settings['licenses']['charitable'][ 'plan_id' ] ) ? intval( $settings['licenses']['charitable'][ 'plan_id' ] ) : false; |
| 258 |
$valid = isset( $settings['licenses']['charitable'][ 'valid' ] ) ? trim( esc_html( $settings['licenses']['charitable'][ 'valid' ] ) ) : false; |
| 259 |
} |
| 260 |
} |
| 261 |
|
| 262 |
if ( $valid ) { |
| 263 |
switch ( $plan_id ) { |
| 264 |
case 1: |
| 265 |
$plan_slug = 'basic'; |
| 266 |
break; |
| 267 |
case 2: |
| 268 |
$plan_slug = 'plus'; |
| 269 |
break; |
| 270 |
case 3: |
| 271 |
$plan_slug = 'pro'; |
| 272 |
break; |
| 273 |
case 4: |
| 274 |
$plan_slug = 'agency'; |
| 275 |
break; |
| 276 |
default: |
| 277 |
$plan_slug = 'lite'; |
| 278 |
break; |
| 279 |
} |
| 280 |
} else { |
| 281 |
$plan_slug = 'lite'; |
| 282 |
} |
| 283 |
|
| 284 |
return $plan_slug; |
| 285 |
|
| 286 |
} |
| 287 |
|
| 288 |
/** |
| 289 |
* Callback for displaying the UI for Addons. |
| 290 |
* |
| 291 |
* @since 1.7.0 |
| 292 |
*/ |
| 293 |
public function addons_directory_content() { |
| 294 |
|
| 295 |
// Get Addons. |
| 296 |
$temp_addons = $this->get_addons(); |
| 297 |
|
| 298 |
// If error(s) occured during license key verification, display them and exit now. |
| 299 |
if ( empty( $temp_addons ) ) { ?> |
| 300 |
|
| 301 |
<h1 class="page-title"><?php echo __( 'Charitable Addons', 'charitable' ); ?></h1> |
| 302 |
|
| 303 |
<div class="error below-h2"> |
| 304 |
<p> |
| 305 |
<?php esc_html_e( 'There are some communication or license issues. Please make sure your server is able to communicate with wpcharitable.com. Contact Charitable Support for additional assistance.', 'charitable' ); ?> |
| 306 |
</p> |
| 307 |
</div> |
| 308 |
<?php |
| 309 |
|
| 310 |
if ( defined( 'CHARITABLE_DEBUG' ) && CHARITABLE_DEBUG ) { |
| 311 |
error_log( 'addons_directory_content - communication issue' ); |
| 312 |
} |
| 313 |
|
| 314 |
return; |
| 315 |
} |
| 316 |
|
| 317 |
$recommended_addons = array_map( array( $this, 'prepare_addon_data' ), ! empty( $temp_addons['recommended'] ) ? $temp_addons['recommended'] : array() ); |
| 318 |
$unlicensed_addons = array_map( array( $this, 'prepare_addon_data' ), ! empty( $temp_addons['unlicensed'] ) ? $temp_addons['unlicensed'] : array() ); |
| 319 |
$licensed_addons = array_map( array( $this, 'prepare_addon_data' ), ! empty( $temp_addons['licensed'] ) ? $temp_addons['licensed'] : array() ); |
| 320 |
|
| 321 |
$addons = array ( 'recommended' => $recommended_addons, 'licensed' => $licensed_addons, 'unlicensed' => $unlicensed_addons ); |
| 322 |
|
| 323 |
// If no Addon(s) were returned, our API call returned an error. |
| 324 |
// Show an error message with a button to reload the page, which will trigger another API call. |
| 325 |
if ( ! $addons ) { |
| 326 |
?> |
| 327 |
<form id="charitable-addons-refresh-addons-form" method="post"> |
| 328 |
<p> |
| 329 |
<?php esc_html_e( 'There was an issue retrieving the addons for this site. Please click on the button below the refresh the addons data.', 'charitable' ); ?> |
| 330 |
</p> |
| 331 |
<p> |
| 332 |
<a href="<?php echo esc_url( wp_unslash( $_SERVER['REQUEST_URI'] ) ); ?>" class="button button-primary"><?php esc_html_e( 'Refresh Addons', 'charitable' ); ?></a> <?php // @codingStandardsIgnoreLine ?> |
| 333 |
</p> |
| 334 |
</form> |
| 335 |
<?php |
| 336 |
return; |
| 337 |
} |
| 338 |
|
| 339 |
// If here, we have Addons to display, so let's output them now. |
| 340 |
// Get installed plugins and upgrade URL. |
| 341 |
$installed_plugins = get_plugins(); |
| 342 |
$upgrade_url = $this->charitable_get_upgrade_link(); |
| 343 |
$type = ( isset( $_GET['plan'] ) ) ? $_GET['plan'] : $this->get_current_plan_slug(); // todo: remove $_GET. |
| 344 |
?> |
| 345 |
|
| 346 |
<h1 class="page-title"><?php echo get_admin_page_title(); ?><input type="search" placeholder="Search Addons" id="charitable-admin-addons-search"></h1> |
| 347 |
|
| 348 |
<?php |
| 349 |
|
| 350 |
if ( defined( 'CHARITABLE_DEBUG' ) && CHARITABLE_DEBUG ) { |
| 351 |
echo '<p>Plan type is: ' . $type . '</p>'; |
| 352 |
error_log('addons_directory_content' ); |
| 353 |
error_log( print_r( $type, true ) ); |
| 354 |
error_log( print_r( $installed_plugins, true ) ); |
| 355 |
error_log( print_r( $upgrade_url, true ) ); |
| 356 |
} |
| 357 |
|
| 358 |
?> |
| 359 |
|
| 360 |
<?php if ( ! charitable_is_pro() ) { ?> |
| 361 |
|
| 362 |
<?php echo Charitable_Settings::get_instance()->settings_cta(); ?> |
| 363 |
|
| 364 |
<?php } ?> |
| 365 |
|
| 366 |
<div id="charitable-addons"> |
| 367 |
|
| 368 |
<div id="charitable-admin-addons-list"> |
| 369 |
|
| 370 |
<div class="list"> |
| 371 |
<?php |
| 372 |
if ( isset( $addons['recommended'] ) && ! empty( $addons['recommended'] ) ) { |
| 373 |
foreach ( (array) $addons['recommended'] as $i => $addon ) { |
| 374 |
$this->get_addon_card( $addon, $i, true, $installed_plugins ); |
| 375 |
} |
| 376 |
} |
| 377 |
?> |
| 378 |
<?php |
| 379 |
if ( isset( $addons['licensed'] ) && ! empty( $addons['licensed'] ) ) { |
| 380 |
foreach ( (array) $addons['licensed'] as $i => $addon ) { |
| 381 |
$this->get_addon_card( $addon, $i, true, $installed_plugins ); |
| 382 |
} |
| 383 |
} |
| 384 |
?> |
| 385 |
<?php |
| 386 |
if ( isset( $addons['unlicensed'] ) && ! empty( $addons['unlicensed'] ) ) { |
| 387 |
foreach ( (array) $addons['unlicensed'] as $i => $addon ) { |
| 388 |
$this->get_addon_card( $addon, $i, false, $installed_plugins ); |
| 389 |
} |
| 390 |
} |
| 391 |
?> |
| 392 |
</div> |
| 393 |
|
| 394 |
</div> |
| 395 |
<?php |
| 396 |
|
| 397 |
} |
| 398 |
|
| 399 |
/** |
| 400 |
* Retrieves addons from the stored transient or remote server. |
| 401 |
* |
| 402 |
* @since 1.7.0 |
| 403 |
* |
| 404 |
* @return bool | array false | Array of licensed and unlicensed Addons. |
| 405 |
*/ |
| 406 |
public function get_addons() { |
| 407 |
|
| 408 |
// Get license key and type. |
| 409 |
$key = false; // charitable_get_license_key(); |
| 410 |
$type = $this->get_current_plan_slug(); |
| 411 |
$addons = get_transient( '_charitable_addons' ); // @codingStandardsIgnoreLine - testing. |
| 412 |
|
| 413 |
// Get addons data from transient or perform API query if no transient. |
| 414 |
if ( false === $addons ) { |
| 415 |
$addons = $this->get_addons_data_from_server( $key ); |
| 416 |
} |
| 417 |
|
| 418 |
// If no Addons exist, return false. |
| 419 |
if ( ! $addons ) { |
| 420 |
return array(); |
| 421 |
} |
| 422 |
|
| 423 |
// Iterate through Addons, to build two arrays: |
| 424 |
// - Addons the user is licensed to use, |
| 425 |
// - Addons the user isn't licensed to use. |
| 426 |
$results = array( |
| 427 |
'recommended' => array(), |
| 428 |
'licensed' => array(), |
| 429 |
'unlicensed' => array(), |
| 430 |
); |
| 431 |
|
| 432 |
foreach ( (array) $addons as $i => $addon ) { |
| 433 |
|
| 434 |
if ( ! isset( $addon['slug'] ) || $addon['slug'] === '' || strtolower( $addon['slug'] ) === 'auto draft' ) { |
| 435 |
continue; |
| 436 |
} |
| 437 |
|
| 438 |
if ( ! is_array( $addon ) ) { |
| 439 |
$addon = array(); |
| 440 |
} |
| 441 |
|
| 442 |
$addon['path'] = ( '' === $addon['path'] ) ? sprintf( '%1$s/%1$s.php', $addon['slug'] ) : $addon['path']; |
| 443 |
|
| 444 |
$type = ( isset( $_GET['license'] ) ) ? $_GET['license'] : $this->get_current_plan_slug(); |
| 445 |
|
| 446 |
if ( isset( $addon['featured'] ) && in_array( 'recommended', $addon['featured'] ) ) { |
| 447 |
$results['recommended'][] = (array) $addon; |
| 448 |
continue; |
| 449 |
} else { |
| 450 |
// Determine if the addon belongs licensed or unlicensed based on the confirmed plan. |
| 451 |
if ( isset( $addon['license'] ) && in_array( $type, $addon['license'] ) ) { |
| 452 |
$results['licensed'][] = (array) $addon; |
| 453 |
continue; |
| 454 |
} else { |
| 455 |
$results['unlicensed'][] = (array) $addon; |
| 456 |
continue; |
| 457 |
} |
| 458 |
} |
| 459 |
|
| 460 |
} |
| 461 |
|
| 462 |
// Return Addons, split by licensed and unlicensed. |
| 463 |
return $results; |
| 464 |
|
| 465 |
} |
| 466 |
|
| 467 |
|
| 468 |
/** |
| 469 |
* Stores an upgrade link used for the addons page when a person needs a pro license. |
| 470 |
* |
| 471 |
* @since 1.7.0.4 |
| 472 |
* |
| 473 |
* @return string The url |
| 474 |
*/ |
| 475 |
public function charitable_get_upgrade_link() { |
| 476 |
return 'https://wpcharitable.com/lite-upgrade/?discount=LITEUPGRADE&utm_source=WordPress&utm_campaign=liteplugin&utm_medium=addons&utm_content=ActiveCampaign%20Addon'; |
| 477 |
} |
| 478 |
|
| 479 |
/** |
| 480 |
* Retrieve the plugin basename from the plugin slug. |
| 481 |
* |
| 482 |
* @since 1.7.0 |
| 483 |
* |
| 484 |
* @param string $slug The plugin slug. |
| 485 |
* @return string The plugin basename if found, else the plugin slug. |
| 486 |
*/ |
| 487 |
public function get_plugin_basename_from_slug( $slug ) { |
| 488 |
|
| 489 |
$keys = array_keys( get_plugins() ); |
| 490 |
|
| 491 |
foreach ( $keys as $key ) { |
| 492 |
if ( preg_match( '|^' . $slug . '|', $key ) ) { |
| 493 |
return $key; |
| 494 |
} |
| 495 |
} |
| 496 |
|
| 497 |
return $slug; |
| 498 |
|
| 499 |
} |
| 500 |
|
| 501 |
/** |
| 502 |
* Outputs the addon "box" on the addons page. |
| 503 |
* |
| 504 |
* @since 1.7.0 |
| 505 |
* |
| 506 |
* @param object $addon Addon data from the API / transient call. |
| 507 |
* @param int $counter Index of this Addon in the collection. |
| 508 |
* @param bool $is_licensed Whether the Addon is licensed for use. |
| 509 |
* @param array $installed_plugins Installed WordPress Plugins. |
| 510 |
*/ |
| 511 |
public function get_addon_card( $addon, $counter = 0, $is_licensed = false, $installed_plugins = false ) { |
| 512 |
|
| 513 |
if ( ! isset( $addon['slug'] ) ) { |
| 514 |
return; |
| 515 |
} |
| 516 |
|
| 517 |
// Setup some vars. |
| 518 |
$plugin_basename = $this->get_plugin_basename_from_slug( $addon['slug'] ); |
| 519 |
$replacements = array ('charitable-recurring-donations' => 'charitable-recurring' ); |
| 520 |
if ( array_key_exists( $addon['slug'], $replacements ) ) { |
| 521 |
$plugin_basename = $this->get_plugin_basename_from_slug( $replacements[ $addon['slug'] ] ); |
| 522 |
} |
| 523 |
// $categories = implode( ',', $addon['categories'] ); |
| 524 |
|
| 525 |
if ( ! $installed_plugins ) { |
| 526 |
$installed_plugins = get_plugins(); |
| 527 |
} |
| 528 |
|
| 529 |
// If the Addon doesn't supply an upgrade_url key, it's because the user hasn't provided a license. |
| 530 |
// get_upgrade_link() will return the Lite or Pro link as necessary for us. |
| 531 |
if ( ! isset( $addon['upgrade_url'] ) ) { |
| 532 |
$addon['upgrade_url'] = $this->charitable_get_upgrade_link(); |
| 533 |
} |
| 534 |
|
| 535 |
// Add marketing tracking. |
| 536 |
$addon['upgrade_url'] = add_query_arg( |
| 537 |
array( |
| 538 |
'utm_source' => 'proplugin', |
| 539 |
'utm_medium' => 'addonspage', |
| 540 |
'utm_campaign' => str_replace( '-', '', $addon['slug'] ) . 'addon', |
| 541 |
), |
| 542 |
$addon['upgrade_url'] |
| 543 |
); |
| 544 |
|
| 545 |
if ( ! isset( $installed_plugins[ $plugin_basename ] ) ) { |
| 546 |
switch ( $this->get_current_plan_slug() ) { |
| 547 |
case 'plus': |
| 548 |
$the_plans = array( 'basic', 'plus' ); |
| 549 |
break; |
| 550 |
case 'pro': |
| 551 |
$the_plans = array( 'basic', 'plus', 'pro' ); |
| 552 |
break; |
| 553 |
case 'agency': |
| 554 |
$the_plans = array( 'basic', 'plus', 'pro', 'agency' ); |
| 555 |
break; |
| 556 |
|
| 557 |
default: |
| 558 |
$the_plans = array (); |
| 559 |
break; |
| 560 |
} |
| 561 |
|
| 562 |
$addon['status'] = 'missing'; |
| 563 |
$addon['action'] = 'license'; |
| 564 |
|
| 565 |
foreach ( $addon['license'] as $license_to_check ) { |
| 566 |
if ( in_array( $license_to_check, $the_plans ) ) { |
| 567 |
$addon['status'] = 'missing'; |
| 568 |
$addon['action'] = 'install'; |
| 569 |
} |
| 570 |
} |
| 571 |
|
| 572 |
} else { |
| 573 |
// Plugin is installed. |
| 574 |
if ( is_plugin_active( $plugin_basename ) ) { |
| 575 |
$addon['status'] = 'active'; |
| 576 |
$addon['action'] = 'deactivate'; |
| 577 |
} else { |
| 578 |
$addon['status'] = 'installed'; |
| 579 |
$addon['action'] = 'activate'; |
| 580 |
} |
| 581 |
} |
| 582 |
|
| 583 |
$button = $this->get_addon_button_html( $addon ); |
| 584 |
|
| 585 |
$status_label = $this->get_addon_status_label( $addon['status'] ); |
| 586 |
|
| 587 |
// get the icon/graphic. |
| 588 |
$icon = isset( $addon['icon'] ) ? esc_url( $addon['icon'] ) : 'placeholder'; |
| 589 |
|
| 590 |
// get the plugin description. |
| 591 |
$sections = unserialize( $addon['sections'] ); |
| 592 |
$description = wp_strip_all_tags( ( $sections['description'] ) ); |
| 593 |
$is_recommended = ( isset( $addon['featured'] ) && is_array( $addon['featured'] ) && in_array( 'recommended', $addon['featured']) ) ? true : false; |
| 594 |
|
| 595 |
// css |
| 596 |
$css = array ('addon-container'); |
| 597 |
if ( $is_recommended ) { |
| 598 |
$css[] = 'recommended'; |
| 599 |
} |
| 600 |
|
| 601 |
// Output the card. |
| 602 |
?> |
| 603 |
|
| 604 |
<div class="<?php echo implode(' ', $css ); ?>"> |
| 605 |
<div class="addon-item"> |
| 606 |
<?php if ( $is_recommended ) : ?> |
| 607 |
<div class="recommended"><?php echo esc_html__( 'Recommended', 'charitable' ); ?></div> |
| 608 |
<?php endif; ?> |
| 609 |
<img src="<?php echo esc_url( $icon ); ?>" alt="<?php echo esc_html( $addon['name'] ); ?> Addon logo"> |
| 610 |
<div class="details charitable-clear"> |
| 611 |
<h5 class="addon-name"> |
| 612 |
<a href="<?php echo esc_url( $addon['upgrade_url'] ); ?>" title="Learn more" target="_blank" rel="noopener noreferrer" class="addon-link"><?php echo esc_html( $addon['name'] ); ?> Addon</a></h5> |
| 613 |
<p class="addon-desc"><?php echo wpautop( $description ); ?></p> |
| 614 |
</div> |
| 615 |
<div class="actions charitable-clear"><?php //echo $addon['action']; ?> |
| 616 |
<?php |
| 617 |
if ( ! empty( $addon['status'] ) && $addon['action'] !== 'upgrade' && $addon['action'] !== 'license' && $addon['plugin_allow'] ) : |
| 618 |
$action_class = 'action-button'; |
| 619 |
?> |
| 620 |
<div class="status"> |
| 621 |
<strong> |
| 622 |
<?php |
| 623 |
printf( |
| 624 |
/* translators: %s - addon status label. */ |
| 625 |
esc_html__( 'Status: %s', 'charitable' ), |
| 626 |
'<span class="status-label status-' . esc_attr( $addon['status'] ) . '">' . wp_kses_post( $status_label ) . '</span>' |
| 627 |
); |
| 628 |
?> |
| 629 |
</strong> |
| 630 |
</div> |
| 631 |
<?php |
| 632 |
endif; |
| 633 |
|
| 634 |
$action_class = empty( $action_class ) ? 'upgrade-button' : $action_class; |
| 635 |
?> |
| 636 |
<div class="<?php echo esc_attr( $action_class ); ?>"> |
| 637 |
<?php echo $button; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?> |
| 638 |
</div> |
| 639 |
</div> |
| 640 |
</div> |
| 641 |
</div> |
| 642 |
|
| 643 |
<?php |
| 644 |
|
| 645 |
} |
| 646 |
|
| 647 |
/** |
| 648 |
* Get addon button HTML. |
| 649 |
* |
| 650 |
* @since 1.6.7 |
| 651 |
* |
| 652 |
* @param array $addon Prepared addon data. |
| 653 |
* |
| 654 |
* @return string |
| 655 |
*/ |
| 656 |
private function get_addon_button_html( $addon ) { |
| 657 |
|
| 658 |
if ( $addon['action'] === 'upgrade' || $addon['action'] === 'license' || ! $addon['plugin_allow'] ) { |
| 659 |
|
| 660 |
if ( charitable_is_pro() ) { |
| 661 |
|
| 662 |
// go ahead and send those who have a license key added to the checkout page, but down the road we will send them to the pricing page and then customize the prices on the pricing page to reflect the upgrade amounts per plan. |
| 663 |
|
| 664 |
$license_data_to_send = $this->get_license_key_for_upgrade(); |
| 665 |
|
| 666 |
if ( false !== $license_data_to_send && isset( $license_data_to_send['license'] ) ) { |
| 667 |
|
| 668 |
$upid = 0; // the upgrade plan id. |
| 669 |
|
| 670 |
if ( in_array( 'agency', $addon['license'] ) ) { // if the desired addon is in the agency category license, we need to pass along the upgrade plan id of 4 |
| 671 |
$upid = 4; |
| 672 |
} |
| 673 |
|
| 674 |
if ( in_array( 'pro', $addon['license'] ) ) { // if the desired addon is in the pro category license, we need to pass along the upgrade plan id of 3 |
| 675 |
$upid = 3; |
| 676 |
} |
| 677 |
|
| 678 |
if ( in_array( 'plus', $addon['license'] ) ) { // if the desired addon is in the plus category license, we need to pass along the upgrade plan id of 2 |
| 679 |
$upid = 2; |
| 680 |
} |
| 681 |
|
| 682 |
// we have a valid license that we could get an upgrade path, etc. from |
| 683 |
$upgrade_url = charitable_ga_url( |
| 684 |
// pid = plan_id |
| 685 |
Charitable_Addons_Directory::UPDATE_URL . '/?license_upgrade=true&license_key=' . $license_data_to_send['license'] . '&upid=' . $upid . '&pid=' . $license_data_to_send['plan_id'] . '&addon=' . esc_html( $addon['name'] ), |
| 686 |
urlencode( 'Plugin Addon Page' ), |
| 687 |
urlencode( $addon['name'] . ' Upgrade' ) |
| 688 |
); |
| 689 |
|
| 690 |
} else { |
| 691 |
|
| 692 |
// they may be on 'pro' mode but they don't have a license we can send, so fall back to sending them to the pricing page. |
| 693 |
$upgrade_url = charitable_ga_url( |
| 694 |
'https://www.wpcharitable.com/pricing/', |
| 695 |
urlencode( 'Plugin Addon Page' ), |
| 696 |
urlencode( $addon['name'] . ' Upgrade' ) |
| 697 |
); |
| 698 |
|
| 699 |
} |
| 700 |
|
| 701 |
|
| 702 |
} else { |
| 703 |
// they are on lite, with no license so send them to the pricing page. |
| 704 |
$upgrade_url = charitable_ga_url( |
| 705 |
'https://www.wpcharitable.com/pricing/', |
| 706 |
urlencode( 'Plugin Addon Page' ), |
| 707 |
urlencode( $addon['name'] . ' Upgrade' ) |
| 708 |
); |
| 709 |
} |
| 710 |
|
| 711 |
return sprintf( |
| 712 |
'<a href="%1$s" target="_blank" rel="noopener noreferrer" class="charitable-btn charitable-btn-orange">%2$s</a>', |
| 713 |
$upgrade_url, |
| 714 |
esc_html__( 'Upgrade Now', 'charitable' ) |
| 715 |
); |
| 716 |
} |
| 717 |
|
| 718 |
$html = ''; |
| 719 |
|
| 720 |
// Override to account for odd setup prior to new ownership. |
| 721 |
$addon['path'] = str_replace( 'charitable-recurring-donations', 'charitable-recurring', $addon['path'] ); |
| 722 |
|
| 723 |
// Apply filter, mostly for testing and troubleshooting. |
| 724 |
$addon = apply_filters( 'get_addon_button_html_addon', $addon ); |
| 725 |
|
| 726 |
switch ( $addon['status'] ) { |
| 727 |
case 'active': |
| 728 |
$html = '<button class="status-' . esc_attr( $addon['status'] ) . '" data-plugin="' . esc_attr( $addon['path'] ) . '" data-type="addon">'; |
| 729 |
$html .= esc_html__( 'Deactivate', 'charitable' ); |
| 730 |
$html .= '</button>'; |
| 731 |
break; |
| 732 |
|
| 733 |
case 'installed': |
| 734 |
$html = '<button class="status-' . esc_attr( $addon['status'] ) . '" data-plugin="' . esc_attr( $addon['path'] ) . '" data-type="addon">'; |
| 735 |
$html .= esc_html__( 'Activate', 'charitable' ); |
| 736 |
$html .= '</button>'; |
| 737 |
break; |
| 738 |
|
| 739 |
case 'missing': |
| 740 |
if ( ! $this->can_install ) { |
| 741 |
break; |
| 742 |
} |
| 743 |
$html = '<button class="status-' . esc_attr( $addon['status'] ) . '" data-plugin="' . esc_url( $addon['install'] ) . '" data-type="addon">'; |
| 744 |
$html .= esc_html__( 'Install Addon', 'charitable' ); |
| 745 |
$html .= '</button>'; |
| 746 |
break; |
| 747 |
} |
| 748 |
|
| 749 |
return $html; |
| 750 |
} |
| 751 |
|
| 752 |
|
| 753 |
/** |
| 754 |
* Get addon status label. |
| 755 |
* |
| 756 |
* @since 1.6.7 |
| 757 |
* |
| 758 |
* @param string $status Addon status. |
| 759 |
* |
| 760 |
* @return string |
| 761 |
*/ |
| 762 |
private function get_addon_status_label( $status ) { |
| 763 |
|
| 764 |
$label = [ |
| 765 |
'active' => esc_html__( 'Active', 'charitable' ), |
| 766 |
'installed' => esc_html__( 'Inactive', 'charitable' ), |
| 767 |
'missing' => esc_html__( 'Not Installed', 'charitable' ), |
| 768 |
]; |
| 769 |
|
| 770 |
return isset( $label[ $status ] ) ? $label[ $status ] : ''; |
| 771 |
} |
| 772 |
|
| 773 |
|
| 774 |
/** |
| 775 |
* Prepare addon data. |
| 776 |
* |
| 777 |
* @since 1.6.6 |
| 778 |
* |
| 779 |
* @param array $addon Addon data. |
| 780 |
* |
| 781 |
* @return array Extended addon data. |
| 782 |
*/ |
| 783 |
protected function prepare_addon_data( $addon ) { |
| 784 |
|
| 785 |
if ( empty( $addon ) ) { |
| 786 |
return []; |
| 787 |
} |
| 788 |
|
| 789 |
$addon['title'] = ! empty( $addon['title'] ) ? $addon['title'] : ''; |
| 790 |
$addon['slug'] = ! empty( $addon['slug'] ) ? $addon['slug'] : ''; |
| 791 |
|
| 792 |
// We need the cleared name of the addon, without the ' addon' suffix, for further use. |
| 793 |
// $addon['name'] = preg_replace( '/ addon$/i', '', $addon['title'] ); |
| 794 |
|
| 795 |
/* translators: %s - addon name. */ |
| 796 |
$addon['modal_name'] = sprintf( esc_html__( '%s addon', 'charitable' ), $addon['name'] ); |
| 797 |
$addon['clear_slug'] = str_replace( 'charitable-', '', $addon['slug'] ); |
| 798 |
$addon['utm_content'] = ucwords( str_replace( '-', ' ', $addon['clear_slug'] ) ); |
| 799 |
$addon['license'] = empty( $addon['license'] ) ? [] : (array) $addon['license']; |
| 800 |
$addon['license_level'] = $this->get_license_level( $addon ); |
| 801 |
$addon['icon'] = ! empty( $addon['icon'] ) ? $addon['icon'] : ''; |
| 802 |
$addon['path'] = sprintf( '%1$s/%1$s.php', $addon['slug'] ); |
| 803 |
$addon['video'] = ! empty( $addon['video'] ) ? $addon['video'] : ''; |
| 804 |
$addon['plugin_allow'] = $this->has_access( $addon ); |
| 805 |
$addon['status'] = 'missing'; |
| 806 |
$addon['action'] = 'upgrade'; |
| 807 |
$addon['page_url'] = empty( $addon['url'] ) ? '' : $addon['url']; |
| 808 |
$addon['doc_url'] = empty( $addon['doc'] ) ? '' : $addon['doc']; |
| 809 |
$addon['url'] = ''; |
| 810 |
|
| 811 |
static $nonce = ''; |
| 812 |
$nonce = empty( $nonce ) ? wp_create_nonce( 'charitable-admin' ) : $nonce; |
| 813 |
$addon['nonce'] = $nonce; |
| 814 |
|
| 815 |
return $addon; |
| 816 |
} |
| 817 |
|
| 818 |
|
| 819 |
/** |
| 820 |
* Get available addon data by slug. |
| 821 |
* |
| 822 |
* @since 1.6.6 |
| 823 |
* |
| 824 |
* @param string $slug Addon slug, can be both "charitable-drip" and "drip". |
| 825 |
* |
| 826 |
* @return array Single addon data. Empty array if addon is not found. |
| 827 |
*/ |
| 828 |
public function get_addon( $slug ) { |
| 829 |
|
| 830 |
$slug = 'charitable-' . str_replace( 'charitable-', '', sanitize_key( $slug ) ); |
| 831 |
|
| 832 |
$addon = ! empty( $this->available_addons[ $slug ] ) ? $this->available_addons[ $slug ] : []; |
| 833 |
|
| 834 |
// In case if addon is "not available" let's try to get and prepare addon data from all addons. |
| 835 |
if ( empty( $addon ) ) { |
| 836 |
$addon = ! empty( $this->addons[ $slug ] ) ? $this->prepare_addon_data( $this->addons[ $slug ] ) : []; |
| 837 |
} |
| 838 |
|
| 839 |
return $addon; |
| 840 |
} |
| 841 |
|
| 842 |
/** |
| 843 |
* Get license level of the addon. |
| 844 |
* |
| 845 |
* @since 1.6.6 |
| 846 |
* |
| 847 |
* @param array|string $addon Addon data array OR addon slug. |
| 848 |
* |
| 849 |
* @return string License level: pro | elite. |
| 850 |
*/ |
| 851 |
private function get_license_level( $addon ) { |
| 852 |
|
| 853 |
if ( empty( $addon ) ) { |
| 854 |
return ''; |
| 855 |
} |
| 856 |
|
| 857 |
$addon = is_string( $addon ) ? $this->get_addon( $addon ) : $addon; |
| 858 |
$addon['license'] = empty( $addon['license'] ) ? [] : (array) $addon['license']; |
| 859 |
|
| 860 |
// TODO: convert to a class constant when we will drop PHP 5.5. |
| 861 |
$levels = [ 'basic', 'plus', 'pro', 'elite', 'agency', 'ultimate' ]; |
| 862 |
$license = ''; |
| 863 |
|
| 864 |
foreach ( $levels as $level ) { |
| 865 |
if ( in_array( $level, $addon['license'], true ) ) { |
| 866 |
$license = $level; |
| 867 |
|
| 868 |
break; |
| 869 |
} |
| 870 |
} |
| 871 |
|
| 872 |
if ( empty( $license ) ) { |
| 873 |
return ''; |
| 874 |
} |
| 875 |
|
| 876 |
return in_array( $license, [ 'basic', 'plus', 'pro' ], true ) ? 'pro' : 'elite'; |
| 877 |
} |
| 878 |
|
| 879 |
/** |
| 880 |
* This attempts to send the BEST license key to Charitable whenever a suggested upgrade is possible. |
| 881 |
* Note: We look for "v2" licenses in settings first, then attempt to locate a charitable basic/plus/pro/agency (new or oldschool) license. |
| 882 |
* We don't return individual addons in this function because there's no good way to suggest an upgrade EDD license path. |
| 883 |
* |
| 884 |
* @since 1.7.0.4 |
| 885 |
* |
| 886 |
* @return array |
| 887 |
*/ |
| 888 |
private function get_license_key_for_upgrade() { |
| 889 |
|
| 890 |
$settings = get_option( 'charitable_settings' ); |
| 891 |
if ( isset( $settings['licenses']['charitable-v2']['license'] ) && ! empty( $settings['licenses']['charitable-v2']['license'] ) ) { |
| 892 |
|
| 893 |
// attempt to grab the "v2" license |
| 894 |
$license = esc_html( $settings['licenses']['charitable-v2']['license'] ); |
| 895 |
$plan_id = isset( $settings['licenses']['charitable-v2']['plan_id'] ) && ! empty( $settings['licenses']['charitable-v2']['plan_id'] ) ? intval( $settings['licenses']['charitable-v2']['plan_id'] ) : false; |
| 896 |
return array( 'license' => $license, 'plan_id' => $plan_id ); |
| 897 |
|
| 898 |
} else if ( isset( $settings['licenses']['charitable'] ) && ! empty( $settings['licenses']['charitable'] ) ) { |
| 899 |
|
| 900 |
$license = esc_html( $settings['licenses']['charitable'] ); |
| 901 |
return array( 'license' => $license, 'plan_id' => false ); // no plan id when this was added into settings. |
| 902 |
|
| 903 |
} else if ( isset( $settings['licenses']['charitable_pro'] ) && ! empty( $settings['licenses']['charitable_pro'] ) ) { |
| 904 |
|
| 905 |
// unlikely but technically possible. |
| 906 |
$license = esc_html( $settings['licenses']['charitable_pro'] ); |
| 907 |
return array( 'license' => $license, 'plan_id' => false ); // no plan id when this was added into settings. |
| 908 |
|
| 909 |
} |
| 910 |
|
| 911 |
return false; |
| 912 |
|
| 913 |
} |
| 914 |
|
| 915 |
/** |
| 916 |
* Determine if user's license level has access. |
| 917 |
* |
| 918 |
* @since 1.6.6 |
| 919 |
* |
| 920 |
* @param array|string $addon Addon data array OR addon slug. |
| 921 |
* |
| 922 |
* @return bool |
| 923 |
*/ |
| 924 |
protected function has_access( $addon ) { |
| 925 |
|
| 926 |
return true; |
| 927 |
|
| 928 |
} |
| 929 |
|
| 930 |
|
| 931 |
/** |
| 932 |
* Return the latest versions of Charitable plugins. |
| 933 |
* |
| 934 |
* @since 1.7.0.4 |
| 935 |
* |
| 936 |
* @return array |
| 937 |
*/ |
| 938 |
public function get_addons_data_from_server( $licenses = false ) { |
| 939 |
|
| 940 |
$versions = false; |
| 941 |
|
| 942 |
// if ( ! defined( 'CHARITABLE_DEBUG' ) ) { |
| 943 |
$versions = get_transient( '_charitable_plugin_versions' ); |
| 944 |
// } |
| 945 |
|
| 946 |
if ( false === $versions ) { |
| 947 |
|
| 948 |
if ( false === $licenses ) { |
| 949 |
|
| 950 |
$licenses = array(); |
| 951 |
|
| 952 |
foreach ( $this->get_licenses() as $license ) { |
| 953 |
if ( isset( $license['license'] ) ) { |
| 954 |
$licenses[] = $license['license']; |
| 955 |
} |
| 956 |
} |
| 957 |
|
| 958 |
} |
| 959 |
|
| 960 |
$response = wp_remote_post( |
| 961 |
Charitable_Addons_Directory::UPDATE_URL . '/edd-api/versions-v3/', |
| 962 |
array( |
| 963 |
'sslverify' => false, |
| 964 |
'timeout' => 15, |
| 965 |
'body' => array( |
| 966 |
'licenses' => $licenses, |
| 967 |
'url' => home_url(), |
| 968 |
), |
| 969 |
) |
| 970 |
); |
| 971 |
|
| 972 |
$response_body = wp_remote_retrieve_body( $response ); |
| 973 |
$response_code = wp_remote_retrieve_response_code( $response ); |
| 974 |
|
| 975 |
// Bail out early if there are any errors. |
| 976 |
if ( (int) $response_code !== 200 || is_wp_error( $response_body ) ) { |
| 977 |
return false; |
| 978 |
} |
| 979 |
|
| 980 |
$versions = json_decode( $response_body, true ); |
| 981 |
|
| 982 |
set_transient( '_charitable_plugin_versions', $versions, DAY_IN_SECONDS ); |
| 983 |
|
| 984 |
} // end if |
| 985 |
|
| 986 |
return $versions; |
| 987 |
|
| 988 |
} |
| 989 |
|
| 990 |
/** |
| 991 |
* Return the latest versions of Charitable plugins. |
| 992 |
* |
| 993 |
* @since 1.4.0 |
| 994 |
* |
| 995 |
* @return array |
| 996 |
*/ |
| 997 |
protected function get_versions() { |
| 998 |
$versions = wp_cache_get( 'plugin_versions', 'charitable' ); |
| 999 |
|
| 1000 |
if ( false === $versions ) { |
| 1001 |
|
| 1002 |
$licenses = array(); |
| 1003 |
|
| 1004 |
foreach ( $this->get_licenses() as $license ) { |
| 1005 |
if ( isset( $license['license'] ) ) { |
| 1006 |
$licenses[] = $license['license']; |
| 1007 |
} |
| 1008 |
} |
| 1009 |
|
| 1010 |
$response = wp_remote_post( |
| 1011 |
Charitable_Addons_Directory::UPDATE_URL . '/edd-api/versions-v2/', |
| 1012 |
array( |
| 1013 |
'sslverify' => false, |
| 1014 |
'timeout' => 15, |
| 1015 |
'body' => array( |
| 1016 |
'licenses' => $licenses, |
| 1017 |
'url' => home_url(), |
| 1018 |
), |
| 1019 |
) |
| 1020 |
); |
| 1021 |
|
| 1022 |
$versions = wp_remote_retrieve_body( $response ); |
| 1023 |
|
| 1024 |
$versions = json_decode( $versions, true ); |
| 1025 |
|
| 1026 |
wp_cache_set( 'plugin_versions', $versions, 'charitable' ); |
| 1027 |
} // end if |
| 1028 |
|
| 1029 |
return $versions; |
| 1030 |
} |
| 1031 |
|
| 1032 |
/** |
| 1033 |
* Return the list of licenses. |
| 1034 |
* |
| 1035 |
* Note: The licenses are not necessarily valid. If a user enters an invalid |
| 1036 |
* license, the license will be stored but it will be flagged as invalid. |
| 1037 |
* |
| 1038 |
* @since 1.0.0 |
| 1039 |
* |
| 1040 |
* @return array[] |
| 1041 |
*/ |
| 1042 |
public function get_licenses() { |
| 1043 |
if ( ! isset( $this->licenses ) ) { |
| 1044 |
$this->licenses = charitable_get_option( 'licenses', array() ); |
| 1045 |
} |
| 1046 |
|
| 1047 |
return $this->licenses; |
| 1048 |
} |
| 1049 |
|
| 1050 |
} |
| 1051 |
|
| 1052 |
endif; |
| 1053 |
|