class-fs-client-addon-migration-abstract.php
6 years ago
class-fs-client-license-abstract.php
6 years ago
class-fs-client-migration-abstract.php
7 months ago
class-fs-edd-client-migration.php
6 years ago
class-fs-wc-client-migration.php
6 years ago
edd.php
1 year ago
index.php
6 years ago
edd.php
517 lines
| 1 | <?php |
| 2 | /** |
| 3 | * @package Freemius Migration |
| 4 | * @copyright Copyright (c) 2016, Freemius, Inc. |
| 5 | * @license http://opensource.org/licenses/gpl-2.0.php GNU Public License |
| 6 | * @since 1.0.3 |
| 7 | */ |
| 8 | |
| 9 | if ( ! defined( 'ABSPATH' ) ) { |
| 10 | exit; |
| 11 | } |
| 12 | |
| 13 | if ( ! class_exists( 'FS_Client_License_Abstract_v2' ) ) { |
| 14 | require_once dirname( __FILE__ ) . '/class-fs-client-license-abstract.php'; |
| 15 | } |
| 16 | |
| 17 | if ( ! class_exists( 'FS_EDD_Client_Migration_v2' ) ) { |
| 18 | require_once dirname( __FILE__ ) . '/class-fs-edd-client-migration.php'; |
| 19 | } |
| 20 | |
| 21 | /** |
| 22 | * You should use your own unique CLASS name, and be sure to replace it |
| 23 | * throughout this file. For example, if your product's name is "Awesome Product" |
| 24 | * then you can rename it to "Awesome_Product_EDD_License_Key". |
| 25 | */ |
| 26 | class OceanWP_EDD_License_Key extends FS_Client_License_Abstract_v2 { |
| 27 | /** |
| 28 | * @var array<string,string> |
| 29 | */ |
| 30 | public static $paid_addons = array( |
| 31 | 'Ocean_Cookie_Notice' => array( |
| 32 | 'name' => 'Cookie Notice', |
| 33 | 'fs_id' => '3765', |
| 34 | 'fs_shortcode' => 'ocean_cookie_notice_fs', |
| 35 | ), |
| 36 | 'Ocean_Elementor_Widgets' => array( |
| 37 | 'name' => 'Elementor Widgets', |
| 38 | 'fs_id' => '3757', |
| 39 | 'fs_shortcode' => 'ocean_elementor_widgets_fs', |
| 40 | ), |
| 41 | 'Ocean_Footer_Callout' => array( |
| 42 | 'name' => 'Footer Callout', |
| 43 | 'fs_id' => '3754', |
| 44 | 'fs_shortcode' => 'ocean_footer_callout_fs', |
| 45 | ), |
| 46 | 'Ocean_Full_Screen' => array( |
| 47 | 'name' => 'Full Screen', |
| 48 | 'fs_id' => '3766', |
| 49 | 'fs_shortcode' => 'ocean_full_screen_fs', |
| 50 | ), |
| 51 | 'Ocean_Hooks' => array( |
| 52 | 'name' => 'Ocean Hooks', |
| 53 | 'fs_id' => '3758', |
| 54 | 'fs_shortcode' => 'oh_fs', |
| 55 | ), |
| 56 | /*'Ocean_Instagram' => array( |
| 57 | 'name' => 'Instagram', |
| 58 | 'fs_id' => '3763', |
| 59 | 'fs_shortcode' => 'ocean_instagram_fs', |
| 60 | ),*/ |
| 61 | 'Ocean_Popup_Login' => array( |
| 62 | 'name' => 'Popup Login', |
| 63 | 'fs_id' => '3764', |
| 64 | 'fs_shortcode' => 'ocean_popup_login_fs', |
| 65 | ), |
| 66 | 'Ocean_Portfolio' => array( |
| 67 | 'name' => 'Portfolio', |
| 68 | 'fs_id' => '3761', |
| 69 | 'fs_shortcode' => 'ocean_portfolio_fs', |
| 70 | ), |
| 71 | 'Ocean_Pro_Demos' => array( |
| 72 | 'name' => 'Pro Demos', |
| 73 | 'fs_id' => '3797', |
| 74 | 'fs_shortcode' => 'ocean_pro_demos_fs', |
| 75 | ), |
| 76 | 'Ocean_Side_Panel' => array( |
| 77 | 'name' => 'Side Panel', |
| 78 | 'fs_id' => '3756', |
| 79 | 'fs_shortcode' => 'ocean_side_panel_fs', |
| 80 | ), |
| 81 | 'Ocean_Sticky_Footer' => array( |
| 82 | 'name' => 'Sticky Footer', |
| 83 | 'fs_id' => '3759', |
| 84 | 'fs_shortcode' => 'ocean_sticky_footer_fs', |
| 85 | ), |
| 86 | 'Ocean_Sticky_Header' => array( |
| 87 | 'name' => 'Sticky Header', |
| 88 | 'fs_id' => '3755', |
| 89 | 'fs_shortcode' => 'ocean_sticky_header_fs', |
| 90 | ), |
| 91 | 'Ocean_White_Label' => array( |
| 92 | 'name' => 'White Label', |
| 93 | 'fs_id' => '3762', |
| 94 | 'fs_shortcode' => 'ocean_white_label_fs', |
| 95 | ), |
| 96 | 'Ocean_Woo_Popup' => array( |
| 97 | 'name' => 'Woo Popup', |
| 98 | 'fs_id' => '3760', |
| 99 | 'fs_shortcode' => 'ocean_woo_popup_fs', |
| 100 | ), |
| 101 | ); |
| 102 | |
| 103 | public static $separate_addons = array( |
| 104 | 'Ocean_eCommerce' => array( |
| 105 | 'name' => 'Ocean Treasure Box', |
| 106 | 'fs_id' => '11449', |
| 107 | 'fs_shortcode' => 'oet_fs', |
| 108 | ), |
| 109 | 'Ocean_Gutenberg_Blocks' => array( |
| 110 | 'name' => 'Ocean Gutenberg Blocks', |
| 111 | 'fs_id' => '9081', |
| 112 | 'fs_shortcode' => 'ocean_gutenberg_blocks_fs', |
| 113 | ), |
| 114 | 'Ocean_SiteBooster' => array( |
| 115 | 'name' => 'Ocean Site Booster', |
| 116 | 'fs_id' => '17389', |
| 117 | 'fs_shortcode' => 'osb_fs', |
| 118 | ), |
| 119 | ); |
| 120 | |
| 121 | private $_is_valid; |
| 122 | private $_is_bundle; |
| 123 | private $_addon_class; |
| 124 | private $_addon_license_index; |
| 125 | private $_logger; |
| 126 | |
| 127 | /** |
| 128 | * OceanWP_EDD_License_Key constructor. |
| 129 | * |
| 130 | * @param bool $is_bundle |
| 131 | * @param string $addon_class |
| 132 | * @param string $addon_name |
| 133 | */ |
| 134 | function __construct( $is_bundle, $addon_class = '', $addon_name = '' ) { |
| 135 | $this->_is_bundle = $is_bundle; |
| 136 | $this->_addon_class = $addon_class; |
| 137 | $this->_addon_license_index = sprintf( |
| 138 | 'oceanwp_%s_license_key', |
| 139 | preg_replace( '/[^a-zA-Z0-9_\s]/', '', str_replace( ' ', '_', strtolower( $addon_name ) ) ) |
| 140 | ); |
| 141 | $this->_is_valid = true; |
| 142 | |
| 143 | if ( ! $is_bundle ) { |
| 144 | $this->_is_valid = ( |
| 145 | isset( self::$paid_addons[ $addon_class ] ) && |
| 146 | $addon_name === self::$paid_addons[ $addon_class ]['name'] |
| 147 | ); |
| 148 | } |
| 149 | |
| 150 | $this->_logger = FS_Logger::get_logger( |
| 151 | WP_FS__SLUG . '_oceanwp_migration_' . ($is_bundle ? 'bundle' : $addon_class), |
| 152 | WP_FS__DEBUG_SDK, |
| 153 | WP_FS__ECHO_DEBUG_SDK |
| 154 | ); |
| 155 | } |
| 156 | |
| 157 | /** |
| 158 | * @author Vova Feldman (@svovaf) |
| 159 | * @since 1.0.3 |
| 160 | * |
| 161 | * @param int|null $blog_id |
| 162 | * |
| 163 | * @return string |
| 164 | */ |
| 165 | function get( $blog_id = null ) { |
| 166 | if ( ! $this->_is_valid ) { |
| 167 | return ''; |
| 168 | } |
| 169 | |
| 170 | if ( $this->_is_bundle ) { |
| 171 | return trim( get_option( 'oceanwp_bundle_key', '' ) ); |
| 172 | } |
| 173 | |
| 174 | $oceanwp_options = get_option( 'oceanwp_options', '' ); |
| 175 | |
| 176 | if ( ! is_array( $oceanwp_options ) || ! isset( $oceanwp_options['licenses'] ) ) { |
| 177 | return ''; |
| 178 | } |
| 179 | |
| 180 | return isset( $oceanwp_options['licenses'][ $this->_addon_license_index ] ) ? |
| 181 | trim( $oceanwp_options['licenses'][ $this->_addon_license_index ] ) : |
| 182 | ''; |
| 183 | } |
| 184 | |
| 185 | /** |
| 186 | * When migrating a bundle license and the sales platform creates a different |
| 187 | * license key for every product in the bundle which is the key that actually |
| 188 | * used for activation, this method should return the collection of all |
| 189 | * child license keys that were activated on the current website. |
| 190 | * |
| 191 | * @author Vova Feldman (@svovaf) |
| 192 | * @since 1.1.0 |
| 193 | * |
| 194 | * @param int|null $blog_id |
| 195 | * |
| 196 | * @return string[] |
| 197 | */ |
| 198 | function get_children( $blog_id = null ) { |
| 199 | if ( ! $this->_is_valid ) { |
| 200 | return array(); |
| 201 | } |
| 202 | |
| 203 | $oceanwp_options = get_option( 'oceanwp_options', '' ); |
| 204 | |
| 205 | if ( ! is_array( $oceanwp_options ) || ! isset( $oceanwp_options['licenses'] ) ) { |
| 206 | return array(); |
| 207 | } |
| 208 | |
| 209 | $children_license_keys = array(); |
| 210 | foreach ( self::$paid_addons as $class_name => $data ) { |
| 211 | $index = sprintf( |
| 212 | 'oceanwp_%s_license_key', |
| 213 | preg_replace( '/[^a-zA-Z0-9_\s]/', '', str_replace( ' ', '_', strtolower( $data['name'] ) ) ) |
| 214 | );; |
| 215 | |
| 216 | if ( isset( $oceanwp_options['licenses'][ $index ] ) ) { |
| 217 | $children_license_keys[] = trim( $oceanwp_options['licenses'][ $index ] ); |
| 218 | } |
| 219 | } |
| 220 | |
| 221 | return $children_license_keys; |
| 222 | } |
| 223 | |
| 224 | /** |
| 225 | * @author Vova Feldman (@svovaf) |
| 226 | * @since 1.0.3 |
| 227 | * |
| 228 | * @param string $license_key |
| 229 | * @param int|null $blog_id |
| 230 | * |
| 231 | * @return bool True if successfully updated. |
| 232 | */ |
| 233 | function set( $license_key, $blog_id = null ) { |
| 234 | if ( ! $this->_is_valid ) { |
| 235 | return false; |
| 236 | } |
| 237 | |
| 238 | if ( $this->_is_bundle ) { |
| 239 | $option_name = 'oceanwp_bundle_key'; |
| 240 | $option_value = $license_key; |
| 241 | } else { |
| 242 | $option_name = 'oceanwp_options'; |
| 243 | |
| 244 | $oceanwp_options = get_option( $option_name, '' ); |
| 245 | |
| 246 | if ( ! is_array( $oceanwp_options ) ) { |
| 247 | $oceanwp_options = array( 'licenses' => array() ); |
| 248 | } else if ( ! isset( $oceanwp_options['licenses'] ) ) { |
| 249 | $oceanwp_options['licenses'] = array(); |
| 250 | } |
| 251 | |
| 252 | $oceanwp_options['licenses'][ $this->_addon_license_index ] = $license_key; |
| 253 | |
| 254 | $option_value = $oceanwp_options; |
| 255 | } |
| 256 | |
| 257 | if ( ! is_multisite() ) { |
| 258 | return update_option( $option_name, $option_value ); |
| 259 | } |
| 260 | |
| 261 | $blog_ids = FS_Client_Migration_Abstract_v2::get_blog_ids(); |
| 262 | |
| 263 | $is_updated = false; |
| 264 | foreach ( $blog_ids as $blog_id ) { |
| 265 | switch_to_blog( $blog_id ); |
| 266 | $is_updated = $is_updated || update_option( $option_name, $option_value ); |
| 267 | restore_current_blog(); |
| 268 | } |
| 269 | |
| 270 | return $is_updated; |
| 271 | } |
| 272 | |
| 273 | /** |
| 274 | * Override this only when the product supports a network level integration. |
| 275 | * |
| 276 | * @author Vova Feldman (@svovaf) |
| 277 | * @since 1.1.0 |
| 278 | * |
| 279 | * @return bool |
| 280 | */ |
| 281 | public function is_network_migration() { |
| 282 | /** |
| 283 | * Comment the line below if you'd like to support network level licenses migration. |
| 284 | * This is only relevant if you have a special network level integration with your plugin |
| 285 | * and you're utilizing the Freemius SDK's multisite network integration mode. |
| 286 | */ |
| 287 | return false; |
| 288 | } |
| 289 | |
| 290 | /** |
| 291 | * This method is only relevant when you're using the network level migration mode. |
| 292 | * The method should return true only if you restrict a network level license activation |
| 293 | * to apply the exact same license for the products network wide. |
| 294 | * |
| 295 | * For example, if a network with 5-sites can have license1 on sub-sites 1-3, |
| 296 | * and license2 on sub-sites 4-5, then the result of this method should be set to `false`. |
| 297 | * BUT, if you the only way to activate the license is that it will be the same license on |
| 298 | * all sub-sites 1-5, then this method should return `true`. |
| 299 | * |
| 300 | * @return bool |
| 301 | */ |
| 302 | public function are_licenses_network_identical() { |
| 303 | return false; |
| 304 | } |
| 305 | |
| 306 | /** |
| 307 | * Activates a bundle license on the installed child products, after successfully migrating the license. |
| 308 | * |
| 309 | * @author Vova Feldman (@svovaf) |
| 310 | * @since 2.0.0 |
| 311 | * |
| 312 | * @param \FS_User $user |
| 313 | * @param string|null $bundle_license_key |
| 314 | */ |
| 315 | public function activate_bundle_license_after_migration( FS_User $user, $bundle_license_key = null ) { |
| 316 | $this->_logger->entrance("bundle_license_key=" . var_export( $bundle_license_key, true )); |
| 317 | |
| 318 | if ( $this->_is_bundle || empty( $bundle_license_key ) ) { |
| 319 | $bundle_license_key = $this->get(); |
| 320 | } |
| 321 | |
| 322 | // Iterate over the installed add-ons and try to activate the bundle's license for each add-on. |
| 323 | foreach ( self::$paid_addons as $class_name => $data ) { |
| 324 | if ( ! class_exists( $class_name ) ) { |
| 325 | $this->_logger->log( "Class {$class_name} does not exist." ); |
| 326 | |
| 327 | continue; |
| 328 | } |
| 329 | |
| 330 | if ( ! function_exists( $data['fs_shortcode'] ) ) { |
| 331 | $this->_logger->log( "Function {$data['fs_shortcode']} does not exist." ); |
| 332 | |
| 333 | continue; |
| 334 | } |
| 335 | |
| 336 | /** |
| 337 | * Initiate the Freemius instance before migrating. |
| 338 | * |
| 339 | * @var Freemius $addon_fs |
| 340 | */ |
| 341 | $addon_fs = call_user_func( $data['fs_shortcode'] ); |
| 342 | |
| 343 | $this->_logger->log( 'Starting activation of the migrated license for ' . str_replace( '_', ' ', $class_name) . '.' ); |
| 344 | |
| 345 | $addon_fs->activate_migrated_license( $bundle_license_key ); |
| 346 | } |
| 347 | } |
| 348 | } |
| 349 | |
| 350 | if ( ! class_exists( 'FS_Client_Addon_Migration_Abstract_v2' ) ) { |
| 351 | require_once dirname( __FILE__ ) . '/class-fs-client-addon-migration-abstract.php'; |
| 352 | } |
| 353 | |
| 354 | /** |
| 355 | * @todo For add-ons migration change the if condition from `false` to `true` an update the class according to the inline instructions. |
| 356 | * |
| 357 | * @author Vova Feldman (@svovaf) |
| 358 | * @since 2.0.0 |
| 359 | */ |
| 360 | if ( true ) { |
| 361 | /** |
| 362 | * You should use your own unique CLASS name, and be sure to replace it |
| 363 | * throughout this file. For example, if your product's name is "Awesome Product" |
| 364 | * then you can rename it to "Awesome_Product_EDD_Addon_Migration". |
| 365 | * |
| 366 | * @author Vova Feldman (@svovaf) |
| 367 | * @since 2.0.0 |
| 368 | * |
| 369 | * Class OceanWP_EDD_Addon_Migration |
| 370 | */ |
| 371 | class OceanWP_EDD_Addon_Migration extends FS_Client_Addon_Migration_Abstract_v2 { |
| 372 | |
| 373 | #region Singleton |
| 374 | |
| 375 | /** |
| 376 | * @var FS_Client_Addon_Migration_Abstract_v2[] |
| 377 | */ |
| 378 | protected static $_INSTANCES = array(); |
| 379 | |
| 380 | /** |
| 381 | * @param string $addon_shortcode |
| 382 | * |
| 383 | * @return FS_Client_Addon_Migration_Abstract_v2 |
| 384 | */ |
| 385 | public static function instance( $addon_shortcode ) { |
| 386 | if ( ! isset( self::$_INSTANCES[ $addon_shortcode ] ) ) { |
| 387 | self::$_INSTANCES[ $addon_shortcode ] = new self( $addon_shortcode ); |
| 388 | } |
| 389 | |
| 390 | return self::$_INSTANCES[ $addon_shortcode ]; |
| 391 | } |
| 392 | |
| 393 | /** |
| 394 | * OceanWP_EDD_Addon_Migration constructor. |
| 395 | * |
| 396 | * @param string $addon_shortcode |
| 397 | */ |
| 398 | private function __construct( $addon_shortcode ) { |
| 399 | $this->_addon_shortcode = $addon_shortcode; |
| 400 | } |
| 401 | |
| 402 | #endregion |
| 403 | |
| 404 | /** |
| 405 | * The parent product's shortcode. |
| 406 | * |
| 407 | * @author Vova Feldman (@svovaf) |
| 408 | * @since 2.0.0 |
| 409 | * |
| 410 | * @return string |
| 411 | */ |
| 412 | protected function get_parent_shortcode() { |
| 413 | return 'owp_fs'; |
| 414 | } |
| 415 | |
| 416 | /** |
| 417 | * @author Vova Feldman (@svovaf) |
| 418 | * @since 2.0.0 |
| 419 | * |
| 420 | * @return bool |
| 421 | */ |
| 422 | protected function is_parent_included() { |
| 423 | return class_exists( 'OCEANWP_Theme_Class' ); |
| 424 | } |
| 425 | |
| 426 | /** |
| 427 | * @author Vova Feldman (@svovaf) |
| 428 | * @since 2.0.0 |
| 429 | * |
| 430 | * @return array |
| 431 | */ |
| 432 | protected function get_addons_sdk_init_common_config() { |
| 433 | return array( |
| 434 | 'type' => 'plugin', |
| 435 | 'is_premium' => true, |
| 436 | 'is_premium_only' => true, |
| 437 | 'has_paid_plans' => true, |
| 438 | 'parent' => array( |
| 439 | 'id' => '3752', |
| 440 | 'slug' => 'oceanwp', |
| 441 | 'public_key' => 'pk_043077b34f20f5e11334af3c12493', |
| 442 | 'name' => 'OceanWP', |
| 443 | ), |
| 444 | 'menu' => array( |
| 445 | 'first-path' => 'plugins.php', |
| 446 | 'support' => false, |
| 447 | ), |
| 448 | ); |
| 449 | } |
| 450 | |
| 451 | /** |
| 452 | * @author Vova Feldman (@svovaf) |
| 453 | * @since 2.0.0 |
| 454 | * |
| 455 | * @param bool $is_bundle |
| 456 | * @param string $addon_class |
| 457 | * @param string $addon_name |
| 458 | * |
| 459 | * @return FS_Client_License_Abstract_v2 |
| 460 | */ |
| 461 | protected function get_new_license_key_manager( $is_bundle, $addon_class = '', $addon_name = '' ) { |
| 462 | return new OceanWP_EDD_License_Key( $is_bundle, $addon_class, $addon_name ); |
| 463 | } |
| 464 | |
| 465 | /** |
| 466 | * @todo This should point to your EDD store root URL. |
| 467 | * |
| 468 | * @author Vova Feldman (@svovaf) |
| 469 | * @since 2.0.0 |
| 470 | * |
| 471 | * @return string |
| 472 | */ |
| 473 | protected function get_store_url() { |
| 474 | return 'https://oceanwp.org'; |
| 475 | } |
| 476 | } |
| 477 | } |
| 478 | |
| 479 | $is_migration_debug = FS_Client_Addon_Migration_Abstract_v2::is_migration_debug(); |
| 480 | |
| 481 | if ( FS_Client_Addon_Migration_Abstract_v2::is_migration_on() ) { |
| 482 | if ( ! $is_migration_debug || |
| 483 | ( ! FS_Client_Addon_Migration_Abstract_v2::is_wp_ajax() && ! FS_Client_Addon_Migration_Abstract_v2::is_wp_cron() ) |
| 484 | ) { |
| 485 | $bundle_license_manager = new OceanWP_EDD_License_Key( true ); |
| 486 | |
| 487 | // @todo We need to make sure that if there's both a bundle license and individual add-on license, it first migrates the bundle’s license, and only later migrate the individual license, but only if the bundle’s migration failed. |
| 488 | |
| 489 | if ( empty( $bundle_license_manager->get() ) ) { |
| 490 | // Bundle license is not set, try to migrate per add-on. |
| 491 | do_action( 'owp_fs_client_migration_loaded' ); |
| 492 | } else { |
| 493 | // Bundle license is set, try to migrate the bundle's license. |
| 494 | new FS_EDD_Client_Migration_v2( |
| 495 | // This should be replaced with your custom Freemius shortcode. |
| 496 | owp_fs(), |
| 497 | |
| 498 | // This should point to your EDD store root URL. |
| 499 | 'https://oceanwp.org', |
| 500 | |
| 501 | // The bundle's download ID. |
| 502 | '37394', |
| 503 | |
| 504 | $bundle_license_manager, |
| 505 | |
| 506 | // Migration type. |
| 507 | FS_Client_Migration_Abstract_v2::TYPE_BUNDLE_TO_BUNDLE, |
| 508 | |
| 509 | // Freemius was NOT included in the previous (last) version of the product. |
| 510 | true, |
| 511 | |
| 512 | // For testing, you can change that argument to TRUE to trigger the migration in the same HTTP request. |
| 513 | $is_migration_debug |
| 514 | ); |
| 515 | } |
| 516 | } |
| 517 | } |