| @@ -64,16 +64,79 @@ | ||
| 64 | 64 | if(is_dir($logs_dir) && is_writable($logs_dir)) |
| 65 | 65 | if(!is_file($htaccess = $logs_dir.'/.htaccess') || !apply_filters('ws_plugin__s2member_preserve_logs_dir_htaccess', !is_writable($logs_dir.'/.htaccess'), get_defined_vars())) |
| 66 | 66 | file_put_contents($htaccess, trim(c_ws_plugin__s2member_utilities::evl(file_get_contents($GLOBALS['WS_PLUGIN__']['s2member']['c']['logs_dir_htaccess'])))); |
| 67 | 67 | |
| 68 | + //260916.2137 Detect a genuinely fresh activation before creating the options row; missing options on any prior installation must retain legacy EOT demotion behavior. | |
| 69 | + $fresh_install = !get_option('ws_plugin__s2member_activated_version') && !is_array(get_option('ws_plugin__s2member_options')); | |
| 70 | + | |
| 68 | 71 | (!is_array(get_option('ws_plugin__s2member_cache'))) ? update_option('ws_plugin__s2member_cache', array()) : NULL; |
| 69 | 72 | (!is_array(get_option('ws_plugin__s2member_notices'))) ? update_option('ws_plugin__s2member_notices', array()) : NULL; |
| 70 | 73 | (!is_array(get_option('ws_plugin__s2member_options'))) ? update_option('ws_plugin__s2member_options', array()) : NULL; |
| 71 | 74 | (!is_numeric(get_option('ws_plugin__s2member_configured'))) ? update_option('ws_plugin__s2member_configured', '0') : NULL; |
| 72 | 75 | |
| 76 | + $options = (array)get_option('ws_plugin__s2member_options'); | |
| 77 | + if(!array_key_exists('eot_demotion_from', $options)) | |
| 78 | + { | |
| 79 | + $options['eot_demotion_from'] = $fresh_install ? 's2member_level' : 'all'; | |
| 80 | + update_option('ws_plugin__s2member_options', $options); | |
| 81 | + if(is_multisite() && is_main_site()) | |
| 82 | + update_site_option('ws_plugin__s2member_options', $options); | |
| 83 | + } | |
| 84 | + unset($fresh_install, $options); | |
| 85 | + | |
| 86 | + //260902.0420 A Framework activation/update invalidates cached Pro update availability; the next admin request will refresh it in the background. | |
| 87 | + if($reactivation_reason === '' || $reactivation_reason === 'version') | |
| 88 | + { | |
| 89 | + $options = (array)get_option('ws_plugin__s2member_options'); | |
| 90 | + if(isset($options['pro_latest_version'])) | |
| 91 | + { | |
| 92 | + unset($options['pro_latest_version']); | |
| 93 | + $options = ws_plugin__s2member_configure_options_and_their_defaults($options); | |
| 94 | + update_option('ws_plugin__s2member_options', $options); | |
| 95 | + if(is_multisite() && is_main_site()) | |
| 96 | + update_site_option('ws_plugin__s2member_options', $options); | |
| 97 | + } | |
| 98 | + unset($options); | |
| 99 | + } | |
| 100 | + | |
| 101 | + //260809 Seed hashed Defuse key mappings on activation after installation or updates; migration is idempotent. | |
| 102 | + c_ws_plugin__s2member_utils_defuse::migrate_legacy_defuse_key_mappings(); | |
| 103 | + | |
| 73 | 104 | if($GLOBALS['WS_PLUGIN__']['s2member']['c']['configured']) // If we are re-activating. |
| 74 | 105 | { |
| 75 | 106 | $v = get_option('ws_plugin__s2member_activated_version'); // Currently. |
| 107 | + | |
| 108 | + //260822.2048 Older EOT demotions recorded their processing time only in Administrative Notes; recover that history asynchronously where the legacy note is still available. | |
| 109 | + if(!$v || version_compare($v, '260822.2048', '<')) | |
| 110 | + c_ws_plugin__s2member_auto_eots::start_eot_processed_time_backfill(); | |
| 111 | + | |
| 112 | + //260824.1727 Refresh existing Checkout webhooks once more to add dispute-created notifications. | |
| 113 | + if(!$v || version_compare($v, '260824.1727', '<')) | |
| 114 | + { | |
| 115 | + $ppco_webhook_envs = array( | |
| 116 | + 'live' => array( | |
| 117 | + 'client_id' => (string)$GLOBALS['WS_PLUGIN__']['s2member']['o']['paypal_checkout_client_id'], | |
| 118 | + 'secret' => (string)$GLOBALS['WS_PLUGIN__']['s2member']['o']['paypal_checkout_client_secret'], | |
| 119 | + 'webhook_id' => (string)$GLOBALS['WS_PLUGIN__']['s2member']['o']['paypal_checkout_webhook_id'], | |
| 120 | + ), | |
| 121 | + 'sandbox' => array( | |
| 122 | + 'client_id' => (string)$GLOBALS['WS_PLUGIN__']['s2member']['o']['paypal_checkout_sandbox_client_id'], | |
| 123 | + 'secret' => (string)$GLOBALS['WS_PLUGIN__']['s2member']['o']['paypal_checkout_sandbox_client_secret'], | |
| 124 | + 'webhook_id' => (string)$GLOBALS['WS_PLUGIN__']['s2member']['o']['paypal_checkout_sandbox_webhook_id'], | |
| 125 | + ), | |
| 126 | + ); | |
| 127 | + foreach($ppco_webhook_envs as $ppco_webhook_env => $ppco_webhook_config) | |
| 128 | + if($ppco_webhook_config['client_id'] && $ppco_webhook_config['secret'] && $ppco_webhook_config['webhook_id']) | |
| 129 | + if(!c_ws_plugin__s2member_paypal_utilities::paypal_checkout_webhook_upsert($ppco_webhook_env, TRUE)) | |
| 130 | + { | |
| 131 | + $ppco_webhook_env_label = ($ppco_webhook_env === 'sandbox') ? 'Sandbox' : 'Live'; | |
| 132 | + $ppco_webhook_settings_url = add_query_arg('s2member-open-panel', 'paypal-checkout', admin_url('/admin.php?page=ws-plugin--s2member-paypal-ops')).'#ws-plugin--s2member-paypal-checkout'; | |
| 133 | + | |
| 134 | + //260824.0507 Mark this persistent warning so a later successful reconciliation can remove it automatically. | |
| 135 | + $notice = '<span class="s2member-ppco-webhook-upgrade-notice-'.esc_attr($ppco_webhook_env).'"><strong>s2Member PayPal Checkout:</strong> Your '.esc_html($ppco_webhook_env_label).' webhook could not be updated automatically with the latest required events. Please go to <a href="'.esc_url($ppco_webhook_settings_url).'"><strong>s2Member → PayPal Options → PayPal Checkout</strong></a> and click <strong>Create/Update Webhook</strong> for '.esc_html($ppco_webhook_env_label).'.</span>'; | |
| 136 | + c_ws_plugin__s2member_admin_notices::enqueue_admin_notice($notice, array(), TRUE, 0, TRUE); | |
| 137 | + } | |
| 138 | + } | |
| 76 | 139 | |
| 77 | 140 | if(!$v || !version_compare($v, '3.2', '>=')) // Needs to be upgraded? |
| 78 | 141 | // Version 3.2 is where `meta_key` names were changed. They're prefixed now. |
| 79 | 142 | { |