/**
  * Saves all options from any menu page.
  *
  * Can also be self-verified; and configured extensively with function parameters.
  *
  * @package s2Member\Menu_Pages
  * @since 3.5
  *
  * @param null|array $new_options Optional. Force feed an array of new options. Defaults to ``$_POST`` vars.
  *   If ``$new_options`` are passed in, be SURE that you've already applied ``stripslashes_deep()``.
  * @param bool       $verified Optional. Defaults to false. If true, ``wp_verify_nonce()`` is skipped in this routine.
  * @param bool       $update_other Optional. Defaults to true. If false, other option-dependent routines will not be processed.
  * @param bool|array $display_notices Optional. Defaults to true. Can be false, or an array of certain notices that can be displayed.
  * @param bool|array $enqueue_notices Optional. Defaults to false. Can be true, or an array of certain notices that should be enqueued.
  * @param bool       $request_refresh Optional. Defaults to false. If true, resulting `success` notice will include a link to refresh the menu page.
  *
  * @return bool True if all s2Member options were updated successfully, else false.
  */
 public static function update_all_options($new_options = NULL, $verified = FALSE, $update_other = TRUE, $display_notices = TRUE, $enqueue_notices = FALSE, $request_refresh = FALSE)
 {
     $updated_all_options = FALSE;
     // Initializing this variable here makes it an available reference-variable to Hooks/Filters.
     foreach (array_keys(get_defined_vars()) as $__v) {
         $__refs[$__v] =& ${$__v};
     }
     do_action('ws_plugin__s2member_before_update_all_options', get_defined_vars());
     // If you use this Hook, be sure to use ``wp_verify_nonce()``.
     unset($__refs, $__v);
     // Housekeeping.
     if ($verified || !empty($_POST['ws_plugin__s2member_options_save']) && ($nonce = $_POST['ws_plugin__s2member_options_save']) && wp_verify_nonce($nonce, 'ws-plugin--s2member-options-save')) {
         $options = $GLOBALS['WS_PLUGIN__']['s2member']['o'];
         // Acquire the full existing configuration options array here.
         $new_options = is_array($new_options) ? $new_options : (!empty($_POST) && is_array($_POST) ? stripslashes_deep($_POST) : array());
         $new_options = c_ws_plugin__s2member_utils_strings::trim_deep($new_options);
         foreach ($new_options as $key => $value) {
             // Find all keys contained within ``$new_options`` matching `^ws_plugin__s2member_`.
             if (strpos($key, 'ws_plugin__s2member_') === 0) {
                 // A relevant ``$new_options`` key matching `^ws_plugin__s2member_`?
                 if ($key === 'ws_plugin__s2member_configured') {
                     // s2Member is now configured (according to these options)?
                     ($GLOBALS['WS_PLUGIN__']['s2member']['c']['configured'] = $value) . update_option('ws_plugin__s2member_configured', $value);
                 } else {
                     if (!is_array($value) || is_array($value) && array_shift($value) === 'update-signal') {
                         // Updating an array?
                         $options[preg_replace('/^' . preg_quote('ws_plugin__s2member_', '/') . '/', '', $key)] = $value;
                     }
                 }
             }
         }
         unset($key, $value);
         // Unset these utility variables now. This prevents bleeding vars into Hooks/Filters that are of no use.
         foreach (array_keys(get_defined_vars()) as $__v) {
             $__refs[$__v] =& ${$__v};
         }
         do_action('ws_plugin__s2member_during_update_all_options', get_defined_vars());
         unset($__refs, $__v);
         // Housekeeping.
         $options = ws_plugin__s2member_configure_options_and_their_defaults($options = array_merge($options, array('options_version' => (string) ($options['options_version'] + 0.001))));
         update_option('ws_plugin__s2member_options', $options) . (is_multisite() && is_main_site() ? update_site_option('ws_plugin__s2member_options', $options) : NULL) . update_option('ws_plugin__s2member_cache', array());
         if ($update_other === TRUE || in_array('auto_eot_system', (array) $update_other)) {
             // Handle the Auto-EOT System now (enable/disable).
             $options['auto_eot_system_enabled'] == 1 ? c_ws_plugin__s2member_auto_eots::add_auto_eot_system() : c_ws_plugin__s2member_auto_eots::delete_auto_eot_system();
         }
         if (($display_notices === TRUE || in_array('success', (array) $display_notices)) && ($notice = '<strong>Options saved.' . ($request_refresh ? ' Please <a href="' . esc_attr($_SERVER['REQUEST_URI']) . '">refresh</a>.' : '') . '</strong>')) {
             $enqueue_notices === TRUE || in_array('success', (array) $enqueue_notices) ? c_ws_plugin__s2member_admin_notices::enqueue_admin_notice($notice, '*:*') : c_ws_plugin__s2member_admin_notices::display_admin_notice($notice);
         }
         if (empty($_GET['page']) || $_GET['page'] !== 'ws-plugin--s2member-mms-ops') {
             if (!$options['membership_options_page'] && ($display_notices === TRUE || in_array('page-conflict-warnings', (array) $display_notices)) && ($notice = '<strong>NOTE:</strong> s2Member security restrictions will NOT be enforced until you\'ve configured a Membership Options Page. See: <strong>s2Member → General Options → Membership Options Page</strong>.')) {
                 $enqueue_notices === TRUE || in_array('page-conflict-warnings', (array) $enqueue_notices) ? c_ws_plugin__s2member_admin_notices::enqueue_admin_notice($notice, '*:*', TRUE) : c_ws_plugin__s2member_admin_notices::display_admin_notice($notice, TRUE);
             }
             if ($options['login_welcome_page'] && $options['login_welcome_page'] === $options['membership_options_page'] && ($display_notices === TRUE || in_array('page-conflict-warnings', (array) $display_notices)) && ($notice = '<strong>s2Member:</strong> Your Login Welcome Page is the same as your Membership Options Page. Please correct this. See: <strong>s2Member → General Options → Login Welcome Page</strong>.')) {
                 $enqueue_notices === TRUE || in_array('page-conflict-warnings', (array) $enqueue_notices) ? c_ws_plugin__s2member_admin_notices::enqueue_admin_notice($notice, '*:*', TRUE) : c_ws_plugin__s2member_admin_notices::display_admin_notice($notice, TRUE);
             }
             if ($options['membership_options_page'] && (string) get_option('page_on_front') === $options['membership_options_page'] && ($display_notices === TRUE || in_array('page-conflict-warnings', (array) $display_notices)) && ($notice = '<strong>s2Member:</strong> Your Membership Options Page is currently configured as your Home Page (i.e., static page) for WordPress. This causes internal conflicts with s2Member. Your Membership Options Page MUST stand alone. Please correct this. See: <strong>WordPress → Reading Options</strong>. Or change: <strong>s2Member → General Options → Membership Options Page</strong>.')) {
                 $enqueue_notices === TRUE || in_array('page-conflict-warnings', (array) $enqueue_notices) ? c_ws_plugin__s2member_admin_notices::enqueue_admin_notice($notice, '*:*', TRUE) : c_ws_plugin__s2member_admin_notices::display_admin_notice($notice, TRUE);
             }
             if ($options['login_welcome_page'] && (string) get_option('page_on_front') === $options['login_welcome_page'] && ($display_notices === TRUE || in_array('page-conflict-warnings', (array) $display_notices)) && ($notice = '<strong>s2Member:</strong> Your Login Welcome Page is currently configured as your Home Page (i.e., static page) for WordPress. This causes internal conflicts with s2Member. Your Login Welcome Page MUST stand alone. Please correct this. See: <strong>WordPress → Reading Options</strong>. Or change: <strong>s2Member → General Options → Login Welcome Page</strong>.')) {
                 $enqueue_notices === TRUE || in_array('page-conflict-warnings', (array) $enqueue_notices) ? c_ws_plugin__s2member_admin_notices::enqueue_admin_notice($notice, '*:*', TRUE) : c_ws_plugin__s2member_admin_notices::display_admin_notice($notice, TRUE);
             }
             if ($options['membership_options_page'] && (string) get_option('page_for_posts') === $options['membership_options_page'] && ($display_notices === TRUE || in_array('page-conflict-warnings', (array) $display_notices)) && ($notice = '<strong>s2Member:</strong> Your Membership Options Page is currently configured as your Posts Page (i.e., static page) for WordPress. This causes internal conflicts with s2Member. Your Membership Options Page MUST stand alone. Please correct this. See: <strong>WordPress → Reading Options</strong>. Or change: <strong>s2Member → General Options → Membership Options Page</strong>.')) {
                 $enqueue_notices === TRUE || in_array('page-conflict-warnings', (array) $enqueue_notices) ? c_ws_plugin__s2member_admin_notices::enqueue_admin_notice($notice, '*:*', TRUE) : c_ws_plugin__s2member_admin_notices::display_admin_notice($notice, TRUE);
             }
             if ($options['login_welcome_page'] && (string) get_option('page_for_posts') === $options['login_welcome_page'] && ($display_notices === TRUE || in_array('page-conflict-warnings', (array) $display_notices)) && ($notice = '<strong>s2Member:</strong> Your Login Welcome Page is currently configured as your Posts Page (i.e., static page) for WordPress. This causes internal conflicts with s2Member. Your Login Welcome Page MUST stand alone. Please correct this. See: <strong>WordPress → Reading Options</strong>. Or change: <strong>s2Member → General Options → Login Welcome Page</strong>.')) {
                 $enqueue_notices === TRUE || in_array('page-conflict-warnings', (array) $enqueue_notices) ? c_ws_plugin__s2member_admin_notices::enqueue_admin_notice($notice, '*:*', TRUE) : c_ws_plugin__s2member_admin_notices::display_admin_notice($notice, TRUE);
             }
             if ($options['file_download_limit_exceeded_page'] && $options['file_download_limit_exceeded_page'] === $options['membership_options_page'] && ($display_notices === TRUE || in_array('page-conflict-warnings', (array) $display_notices)) && ($notice = '<strong>s2Member:</strong> Your Download Limit Exceeded Page is the same as your Membership Options Page. Please correct this. See: <strong>s2Member → Download Options</strong>.')) {
                 $enqueue_notices === TRUE || in_array('page-conflict-warnings', (array) $enqueue_notices) ? c_ws_plugin__s2member_admin_notices::enqueue_admin_notice($notice, '*:*', TRUE) : c_ws_plugin__s2member_admin_notices::display_admin_notice($notice, TRUE);
             }
         }
         $updated_all_options = TRUE;
         // Flag indicating this routine was processed successfully; and that all s2Member options have been updated successfully.
     }
     foreach (array_keys(get_defined_vars()) as $__v) {
         $__refs[$__v] =& ${$__v};
     }
     do_action('ws_plugin__s2member_after_update_all_options', get_defined_vars());
     unset($__refs, $__v);
     // Housekeeping.
     return apply_filters('ws_plugin__s2member_update_all_options', $updated_all_options ? TRUE : FALSE, get_defined_vars());
 }
 /**
  * Upgrade processor.
  *
  * @package s2Member\Upgrader
  * @since 1.5
  *
  * @attaches-to ``add_action("admin_init");``
  *
  * @return null Upgrader does NOT return anything.
  */
 public static function upgrade()
 {
     global $wp_filesystem;
     if (!empty($_POST["ws_plugin__s2member_pro_upgrade"]) && ($nonce = (string) $_POST["ws_plugin__s2member_pro_upgrade"]) && wp_verify_nonce($nonce, "ws-plugin--s2member-pro-upgrade") && ($_p = c_ws_plugin__s2member_utils_strings::trim_deep(stripslashes_deep($_POST)))) {
         if (@set_time_limit(0) !== "nill" && @ini_set("memory_limit", apply_filters("admin_memory_limit", WP_MAX_MEMORY_LIMIT)) !== "nill" && c_ws_plugin__s2member_pro_upgrader::abbr_bytes(@ini_get("memory_limit")) >= c_ws_plugin__s2member_pro_upgrader::abbr_bytes(apply_filters("admin_memory_limit", WP_MAX_MEMORY_LIMIT))) {
             if (!empty($_p["ws_plugin__s2member_pro_upgrade_username"]) && !empty($_p["ws_plugin__s2member_pro_upgrade_password"]) && is_array($s2_pro_upgrade = maybe_unserialize(c_ws_plugin__s2member_utils_urls::remote(add_query_arg(urlencode_deep(array("s2_pro_upgrade" => array("username" => (string) $_p["ws_plugin__s2member_pro_upgrade_username"], "password" => (string) $_p["ws_plugin__s2member_pro_upgrade_password"], "version" => WS_PLUGIN__S2MEMBER_PRO_VERSION))), c_ws_plugin__s2member_readmes::parse_readme_value("Pro Add-on / Auto-Update URL", dirname(dirname(dirname(__FILE__))) . "/readme.txt"))))) && !empty($s2_pro_upgrade["zip"]) && !empty($s2_pro_upgrade["ver"])) {
                 set_transient(md5("ws_plugin__s2member_pro_upgrade_credentials"), array("username" => (string) $_p["ws_plugin__s2member_pro_upgrade_username"], "password" => (string) $_p["ws_plugin__s2member_pro_upgrade_password"]), 5184000);
                 ob_start();
                 if (is_array($credentials = request_filesystem_credentials($_SERVER["REQUEST_URI"], false, false, dirname(dirname(dirname(dirname(__FILE__))))))) {
                     c_ws_plugin__s2member_pro_upgrader::$credentials = $credentials;
                 }
                 $credentials_form = ob_get_clean();
                 c_ws_plugin__s2member_pro_upgrader::maintenance(true);
                 if (WP_Filesystem(c_ws_plugin__s2member_pro_upgrader::$credentials, $plugins_dir = $_plugins_dir = dirname(dirname(dirname(dirname(__FILE__))))) && ($plugins_dir = rtrim($wp_filesystem->find_folder($plugins_dir), "/")) && ($plugin_dir = rtrim($wp_filesystem->find_folder($_plugin_dir = dirname(dirname(dirname(__FILE__)))), "/"))) {
                     if (($tmp_zip = wp_unique_filename($_plugins_dir, basename($plugin_dir) . ".zip")) && ($_tmp_zip = $_plugins_dir . "/" . $tmp_zip) && ($tmp_zip = $plugins_dir . "/" . $tmp_zip) && $wp_filesystem->put_contents($tmp_zip, c_ws_plugin__s2member_utils_urls::remote($s2_pro_upgrade["zip"], false, array("timeout" => 120)), FS_CHMOD_FILE)) {
                         if ((!$wp_filesystem->is_dir($plugin_dir . "-new") || $wp_filesystem->delete($plugin_dir . "-new", true)) && $wp_filesystem->mkdir($plugin_dir . "-new", FS_CHMOD_DIR)) {
                             if (!is_wp_error($unzip = unzip_file($_tmp_zip, $plugin_dir . "-new"))) {
                                 if (!$wp_filesystem->is_dir($plugin_dir) || $wp_filesystem->delete($plugin_dir, true)) {
                                     if ($wp_filesystem->move($plugin_dir . "-new/s2member-pro", $plugin_dir)) {
                                         $wp_filesystem->delete($plugin_dir . "-new", true) . $wp_filesystem->delete($tmp_zip);
                                         $notice = 's2Member Pro successfully updated to v' . esc_html($s2_pro_upgrade["ver"]) . '.';
                                         do_action("ws_plugin__s2member_pro_during_successfull_upgrade", get_defined_vars());
                                         c_ws_plugin__s2member_admin_notices::enqueue_admin_notice($notice, "blog|network:*");
                                         c_ws_plugin__s2member_pro_upgrader::maintenance(false);
                                         wp_redirect(self_admin_url("/plugins.php")) . exit;
                                     } else {
                                         $wp_filesystem->delete($plugin_dir . "-new", true) . $wp_filesystem->delete($tmp_zip);
                                         c_ws_plugin__s2member_pro_upgrader::$error = "Upgrade failed. Error #0009. Please upgrade via FTP.";
                                     }
                                 } else {
                                     $wp_filesystem->delete($plugin_dir . "-new", true) . $wp_filesystem->delete($tmp_zip);
                                     c_ws_plugin__s2member_pro_upgrader::$error = "Upgrade failed. Error #0008. Please upgrade via FTP.";
                                 }
                             } else {
                                 $wp_filesystem->delete($plugin_dir . "-new", true) . $wp_filesystem->delete($tmp_zip);
                                 c_ws_plugin__s2member_pro_upgrader::$error = "Upgrade failed. Error #0007. " . $unzip->get_error_message() . " ~ Please upgrade via FTP. ";
                             }
                         } else {
                             $wp_filesystem->delete($plugin_dir . "-new", true) . $wp_filesystem->delete($tmp_zip);
                             c_ws_plugin__s2member_pro_upgrader::$error = "Upgrade failed. Error #0006. Please upgrade via FTP.";
                         }
                     } else {
                         $wp_filesystem->delete($plugin_dir . "-new", true) . $wp_filesystem->delete($tmp_zip);
                         c_ws_plugin__s2member_pro_upgrader::$error = "Upgrade failed. Error #0005. Please upgrade via FTP.";
                     }
                 } else {
                     c_ws_plugin__s2member_pro_upgrader::$error = "Upgrade failed. Error #0004. Please upgrade via FTP, or supply valid Filesystem Credentials.";
                 }
                 c_ws_plugin__s2member_pro_upgrader::maintenance(false);
             } else {
                 if (!empty($s2_pro_upgrade) && $s2_pro_upgrade === "403 Forbidden") {
                     c_ws_plugin__s2member_pro_upgrader::$error = "Upgrade failed. Invalid Username/Password (or License Key); please try again.";
                 } else {
                     if (!empty($s2_pro_upgrade) && $s2_pro_upgrade === "503 Service Unavailable") {
                         c_ws_plugin__s2member_pro_upgrader::$error = "Upgrade failed. Service currently unavailable (please try again).";
                     } else {
                         c_ws_plugin__s2member_pro_upgrader::$error = "Upgrade failed. Connection failed (please try again).";
                     }
                 }
             }
         } else {
             c_ws_plugin__s2member_pro_upgrader::$error = "Not enough memory." . " Unzipping s2Member Pro via WordPress requires " . WP_MAX_MEMORY_LIMIT . " of RAM." . " Please upgrade via FTP instead.</code>.";
         }
     }
     return;
 }
 /**
  * Handles PayPal Return URLs.
  *
  * @package s2Member\PayPal
  * @since 3.5
  *
  * @attaches-to ``add_action("init");``
  *
  * @return null Or exits script execution after redirection.
  */
 public static function paypal_return()
 {
     global $current_site, $current_blog;
     do_action("ws_plugin__s2member_before_paypal_return", get_defined_vars());
     if (!empty($_GET["s2member_paypal_return"]) && ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["paypal_business"] || !empty($_GET["s2member_paypal_proxy"]))) {
         $custom_success_redirection = !empty($_GET["s2member_paypal_return_success"]) ? esc_html(trim(stripslashes($_GET["s2member_paypal_return_success"]))) : false;
         $custom_success_redirection = $custom_success_redirection ? str_ireplace(array("&#038;", "&amp;"), "&", $custom_success_redirection) : $custom_success_redirection;
         if (is_array($paypal = c_ws_plugin__s2member_paypal_utilities::paypal_postvars()) && ($_paypal = $paypal) && ($_paypal_s = serialize($_paypal))) {
             $paypal["s2member_log"][] = "Return-Data received on: " . date("D M j, Y g:i:s a T");
             $paypal["s2member_log"][] = "s2Member POST vars verified " . (!empty($paypal["proxy_verified"]) ? "with a Proxy Key" : "through a POST back to PayPal.");
             $paypal["subscr_gateway"] = !empty($_GET["s2member_paypal_proxy"]) ? esc_html(trim(stripslashes($_GET["s2member_paypal_proxy"]))) : "paypal";
             if (empty($_GET["s2member_paypal_proxy"]) || empty($_GET["s2member_paypal_proxy_use"]) || !preg_match("/ty-email/", $_GET["s2member_paypal_proxy_use"])) {
                 $payment_status_issues = "/^(failed|denied|expired|refunded|partially_refunded|reversed|reversal|canceled_reversal|voided)\$/i";
                 if (!empty($paypal["custom"]) && preg_match("/^" . preg_quote(preg_replace("/\\:([0-9]+)\$/", "", $_SERVER["HTTP_HOST"]), "/") . "/i", $paypal["custom"])) {
                     $paypal["s2member_log"][] = "s2Member originating domain ( `\$_SERVER[\"HTTP_HOST\"]` ) validated.";
                     foreach (array_keys(get_defined_vars()) as $__v) {
                         $__refs[$__v] =& ${$__v};
                     }
                     if (!apply_filters("ws_plugin__s2member_during_paypal_return_conditionals", false, get_defined_vars())) {
                         unset($__refs, $__v);
                         if ($_paypal_cp = c_ws_plugin__s2member_paypal_return_in_web_accept_sp::cp(get_defined_vars())) {
                             $paypal = $_paypal_cp;
                         } else {
                             if ($_paypal_cp = c_ws_plugin__s2member_paypal_return_in_wa_ccaps_wo_level::cp(get_defined_vars())) {
                                 $paypal = $_paypal_cp;
                             } else {
                                 if ($_paypal_cp = c_ws_plugin__s2member_paypal_return_in_subscr_or_wa_w_level::cp(get_defined_vars())) {
                                     $paypal = $_paypal_cp;
                                 } else {
                                     if ($_paypal_cp = c_ws_plugin__s2member_paypal_return_in_subscr_modify_w_level::cp(get_defined_vars())) {
                                         $paypal = $_paypal_cp;
                                     } else {
                                         $paypal["s2member_log"][] = "Unexpected `txn_type/status`. The `txn_type/status` did not match a required action.";
                                         $paypal["s2member_log"][] = "Redirecting Customer to the Home Page (after displaying an error message).";
                                         echo c_ws_plugin__s2member_return_templates::return_template($paypal["subscr_gateway"], _x('<strong>ERROR:</strong> Unexpected <code>txn_type/status</code>.<br />The <code>txn_type/status</code> did not meet requirements.<br />Please contact Support for assistance.', "s2member-front", "s2member"), _x("Back To Home Page", "s2member-front", "s2member"), home_url("/"));
                                     }
                                 }
                             }
                         }
                     } else {
                         // Else a custom conditional has been applied by filters.
                         unset($__refs, $__v);
                     }
                 } else {
                     if ($paypal["custom"] && ($paypal["custom"] === "www." . $_SERVER["HTTP_HOST"] || "www." . $paypal["custom"] === $_SERVER["HTTP_HOST"])) {
                         c_ws_plugin__s2member_admin_notices::enqueue_admin_notice("<strong>s2Member:</strong> Post-processing failed on at least one transaction. It appears that you have a PayPal Button configured with a <code>custom=\"\"</code> Shortcode Attribute that does NOT match up with your installation domain name. If your site uses the <code>www.</code> prefix, please include that. If it does not, please exclude the <code>www.</code> prefix. You should have <code>custom=\"" . preg_replace("/\\:([0-9]+)\$/", "", $_SERVER["HTTP_HOST"]) . "\"</code>", "*:*", true);
                     }
                     $paypal["s2member_log"][] = 'Unable to verify `$_SERVER["HTTP_HOST"]`. Please check the `custom` value in your Button Code. It MUST start with your domain name.';
                     $paypal["s2member_log"][] = "Redirecting Customer to the Home Page (after displaying an error message).";
                     echo c_ws_plugin__s2member_return_templates::return_template($paypal["subscr_gateway"], _x('<strong>ERROR:</strong> Unable to verify <code>$_SERVER["HTTP_HOST"]</code>.<br />Please contact Support for assistance.<br /><br />If you are the site owner, please check the <code>custom</code> value in your Button Code. It MUST start with your domain name.', "s2member-front", "s2member"), _x("Back To Home Page", "s2member-front", "s2member"), home_url("/"));
                 }
             } else {
                 // In this case ... a Proxy has explicitly requested `ty-email` processing.
                 $paypal = $_paypal_cp = c_ws_plugin__s2member_paypal_return_in_proxy_ty_email::cp(get_defined_vars());
             }
         } else {
             if (!empty($_GET["s2member_paypal_proxy"]) && !empty($_GET["s2member_paypal_proxy_use"]) && preg_match("/x-preview/", $_GET["s2member_paypal_proxy_use"]) && ($paypal["subscr_gateway"] = esc_html(trim(stripslashes($_GET["s2member_paypal_proxy"]))))) {
                 $paypal = $_paypal_cp = c_ws_plugin__s2member_paypal_return_in_proxy_x_preview::cp(get_defined_vars());
             } else {
                 if (empty($_GET["tx"]) && empty($_GET["s2member_paypal_proxy"]) && ($paypal["subscr_gateway"] = "paypal")) {
                     $paypal = $_paypal_cp = c_ws_plugin__s2member_paypal_return_in_no_tx_data::cp(get_defined_vars());
                 } else {
                     if (!$GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["paypal_identity_token"]) {
                         c_ws_plugin__s2member_admin_notices::enqueue_admin_notice("<strong>s2Member:</strong> You have no PayPal PDT Identity Token configured. PayPal Auto-Return handling failed. Please update your PayPal PDT Identity Key. See: <code>s2Member -› PayPal Options -› PayPal PDT/Auto-Return Integration</code>. Thank you!", "*:*", true);
                     }
                     $paypal["s2member_log"][] = "Unable to verify \$_POST vars. This is most likely related to an invalid configuration of s2Member, or a problem with server compatibility.";
                     $paypal["s2member_log"][] = "Please make sure that you configure a PayPal PDT Identity Token for your installation of s2Member. See: `s2Member -› PayPal Options -› PayPal PDT/Auto-Return Integration`.";
                     $paypal["s2member_log"][] = "See also, this KB article: `http://www.s2member.com/kb/server-scanner/`. We suggest that you run the s2Member Server Scanner.";
                     $paypal["s2member_log"][] = var_export($_REQUEST, true);
                     $paypal["s2member_log"][] = "Redirecting Customer to the Home Page (after displaying an error message).";
                     echo c_ws_plugin__s2member_return_templates::return_template("default", _x('<strong>ERROR:</strong> Unable to verify <code>$_POST</code> vars.<br />Please contact Support for assistance.<br /><br />This is most likely related to an invalid configuration of s2Member, or a problem with server compatibility. If you are the site owner, and you\'re absolutely SURE that your configuration is valid, you may want to run some tests on your server, just to be sure <code>$_POST</code> variables are populated, and that your server is able to connect/communicate with your Payment Gateway over an HTTPS connection.<br /><br />s2Member uses the <code>WP_Http</code> class for remote connections; which will try to use <code>cURL</code> first, and then fall back on the <code>FOPEN</code> method when <code>cURL</code> is not available. On a Windows server, you may have to disable your <code>cURL</code> extension; and instead, set <code>allow_url_fopen = yes</code> in your php.ini file. The <code>cURL</code> extension (usually) does NOT support SSL connections on a Windows server.<br /><br />Please see <a href="http://www.s2member.com/forums/topic/ideal-server-configuration-for-s2member/" target="_blank">this thread</a> for details regarding the ideal server configuration for s2Member.', "s2member-front", "s2member"), _x("Back To Home Page", "s2member-front", "s2member"), home_url("/"));
                 }
             }
         }
         /*
         Add RTN proxy (when available) to the ``$paypal`` array.
         */
         if (!empty($_GET["s2member_paypal_proxy"])) {
             $paypal["s2member_paypal_proxy"] = $_GET["s2member_paypal_proxy"];
         }
         /*
         Add IPN proxy use vars (when available) to the ``$paypal`` array.
         */
         if (!empty($_GET["s2member_paypal_proxy_use"])) {
             $paypal["s2member_paypal_proxy_use"] = $_GET["s2member_paypal_proxy_use"];
         }
         /*
         Also add RTN proxy self-verification (when available) to the ``$paypal`` array.
         */
         if (!empty($_GET["s2member_paypal_proxy_verification"])) {
             $paypal["s2member_paypal_proxy_verification"] = $_GET["s2member_paypal_proxy_verification"];
         }
         /*
         Also add RTN success redirection URL (when available) to the ``$paypal`` array.
         */
         if (!empty($_GET["s2member_paypal_return_success"])) {
             $paypal["s2member_paypal_return_success"] = $_GET["s2member_paypal_return_success"];
         }
         /*
         Also add RTN t and r Attributes (when available) to the ``$paypal`` array.
         */
         if (!empty($_GET["s2member_paypal_return_tra"])) {
             $paypal["s2member_paypal_return_tra"] = $_GET["s2member_paypal_return_tra"];
         }
         /*
         If debugging/logging is enabled; we need to append $paypal to the log file.
         	Logging now supports Multisite Networking as well.
         */
         $logt = c_ws_plugin__s2member_utilities::time_details();
         $logv = c_ws_plugin__s2member_utilities::ver_details();
         $logm = c_ws_plugin__s2member_utilities::mem_details();
         $log4 = $_SERVER["HTTP_HOST"] . $_SERVER["REQUEST_URI"] . "\nUser-Agent: " . $_SERVER["HTTP_USER_AGENT"];
         $log4 = is_multisite() && !is_main_site() ? ($_log4 = $current_blog->domain . $current_blog->path) . "\n" . $log4 : $log4;
         $log2 = is_multisite() && !is_main_site() ? "paypal-rtn-4-" . trim(preg_replace("/[^a-z0-9]/i", "-", $_log4), "-") . ".log" : "paypal-rtn.log";
         if ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["gateway_debug_logs"]) {
             if (is_dir($logs_dir = $GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["logs_dir"])) {
                 if (is_writable($logs_dir) && c_ws_plugin__s2member_utils_logs::archive_oversize_log_files()) {
                     file_put_contents($logs_dir . "/" . $log2, "LOG ENTRY: " . $logt . "\n" . $logv . "\n" . $logm . "\n" . $log4 . "\n" . c_ws_plugin__s2member_utils_logs::conceal_private_info(var_export($paypal, true)) . "\n\n", FILE_APPEND);
                 }
             }
         }
         foreach (array_keys(get_defined_vars()) as $__v) {
             $__refs[$__v] =& ${$__v};
         }
         do_action("ws_plugin__s2member_during_paypal_return", get_defined_vars());
         unset($__refs, $__v);
         exit;
     }
     foreach (array_keys(get_defined_vars()) as $__v) {
         $__refs[$__v] =& ${$__v};
     }
     do_action("ws_plugin__s2member_after_paypal_return", get_defined_vars());
     unset($__refs, $__v);
 }
 /**
  * Deals with Reading Option conflicts.
  *
  * @package s2Member\Option_Notices
  * @since 3.5
  *
  * @attaches-to ``add_action("load-options-reading.php");``
  *
  * @return null
  */
 public static function reading_ops_notice()
 {
     global $pagenow;
     // Need this global variable.
     do_action("ws_plugin__s2member_before_reading_ops_notice", get_defined_vars());
     if (is_blog_admin() && $pagenow === "options-reading.php" && !isset($_GET["page"])) {
         do_action("ws_plugin__s2member_during_reading_ops_notice", get_defined_vars());
         // Now check for conflicts.
         if ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["membership_options_page"] && (string) get_option("page_on_front") === $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["membership_options_page"] && ($notice = '<strong>NOTE:</strong> Your Membership Options Page for s2Member is currently configured as your Home Page (i.e. static page) for WordPress. This causes internal conflicts with s2Member. Your Membership Options Page MUST stand alone. Please correct this.')) {
             c_ws_plugin__s2member_admin_notices::enqueue_admin_notice($notice, "blog:" . $pagenow, true);
         }
         if ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["login_welcome_page"] && (string) get_option("page_on_front") === $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["login_welcome_page"] && ($notice = '<strong>NOTE:</strong> Your Login Welcome Page for s2Member is currently configured as your Home Page (i.e. static page) for WordPress. This causes internal conflicts with s2Member. Your Login Welcome Page MUST stand alone. Please correct this.')) {
             c_ws_plugin__s2member_admin_notices::enqueue_admin_notice($notice, "blog:" . $pagenow, true);
         }
         if ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["membership_options_page"] && (string) get_option("page_for_posts") === $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["membership_options_page"] && ($notice = '<strong>NOTE:</strong> Your Membership Options Page for s2Member is currently configured as your Posts Page (i.e. static page) for WordPress. This causes internal conflicts with s2Member. Your Membership Options Page MUST stand alone. Please correct this.')) {
             c_ws_plugin__s2member_admin_notices::enqueue_admin_notice($notice, "blog:" . $pagenow, true);
         }
         if ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["login_welcome_page"] && (string) get_option("page_for_posts") === $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["login_welcome_page"] && ($notice = '<strong>NOTE:</strong> Your Login Welcome Page for s2Member is currently configured as your Posts Page (i.e. static page) for WordPress. This causes internal conflicts with s2Member. Your Login Welcome Page MUST stand alone. Please correct this.')) {
             c_ws_plugin__s2member_admin_notices::enqueue_admin_notice($notice, "blog:" . $pagenow, true);
         }
     }
     do_action("ws_plugin__s2member_after_reading_ops_notice", get_defined_vars());
     return;
 }
/**
* Deprecated in s2Member v3.5+.
*
* Needed by the s2Member Pro upgrader prior to s2Member Pro v1.5+.
*
* @package s2Member
* @since 3.0
*
* @deprecated Starting with s2Member v3.5+, please use:
* 	``c_ws_plugin__s2member_admin_notices::enqueue_admin_notice()``
*
* @see s2Member\Admin_Notices\c_ws_plugin__s2member_admin_notices::enqueue_admin_notice()
*/
function ws_plugin__s2member_enqueue_admin_notice($notice = FALSE, $on_pages = FALSE, $error = FALSE, $time = FALSE, $dismiss = FALSE)
{
    return c_ws_plugin__s2member_admin_notices::enqueue_admin_notice($notice, $on_pages, $error, $time, $dismiss);
}
 /**
  * Activation routines for s2Member.
  *
  * @package s2Member\Installation
  * @since 3.5
  *
  * @param string $reactivation_reason Optional.
  */
 public static function activate($reactivation_reason = '')
 {
     global $wpdb;
     /** @var $wpdb wpdb */
     global $current_site, $current_blog;
     // Multisite.
     do_action('ws_plugin__s2member_before_activation', get_defined_vars());
     c_ws_plugin__s2member_roles_caps::config_roles();
     // Config Roles/Caps.
     update_option('ws_plugin__s2member_activated_levels', $GLOBALS['WS_PLUGIN__']['s2member']['c']['levels']);
     if (!is_dir($files_dir = $GLOBALS['WS_PLUGIN__']['s2member']['c']['files_dir'])) {
         if (is_writable(dirname(c_ws_plugin__s2member_utils_dirs::strip_dir_app_data($files_dir)))) {
             mkdir($files_dir, 0777, TRUE);
         }
     }
     if (is_dir($files_dir) && is_writable($files_dir)) {
         if (!is_file($htaccess = $files_dir . '/.htaccess') || !apply_filters('ws_plugin__s2member_preserve_files_dir_htaccess', !is_writable($files_dir . '/.htaccess'), get_defined_vars())) {
             file_put_contents($htaccess, trim(c_ws_plugin__s2member_utilities::evl(file_get_contents($GLOBALS['WS_PLUGIN__']['s2member']['c']['files_dir_htaccess']))));
         }
     }
     c_ws_plugin__s2member_files::write_no_gzip_into_root_htaccess();
     // Handle the root `.htaccess` file as well now, for GZIP exclusions.
     if (!is_dir($logs_dir = $GLOBALS['WS_PLUGIN__']['s2member']['c']['logs_dir'])) {
         if (is_writable(dirname(c_ws_plugin__s2member_utils_dirs::strip_dir_app_data($logs_dir)))) {
             mkdir($logs_dir, 0777, TRUE);
         }
     }
     if (is_dir($logs_dir) && is_writable($logs_dir)) {
         if (!is_file($htaccess = $logs_dir . '/.htaccess') || !apply_filters('ws_plugin__s2member_preserve_logs_dir_htaccess', !is_writable($logs_dir . '/.htaccess'), get_defined_vars())) {
             file_put_contents($htaccess, trim(c_ws_plugin__s2member_utilities::evl(file_get_contents($GLOBALS['WS_PLUGIN__']['s2member']['c']['logs_dir_htaccess']))));
         }
     }
     !is_array(get_option('ws_plugin__s2member_cache')) ? update_option('ws_plugin__s2member_cache', array()) : NULL;
     !is_array(get_option('ws_plugin__s2member_notices')) ? update_option('ws_plugin__s2member_notices', array()) : NULL;
     !is_array(get_option('ws_plugin__s2member_options')) ? update_option('ws_plugin__s2member_options', array()) : NULL;
     !is_numeric(get_option('ws_plugin__s2member_configured')) ? update_option('ws_plugin__s2member_configured', '0') : NULL;
     if ($GLOBALS['WS_PLUGIN__']['s2member']['c']['configured']) {
         $v = get_option('ws_plugin__s2member_activated_version');
         // Currently.
         if (!$v || !version_compare($v, '3.2', '>=')) {
             $like = "`meta_key` LIKE 's2member\\_%' AND `meta_key` NOT LIKE '%s2member\\_originating\\_blog%'";
             $wpdb->query("UPDATE `" . $wpdb->usermeta . "` SET `meta_key` = CONCAT('" . $wpdb->prefix . "', `meta_key`) WHERE " . $like);
         }
         if (!$v || !version_compare($v, '3.2.5', '>=')) {
             $wpdb->query("DELETE FROM `" . $wpdb->options . "` WHERE `option_name` LIKE '\\_transient\\_%'");
         }
         if (!$v || !version_compare($v, '3.2.6', '>=')) {
             $wpdb->query("DELETE FROM `" . $wpdb->postmeta . "` WHERE `meta_key` = 's2member_ccaps_req' AND `meta_value` IN('','a:0:{}','a:1:{i:0;s:0:\"\";}')");
         }
         if (!$v || !version_compare($v, '110912', '>=') && $GLOBALS['WS_PLUGIN__']['s2member']['o']['filter_wp_query'] === array('all')) {
             $notice = '<strong>IMPORTANT:</strong> This version of s2Member changes the way your <code>Alternative View Protections</code> work. Please review your options under: <strong>s2Member → Restriction Options → Alternative View Protections</strong>.';
             c_ws_plugin__s2member_admin_notices::enqueue_admin_notice($notice, array('blog|network:plugins.php', 'blog|network:ws-plugin--s2member-start', 'blog|network:ws-plugin--s2member-mms-ops', 'blog|network:ws-plugin--s2member-gen-ops', 'blog|network:ws-plugin--s2member-res-ops'));
         }
         if ($v && version_compare($v, '130316', '<=')) {
             c_ws_plugin__s2member_menu_pages::update_all_options(array('ws_plugin__s2member_gateway_debug_logs' => '0', 'ws_plugin__s2member_gateway_debug_logs_extensive' => '0'), TRUE, FALSE, FALSE, FALSE, FALSE);
             $notice = '<strong>IMPORTANT:</strong> This version of s2Member disables s2Member\'s debug logging by default (for added security). Please see: <a href="' . esc_attr(admin_url('/admin.php?page=ws-plugin--s2member-logs')) . '">s2Member → Log Files (Debug) → Configuration</a> for further details.';
             c_ws_plugin__s2member_admin_notices::enqueue_admin_notice($notice, array('blog|network:plugins.php', 'blog|network:ws-plugin--s2member-start', 'blog|network:ws-plugin--s2member-mms-ops', 'blog|network:ws-plugin--s2member-gen-ops', 'blog|network:ws-plugin--s2member-res-ops'));
             $notice = '<strong>IMPORTANT / Regarding s2Member Security Badges:</strong> If debug logging is enabled, your site will no longer qualify for an s2Member Security Badge until you disable logging (and you must also download, and then delete any existing log files from the past). Please see KB Article: <a href="http://www.s2member.com/kb/security-badges/" target="_blank" rel="external">s2Member Security Badges</a> for further details. If you have existing s2Member log files, you will need to delete those files from the server before your s2Member Security Badge can be re-enabled. s2Member stores log files here: <code>' . esc_html(c_ws_plugin__s2member_utils_dirs::doc_root_path($GLOBALS['WS_PLUGIN__']['s2member']['c']['logs_dir'])) . '</code>. See also: <a href="' . esc_attr(admin_url('/admin.php?page=ws-plugin--s2member-logs')) . '">s2Member → Log Files (Debug) → Configuration</a> for further details.';
             c_ws_plugin__s2member_admin_notices::enqueue_admin_notice($notice, array('blog|network:plugins.php', 'blog|network:ws-plugin--s2member-start', 'blog|network:ws-plugin--s2member-mms-ops', 'blog|network:ws-plugin--s2member-gen-ops', 'blog|network:ws-plugin--s2member-res-ops'));
         }
         if ($v && version_compare($v, '140128', '<=')) {
             if ($GLOBALS['WS_PLUGIN__']['s2member']['o']['triggers_immediate_eot'] === 'refunds,reversals') {
                 // `refunds,reversals` => `refunds,partial_refunds,reversals`
                 c_ws_plugin__s2member_menu_pages::update_all_options(array('ws_plugin__s2member_triggers_immediate_eot' => 'refunds,partial_refunds,reversals'), TRUE, FALSE, FALSE, FALSE, FALSE);
             }
         }
         $notice = '<strong>s2Member</strong> has been <strong>reactivated</strong>, with ' . ($reactivation_reason === 'levels' ? '<code>' . esc_html($GLOBALS['WS_PLUGIN__']['s2member']['c']['levels']) . '</code> Membership Levels' : 'the latest version') . '.<br />';
         $notice .= 'You now have version ' . esc_html(WS_PLUGIN__S2MEMBER_VERSION) . '. Your existing configuration remains.';
         if (!is_multisite() || !c_ws_plugin__s2member_utils_conds::is_multisite_farm() || is_main_site()) {
             // No Changelog on a Multisite Blog Farm.
             $notice .= '<br />Have fun, <a href="' . esc_attr(c_ws_plugin__s2member_readmes::parse_readme_value('Changelog URI')) . '" target="_blank">read the Changelog</a>, and make some money! :-)';
         }
         c_ws_plugin__s2member_admin_notices::enqueue_admin_notice($notice, array('blog|network:plugins.php', 'blog|network:ws-plugin--s2member-start', 'blog|network:ws-plugin--s2member-mms-ops', 'blog|network:ws-plugin--s2member-gen-ops', 'blog|network:ws-plugin--s2member-res-ops'));
     } else {
         $notice = '<strong>Note:</strong> s2Member adds some new data columns to your list of Users/Members. If your list gets overcrowded, please use the <strong>Screen Options</strong> tab <em>(upper right-hand corner)</em>. With WordPress Screen Options, you can add/remove specific data columns; thereby making the most important data easier to read. For example, if you create Custom Registration/Profile Fields with s2Member, those Custom Fields will result in new data columns; which can cause your list of Users/Members to become nearly unreadable. So just use the Screen Options tab to clean things up.';
         c_ws_plugin__s2member_admin_notices::enqueue_admin_notice($notice, 'blog:users.php', FALSE, FALSE, TRUE);
         $notice = '<strong>s2Member</strong> v' . esc_html(WS_PLUGIN__S2MEMBER_VERSION) . ' has been <strong>activated</strong>. Nice work!<br />';
         $notice .= 'Have fun, <a href="' . esc_attr(admin_url('/admin.php?page=ws-plugin--s2member-start')) . '">read the Quick Start Guide</a>, and make some money! :-)';
         c_ws_plugin__s2member_admin_notices::enqueue_admin_notice($notice, array('blog|network:plugins.php', 'blog|network:ws-plugin--s2member-start', 'blog|network:ws-plugin--s2member-mms-ops', 'blog|network:ws-plugin--s2member-gen-ops', 'blog|network:ws-plugin--s2member-res-ops'));
     }
     if (is_multisite() && is_main_site()) {
         $wpdb->query("INSERT INTO `" . $wpdb->usermeta . "` (`user_id`, `meta_key`, `meta_value`) SELECT `ID`, 's2member_originating_blog', '" . esc_sql($current_site->blog_id) . "' FROM `" . $wpdb->users . "` WHERE `ID` NOT IN (SELECT `user_id` FROM `" . $wpdb->usermeta . "` WHERE `meta_key` = 's2member_originating_blog')");
         $notice = '<strong>Multisite Network</strong> updated automatically by <strong>s2Member</strong> v' . esc_html(WS_PLUGIN__S2MEMBER_VERSION) . '.<br />';
         $notice .= 'You\'ll want to configure s2Member\'s Multisite options now.<br />';
         $notice .= 'In the Dashboard for your Main Site, see:<br />';
         $notice .= '<strong>s2Member → Multisite (Config)</strong>.';
         c_ws_plugin__s2member_admin_notices::enqueue_admin_notice($notice, array('blog|network:plugins.php', 'blog|network:ws-plugin--s2member-start', 'blog|network:ws-plugin--s2member-mms-ops', 'blog|network:ws-plugin--s2member-gen-ops', 'blog|network:ws-plugin--s2member-res-ops'));
         update_site_option('ws_plugin__s2member_options', (array) get_option('ws_plugin__s2member_options'));
         update_option('ws_plugin__s2member_activated_mms_version', WS_PLUGIN__S2MEMBER_VERSION);
     }
     update_option('ws_plugin__s2member_activated_version', WS_PLUGIN__S2MEMBER_VERSION);
     do_action('ws_plugin__s2member_after_activation', get_defined_vars());
 }
 /**
  * Draw attention to other payment gateways.
  *
  * @package s2Member\Gateways
  * @since 150717
  *
  * @attaches-to ``add_action('admin_init');``
  */
 public static function maybe_draw_attention_to_gateways()
 {
     if (is_network_admin()) {
         return;
     }
     // Not applicable.
     if ($GLOBALS['WS_PLUGIN__']['s2member']['o']['pro_gateways_seen']) {
         return;
     }
     // Not applicable. Seen already.
     $GLOBALS['WS_PLUGIN__']['s2member']['o']['pro_gateways_seen'] = '1';
     update_option('ws_plugin__s2member_options', $GLOBALS['WS_PLUGIN__']['s2member']['o']);
     if (is_multisite() && is_main_site()) {
         update_site_option('ws_plugin__s2member_options', $GLOBALS['WS_PLUGIN__']['s2member']['o']);
     }
     // If `unconfigured` is not in the array of gateways they have already been configured in that scenario.
     // 	Or, perhaps this is a site that was setup prior to 150717; i.e., this notice is not applicable.
     if (!in_array('unconfigured', $GLOBALS['WS_PLUGIN__']['s2member']['o']['pro_gateways_enabled'], TRUE)) {
         return;
     }
     // Already configured these; i.e., back compatibility.
     $page = admin_url('/admin.php?page=ws-plugin--s2member-pro-other-gateways');
     $notice = '<strong>s2Member® Pro says...</strong> Please configure <a href="' . esc_attr($page) . '" style="text-decoration:underline;">Other Payment Gateways</a>; i.e., choose which payment gateways you would like to use.';
     c_ws_plugin__s2member_admin_notices::enqueue_admin_notice($notice, 'blog:*');
 }
 /**
  * Saves all options from any menu page.
  * 
  * Can also be self-verified; and configured extensively with function parameters.
  *
  * @package s2Member\Menu_Pages
  * @since 3.5
  *
  * @param array $new_options Optional. Force feed an array of new options. Defaults to ``$_POST`` vars.
  * 	If ``$new_options`` are passed in, be SURE that you've already applied ``stripslashes_deep()``.
  * @param bool $verified Optional. Defaults to false. If true, ``wp_verify_nonce()`` is skipped in this routine.
  * @param bool $update_other Optional. Defaults to true. If false, other option-dependent routines will not be processed.
  * @param bool|array $display_notices Optional. Defaults to true. Can be false, or an array of certain notices that can be displayed.
  * @param bool|array $enqueue_notices Optional. Defaults to false. Can be true, or an array of certain notices that should be enqueued.
  * @param bool $request_refresh Optional. Defaults to false. If true, resulting `success` notice will include a link to refresh the menu page.
  * @return bool True if all s2Member options were updated successfully, else false.
  */
 public static function update_all_options($new_options = FALSE, $verified = FALSE, $update_other = TRUE, $display_notices = TRUE, $enqueue_notices = FALSE, $request_refresh = FALSE)
 {
     $updated_all_options = false;
     /* Initialize this to a value of false. Initializing this variable here makes it an available reference-variable to Hooks/Filters. */
     /**/
     eval('foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;');
     do_action("ws_plugin__s2member_before_update_all_options", get_defined_vars());
     /* If you use this Hook, be sure to use ``wp_verify_nonce()``. */
     unset($__refs, $__v);
     /* Unset defined __refs, __v. */
     /**/
     if ($verified || !empty($_POST["ws_plugin__s2member_options_save"]) && ($nonce = $_POST["ws_plugin__s2member_options_save"]) && wp_verify_nonce($nonce, "ws-plugin--s2member-options-save")) {
         $options = $GLOBALS["WS_PLUGIN__"]["s2member"]["o"];
         /* Acquire the full existing configuration options array here. */
         /**/
         $new_options = is_array($new_options) ? $new_options : (!empty($_POST) && is_array($_POST) ? stripslashes_deep($_POST) : array());
         $new_options = c_ws_plugin__s2member_utils_strings::trim_deep($new_options);
         /**/
         foreach ($new_options as $key => $value) {
             /* Find all keys contained within ``$new_options`` matching `^ws_plugin__s2member_`. */
             if (strpos($key, "ws_plugin__s2member_") === 0) {
                 /* A relevant ``$new_options`` key matching `^ws_plugin__s2member_`? */
                 /**/
                 if ($key === "ws_plugin__s2member_configured") {
                     /* s2Member is now configured ( according to these options )? */
                     ($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["configured"] = $value) . update_option("ws_plugin__s2member_configured", $value);
                 } else {
                     if (!is_array($value) || is_array($value) && array_shift($value) === "update-signal") {
                         $options[preg_replace("/^" . preg_quote("ws_plugin__s2member_", "/") . "/", "", $key)] = $value;
                     }
                 }
             }
         }
         /**/
         unset($key, $value);
         /* Unset these utility variables now. This prevents bleeding vars into Hooks/Filters that are of no use. */
         /**/
         eval('foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;');
         do_action("ws_plugin__s2member_during_update_all_options", get_defined_vars());
         /* If you use this Hook, be sure to use ``wp_verify_nonce()``. */
         unset($__refs, $__v);
         /* Unset defined __refs, __v. */
         /**/
         $options = ws_plugin__s2member_configure_options_and_their_defaults($options = array_merge($options, array("options_version" => (string) ($options["options_version"] + 0.001))));
         update_option("ws_plugin__s2member_options", $options) . (is_multisite() && is_main_site() ? update_site_option("ws_plugin__s2member_options", $options) : null) . update_option("ws_plugin__s2member_cache", array());
         /**/
         if ($update_other === true || in_array("auto_eot_system", (array) $update_other)) {
             /* Handle the Auto-EOT System now ( enable/disable ). */
             $options["auto_eot_system_enabled"] == 1 ? c_ws_plugin__s2member_auto_eots::add_auto_eot_system() : c_ws_plugin__s2member_auto_eots::delete_auto_eot_system();
         }
         /**/
         if (($display_notices === true || in_array("success", (array) $display_notices)) && ($notice = '<strong>Options saved.' . ($request_refresh ? ' Please <a href="' . esc_attr($_SERVER["REQUEST_URI"]) . '">refresh</a>.' : '') . '</strong>')) {
             $enqueue_notices === true || in_array("success", (array) $enqueue_notices) ? c_ws_plugin__s2member_admin_notices::enqueue_admin_notice($notice, "*:*") : c_ws_plugin__s2member_admin_notices::display_admin_notice($notice);
         }
         /**/
         if (empty($_GET["page"]) || $_GET["page"] !== "ws-plugin--s2member-mms-ops") {
             if (!$options["membership_options_page"] && ($display_notices === true || in_array("page-conflict-warnings", (array) $display_notices)) && ($notice = '<strong>NOTE:</strong> s2Member security restrictions will NOT be enforced until you\'ve configured a Membership Options Page. See: <code>s2Member -> General Options -> Membership Options Page</code>.')) {
                 $enqueue_notices === true || in_array("page-conflict-warnings", (array) $enqueue_notices) ? c_ws_plugin__s2member_admin_notices::enqueue_admin_notice($notice, "*:*", true) : c_ws_plugin__s2member_admin_notices::display_admin_notice($notice, true);
             }
             /**/
             if ($options["login_welcome_page"] && $options["login_welcome_page"] === $options["membership_options_page"] && ($display_notices === true || in_array("page-conflict-warnings", (array) $display_notices)) && ($notice = '<strong>s2Member:</strong> Your Login Welcome Page is the same as your Membership Options Page. Please correct this. See: <code>s2Member -> General Options -> Login Welcome Page</code>.')) {
                 $enqueue_notices === true || in_array("page-conflict-warnings", (array) $enqueue_notices) ? c_ws_plugin__s2member_admin_notices::enqueue_admin_notice($notice, "*:*", true) : c_ws_plugin__s2member_admin_notices::display_admin_notice($notice, true);
             }
             /**/
             if ($options["membership_options_page"] && (string) get_option("page_on_front") === $options["membership_options_page"] && ($display_notices === true || in_array("page-conflict-warnings", (array) $display_notices)) && ($notice = '<strong>s2Member:</strong> Your Membership Options Page is currently configured as your Home Page ( i.e. static page ) for WordPress®. This causes internal conflicts with s2Member. Your Membership Options Page MUST stand alone. Please correct this. See: <code>WordPress® -> Reading Options</code>. Or change: <code>s2Member -> General Options -> Membership Options Page</code>.')) {
                 $enqueue_notices === true || in_array("page-conflict-warnings", (array) $enqueue_notices) ? c_ws_plugin__s2member_admin_notices::enqueue_admin_notice($notice, "*:*", true) : c_ws_plugin__s2member_admin_notices::display_admin_notice($notice, true);
             }
             /**/
             if ($options["login_welcome_page"] && (string) get_option("page_on_front") === $options["login_welcome_page"] && ($display_notices === true || in_array("page-conflict-warnings", (array) $display_notices)) && ($notice = '<strong>s2Member:</strong> Your Login Welcome Page is currently configured as your Home Page ( i.e. static page ) for WordPress®. This causes internal conflicts with s2Member. Your Login Welcome Page MUST stand alone. Please correct this. See: <code>WordPress® -> Reading Options</code>. Or change: <code>s2Member -> General Options -> Login Welcome Page</code>.')) {
                 $enqueue_notices === true || in_array("page-conflict-warnings", (array) $enqueue_notices) ? c_ws_plugin__s2member_admin_notices::enqueue_admin_notice($notice, "*:*", true) : c_ws_plugin__s2member_admin_notices::display_admin_notice($notice, true);
             }
             /**/
             if ($options["membership_options_page"] && (string) get_option("page_for_posts") === $options["membership_options_page"] && ($display_notices === true || in_array("page-conflict-warnings", (array) $display_notices)) && ($notice = '<strong>s2Member:</strong> Your Membership Options Page is currently configured as your Posts Page ( i.e. static page ) for WordPress®. This causes internal conflicts with s2Member. Your Membership Options Page MUST stand alone. Please correct this. See: <code>WordPress® -> Reading Options</code>. Or change: <code>s2Member -> General Options -> Membership Options Page</code>.')) {
                 $enqueue_notices === true || in_array("page-conflict-warnings", (array) $enqueue_notices) ? c_ws_plugin__s2member_admin_notices::enqueue_admin_notice($notice, "*:*", true) : c_ws_plugin__s2member_admin_notices::display_admin_notice($notice, true);
             }
             /**/
             if ($options["login_welcome_page"] && (string) get_option("page_for_posts") === $options["login_welcome_page"] && ($display_notices === true || in_array("page-conflict-warnings", (array) $display_notices)) && ($notice = '<strong>s2Member:</strong> Your Login Welcome Page is currently configured as your Posts Page ( i.e. static page ) for WordPress®. This causes internal conflicts with s2Member. Your Login Welcome Page MUST stand alone. Please correct this. See: <code>WordPress® -> Reading Options</code>. Or change: <code>s2Member -> General Options -> Login Welcome Page</code>.')) {
                 $enqueue_notices === true || in_array("page-conflict-warnings", (array) $enqueue_notices) ? c_ws_plugin__s2member_admin_notices::enqueue_admin_notice($notice, "*:*", true) : c_ws_plugin__s2member_admin_notices::display_admin_notice($notice, true);
             }
             /**/
             if ($options["file_download_limit_exceeded_page"] && $options["file_download_limit_exceeded_page"] === $options["membership_options_page"] && ($display_notices === true || in_array("page-conflict-warnings", (array) $display_notices)) && ($notice = '<strong>s2Member:</strong> Your Download Limit Exceeded Page is the same as your Membership Options Page. Please correct this. See: <code>s2Member -> Download Options</code>.')) {
                 $enqueue_notices === true || in_array("page-conflict-warnings", (array) $enqueue_notices) ? c_ws_plugin__s2member_admin_notices::enqueue_admin_notice($notice, "*:*", true) : c_ws_plugin__s2member_admin_notices::display_admin_notice($notice, true);
             }
         }
         /**/
         $updated_all_options = true;
         /* Flag indicating this routine was processed successfully; and that all s2Member options have been updated successfully.*/
     }
     /**/
     eval('foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;');
     do_action("ws_plugin__s2member_after_update_all_options", get_defined_vars());
     /* If you use this Hook, be sure to use ``wp_verify_nonce()``. */
     unset($__refs, $__v);
     /* Unset defined __refs, __v. */
     /**/
     return apply_filters("ws_plugin__s2member_update_all_options", $updated_all_options ? true : false, get_defined_vars());
 }
 /**
  * Activation routines for s2Member.
  *
  * @package s2Member\Installation
  * @since 3.5
  *
  * @return null
  */
 public static function activate($reactivation_reason = FALSE)
 {
     global $wpdb;
     /* Global database object reference. */
     global $current_site, $current_blog;
     /* Multisite. */
     /**/
     do_action("ws_plugin__s2member_before_activation", get_defined_vars());
     /**/
     c_ws_plugin__s2member_roles_caps::config_roles();
     /* Config Roles/Caps. */
     update_option("ws_plugin__s2member_activated_levels", $GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["levels"]);
     /**/
     if (!is_dir($files_dir = $GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["files_dir"])) {
         if (is_writable(dirname(c_ws_plugin__s2member_utils_dirs::strip_dir_app_data($files_dir)))) {
             mkdir($files_dir, 0777, true);
         }
     }
     /**/
     if (is_dir($files_dir) && is_writable($files_dir)) {
         if (!file_exists($htaccess = $files_dir . "/.htaccess") || !apply_filters("ws_plugin__s2member_preserve_files_dir_htaccess", false, get_defined_vars())) {
             file_put_contents($htaccess, trim(c_ws_plugin__s2member_utilities::evl(file_get_contents($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["files_dir_htaccess"]))));
         }
     }
     /**/
     if (!is_dir($logs_dir = $GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["logs_dir"])) {
         if (is_writable(dirname(c_ws_plugin__s2member_utils_dirs::strip_dir_app_data($logs_dir)))) {
             mkdir($logs_dir, 0777, true);
         }
     }
     /**/
     if (is_dir($logs_dir) && is_writable($logs_dir)) {
         if (!file_exists($htaccess = $logs_dir . "/.htaccess") || !apply_filters("ws_plugin__s2member_preserve_logs_dir_htaccess", false, get_defined_vars())) {
             file_put_contents($htaccess, trim(c_ws_plugin__s2member_utilities::evl(file_get_contents($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["logs_dir_htaccess"]))));
         }
     }
     /**/
     !is_array(get_option("ws_plugin__s2member_cache")) ? update_option("ws_plugin__s2member_cache", array()) : null;
     !is_array(get_option("ws_plugin__s2member_notices")) ? update_option("ws_plugin__s2member_notices", array()) : null;
     !is_array(get_option("ws_plugin__s2member_options")) ? update_option("ws_plugin__s2member_options", array()) : null;
     !is_numeric(get_option("ws_plugin__s2member_configured")) ? update_option("ws_plugin__s2member_configured", "0") : null;
     /**/
     if ($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["configured"]) {
         $v = get_option("ws_plugin__s2member_activated_version");
         /* Currently. */
         /**/
         if (!$v || !version_compare($v, "3.2", ">=")) {
             $like = "`meta_key` LIKE 's2member\\_%' AND `meta_key` NOT LIKE '%s2member\\_originating\\_blog%'";
             $wpdb->query("UPDATE `" . $wpdb->usermeta . "` SET `meta_key` = CONCAT('" . $wpdb->prefix . "', `meta_key`) WHERE " . $like);
         }
         /**/
         if (!$v || !version_compare($v, "3.2.5", ">=")) {
             $wpdb->query("DELETE FROM `" . $wpdb->options . "` WHERE `option_name` LIKE '\\_transient\\_%'");
         }
         /**/
         if (!$v || !version_compare($v, "3.2.6", ">=")) {
             $wpdb->query("DELETE FROM `" . $wpdb->postmeta . "` WHERE `meta_key` = 's2member_ccaps_req' AND `meta_value` IN('','a:0:{}','a:1:{i:0;s:0:\"\";}')");
         }
         /**/
         if (!$v || !version_compare($v, "110912", ">=") && $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["filter_wp_query"] === array("all")) {
             $notice = '<strong>IMPORTANT:</strong> This version of s2Member® changes the way your <code>Alternative View Protections</code> work. Please review your options under: <code>s2Member -> Restriction Options -> Alternative View Protections</code>.<br />';
             c_ws_plugin__s2member_admin_notices::enqueue_admin_notice($notice, array("blog|network:plugins.php", "blog|network:ws-plugin--s2member-start", "blog|network:ws-plugin--s2member-mms-ops", "blog|network:ws-plugin--s2member-gen-ops", "blog|network:ws-plugin--s2member-res-ops"));
         }
         /**/
         $notice = '<strong>s2Member</strong> has been <strong>reactivated</strong>, with ' . ($reactivation_reason === "levels" ? '<code>' . esc_html($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["levels"]) . '</code> Membership Levels' : 'the latest version') . '.<br />';
         $notice .= 'You now have version ' . esc_html(WS_PLUGIN__S2MEMBER_VERSION) . '. Your existing configuration remains.';
         /**/
         if (!is_multisite() || !c_ws_plugin__s2member_utils_conds::is_multisite_farm() || is_main_site()) {
             /* No Changelog on a Multisite Blog Farm. */
             $notice .= '<br />Have fun, <a href="' . esc_attr(admin_url("/admin.php?page=ws-plugin--s2member-info#rm-changelog")) . '">read the Changelog</a>, and make some money! :-)';
         }
         /**/
         c_ws_plugin__s2member_admin_notices::enqueue_admin_notice($notice, array("blog|network:plugins.php", "blog|network:ws-plugin--s2member-start", "blog|network:ws-plugin--s2member-mms-ops", "blog|network:ws-plugin--s2member-gen-ops", "blog|network:ws-plugin--s2member-res-ops"));
     } else {
         $notice = '<strong>Note:</strong> s2Member adds some new data columns to your list of Users/Members. If your list gets overcrowded, please use the <strong>Screen Options</strong> tab <em>( upper right-hand corner )</em>. With WordPress® Screen Options, you can add/remove specific data columns; thereby making the most important data easier to read. For example, if you create Custom Registration/Profile Fields with s2Member, those Custom Fields will result in new data columns; which can cause your list of Users/Members to become nearly unreadable. So just use the Screen Options tab to clean things up.';
         /**/
         c_ws_plugin__s2member_admin_notices::enqueue_admin_notice($notice, "blog:users.php", false, false, true);
         /**/
         $notice = '<strong>s2Member</strong> v' . esc_html(WS_PLUGIN__S2MEMBER_VERSION) . ' has been <strong>activated</strong>. Nice work!<br />';
         $notice .= 'Have fun, <a href="' . esc_attr(admin_url("/admin.php?page=ws-plugin--s2member-start")) . '">read the Quick Start Guide</a>, and make some money! :-)';
         /**/
         c_ws_plugin__s2member_admin_notices::enqueue_admin_notice($notice, array("blog|network:plugins.php", "blog|network:ws-plugin--s2member-start", "blog|network:ws-plugin--s2member-mms-ops", "blog|network:ws-plugin--s2member-gen-ops", "blog|network:ws-plugin--s2member-res-ops"));
     }
     /**/
     if (is_multisite() && is_main_site()) {
         foreach ((array) ($users = $wpdb->get_results("SELECT `ID` FROM `" . $wpdb->users . "`")) as $user) {
             if (!($originating_blog = get_user_meta($user->ID, "s2member_originating_blog", true))) {
                 update_user_meta($user->ID, "s2member_originating_blog", $current_site->blog_id);
             }
         }
         /**/
         $notice = '<strong>Multisite Network</strong> updated automatically by <strong>s2Member</strong> v' . esc_html(WS_PLUGIN__S2MEMBER_VERSION) . '.<br />';
         $notice .= 'You\'ll want to configure s2Member\'s Multisite options now.<br />';
         $notice .= 'In the Dashboard for your Main Site, see:<br />';
         $notice .= '<code>s2Member -> Multisite ( Config )</code>.';
         /**/
         c_ws_plugin__s2member_admin_notices::enqueue_admin_notice($notice, array("blog|network:plugins.php", "blog|network:ws-plugin--s2member-start", "blog|network:ws-plugin--s2member-mms-ops", "blog|network:ws-plugin--s2member-gen-ops", "blog|network:ws-plugin--s2member-res-ops"));
         /**/
         update_site_option("ws_plugin__s2member_options", (array) get_option("ws_plugin__s2member_options"));
         /**/
         update_option("ws_plugin__s2member_activated_mms_version", WS_PLUGIN__S2MEMBER_VERSION);
     }
     /**/
     update_option("ws_plugin__s2member_activated_version", WS_PLUGIN__S2MEMBER_VERSION);
     /**/
     do_action("ws_plugin__s2member_after_activation", get_defined_vars());
     /**/
     return;
     /* Return for uniformity. */
 }
 /**
  * Activation routines for s2Member.
  *
  * @package s2Member\Installation
  * @since 3.5
  *
  * @return null
  */
 public static function activate($reactivation_reason = FALSE)
 {
     global $wpdb;
     global $current_site, $current_blog;
     do_action("ws_plugin__s2member_before_activation", get_defined_vars());
     c_ws_plugin__s2member_roles_caps::config_roles();
     update_option("ws_plugin__s2member_activated_levels", $GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["levels"]);
     if (!is_dir($files_dir = $GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["files_dir"])) {
         if (is_writable(dirname(c_ws_plugin__s2member_utils_dirs::strip_dir_app_data($files_dir)))) {
             mkdir($files_dir, 0777, true);
         }
     }
     if (is_dir($files_dir) && is_writable($files_dir)) {
         if (!file_exists($htaccess = $files_dir . "/.htaccess") || !apply_filters("ws_plugin__s2member_preserve_files_dir_htaccess", false, get_defined_vars())) {
             file_put_contents($htaccess, trim(c_ws_plugin__s2member_utilities::evl(file_get_contents($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["files_dir_htaccess"]))));
         }
     }
     c_ws_plugin__s2member_files::write_no_gzip_into_root_htaccess();
     if (!is_dir($logs_dir = $GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["logs_dir"])) {
         if (is_writable(dirname(c_ws_plugin__s2member_utils_dirs::strip_dir_app_data($logs_dir)))) {
             mkdir($logs_dir, 0777, true);
         }
     }
     if (is_dir($logs_dir) && is_writable($logs_dir)) {
         if (!file_exists($htaccess = $logs_dir . "/.htaccess") || !apply_filters("ws_plugin__s2member_preserve_logs_dir_htaccess", false, get_defined_vars())) {
             file_put_contents($htaccess, trim(c_ws_plugin__s2member_utilities::evl(file_get_contents($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["logs_dir_htaccess"]))));
         }
     }
     !is_array(get_option("ws_plugin__s2member_cache")) ? update_option("ws_plugin__s2member_cache", array()) : null;
     !is_array(get_option("ws_plugin__s2member_notices")) ? update_option("ws_plugin__s2member_notices", array()) : null;
     !is_array(get_option("ws_plugin__s2member_options")) ? update_option("ws_plugin__s2member_options", array()) : null;
     !is_numeric(get_option("ws_plugin__s2member_configured")) ? update_option("ws_plugin__s2member_configured", "0") : null;
     if ($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["configured"]) {
         $v = get_option("ws_plugin__s2member_activated_version");
         if (!$v || !version_compare($v, "3.2", ">=")) {
             $like = "`meta_key` LIKE 's2member\\_%' AND `meta_key` NOT LIKE '%s2member\\_originating\\_blog%'";
             $wpdb->query("UPDATE `" . $wpdb->usermeta . "` SET `meta_key` = CONCAT('" . $wpdb->prefix . "', `meta_key`) WHERE " . $like);
         }
         if (!$v || !version_compare($v, "3.2.5", ">=")) {
             $wpdb->query("DELETE FROM `" . $wpdb->options . "` WHERE `option_name` LIKE '\\_transient\\_%'");
         }
         if (!$v || !version_compare($v, "3.2.6", ">=")) {
             $wpdb->query("DELETE FROM `" . $wpdb->postmeta . "` WHERE `meta_key` = 's2member_ccaps_req' AND `meta_value` IN('','a:0:{}','a:1:{i:0;s:0:\"\";}')");
         }
         if (!$v || !version_compare($v, "110912", ">=") && $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["filter_wp_query"] === array("all")) {
             $notice = '<strong>IMPORTANT:</strong> This version of s2Member changes the way your <code>Alternative View Protections</code> work. Please review your options under: <code>s2Member -› Restriction Options -› Alternative View Protections</code>.';
             c_ws_plugin__s2member_admin_notices::enqueue_admin_notice($notice, array("blog|network:plugins.php", "blog|network:ws-plugin--s2member-start", "blog|network:ws-plugin--s2member-mms-ops", "blog|network:ws-plugin--s2member-gen-ops", "blog|network:ws-plugin--s2member-res-ops"));
         }
         if ($v && version_compare($v, "130316", "<=")) {
             c_ws_plugin__s2member_menu_pages::update_all_options(array("ws_plugin__s2member_gateway_debug_logs" => "0", "ws_plugin__s2member_gateway_debug_logs_extensive" => "0"), true, false, false, false, false);
             $notice = '<strong>IMPORTANT:</strong> This version of s2Member disables s2Member\'s debug logging by default (for added security). Please see: <a href="' . esc_attr(admin_url("/admin.php?page=ws-plugin--s2member-logs")) . '">s2Member -› Log Files (Debug) -› Configuration</a> for further details.';
             c_ws_plugin__s2member_admin_notices::enqueue_admin_notice($notice, array("blog|network:plugins.php", "blog|network:ws-plugin--s2member-start", "blog|network:ws-plugin--s2member-mms-ops", "blog|network:ws-plugin--s2member-gen-ops", "blog|network:ws-plugin--s2member-res-ops"));
             $notice = '<strong>IMPORTANT / Regarding s2Member Security Badges:</strong> If debug logging is enabled, your site will no longer qualify for an s2Member Security Badge until you disable logging (and you MUST also download, and then delete any existing log files from the past). Please see KB Article: <a href="http://www.s2member.com/kb/security-badges/" target="_blank" rel="external">s2Member Security Badges</a> for further details. If you have existing s2Member log files, you will need to delete those files from the server before your s2Member Security Badge can be re-enabled. s2Member stores log files here: <code>' . esc_html(c_ws_plugin__s2member_utils_dirs::doc_root_path($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["logs_dir"])) . '</code>. See also: <a href="' . esc_attr(admin_url("/admin.php?page=ws-plugin--s2member-logs")) . '">s2Member -› Log Files (Debug) -› Configuration</a> for further details.';
             c_ws_plugin__s2member_admin_notices::enqueue_admin_notice($notice, array("blog|network:plugins.php", "blog|network:ws-plugin--s2member-start", "blog|network:ws-plugin--s2member-mms-ops", "blog|network:ws-plugin--s2member-gen-ops", "blog|network:ws-plugin--s2member-res-ops"));
         }
         $notice = '<strong>s2Member</strong> has been <strong>reactivated</strong>, with ' . ($reactivation_reason === "levels" ? '<code>' . esc_html($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["levels"]) . '</code> Membership Levels' : 'the latest version') . '.<br />';
         $notice .= 'You now have version ' . esc_html(WS_PLUGIN__S2MEMBER_VERSION) . '. Your existing configuration remains.';
         if (!is_multisite() || !c_ws_plugin__s2member_utils_conds::is_multisite_farm() || is_main_site()) {
             // No Changelog on a Multisite Blog Farm.
             $notice .= '<br />Have fun, <a href="' . esc_attr(admin_url("/admin.php?page=ws-plugin--s2member-info#rm-changelog")) . '">read the Changelog</a>, and make some money! :-)';
         }
         c_ws_plugin__s2member_admin_notices::enqueue_admin_notice($notice, array("blog|network:plugins.php", "blog|network:ws-plugin--s2member-start", "blog|network:ws-plugin--s2member-mms-ops", "blog|network:ws-plugin--s2member-gen-ops", "blog|network:ws-plugin--s2member-res-ops"));
     } else {
         $notice = '<strong>Note:</strong> s2Member adds some new data columns to your list of Users/Members. If your list gets overcrowded, please use the <strong>Screen Options</strong> tab <em>(upper right-hand corner)</em>. With WordPress Screen Options, you can add/remove specific data columns; thereby making the most important data easier to read. For example, if you create Custom Registration/Profile Fields with s2Member, those Custom Fields will result in new data columns; which can cause your list of Users/Members to become nearly unreadable. So just use the Screen Options tab to clean things up.';
         c_ws_plugin__s2member_admin_notices::enqueue_admin_notice($notice, "blog:users.php", false, false, true);
         $notice = '<strong>s2Member</strong> v' . esc_html(WS_PLUGIN__S2MEMBER_VERSION) . ' has been <strong>activated</strong>. Nice work!<br />';
         $notice .= 'Have fun, <a href="' . esc_attr(admin_url("/admin.php?page=ws-plugin--s2member-start")) . '">read the Quick Start Guide</a>, and make some money! :-)';
         c_ws_plugin__s2member_admin_notices::enqueue_admin_notice($notice, array("blog|network:plugins.php", "blog|network:ws-plugin--s2member-start", "blog|network:ws-plugin--s2member-mms-ops", "blog|network:ws-plugin--s2member-gen-ops", "blog|network:ws-plugin--s2member-res-ops"));
     }
     if (is_multisite() && is_main_site()) {
         $wpdb->query("INSERT INTO `" . $wpdb->usermeta . "` (`user_id`, `meta_key`, `meta_value`) SELECT `ID`, 's2member_originating_blog', '" . esc_sql($current_site->blog_id) . "' FROM `" . $wpdb->users . "` WHERE `ID` NOT IN (SELECT `user_id` FROM `" . $wpdb->usermeta . "` WHERE `meta_key` = 's2member_originating_blog')");
         $notice = '<strong>Multisite Network</strong> updated automatically by <strong>s2Member</strong> v' . esc_html(WS_PLUGIN__S2MEMBER_VERSION) . '.<br />';
         $notice .= 'You\'ll want to configure s2Member\'s Multisite options now.<br />';
         $notice .= 'In the Dashboard for your Main Site, see:<br />';
         $notice .= '<code>s2Member -› Multisite (Config)</code>.';
         c_ws_plugin__s2member_admin_notices::enqueue_admin_notice($notice, array("blog|network:plugins.php", "blog|network:ws-plugin--s2member-start", "blog|network:ws-plugin--s2member-mms-ops", "blog|network:ws-plugin--s2member-gen-ops", "blog|network:ws-plugin--s2member-res-ops"));
         update_site_option("ws_plugin__s2member_options", (array) get_option("ws_plugin__s2member_options"));
         update_option("ws_plugin__s2member_activated_mms_version", WS_PLUGIN__S2MEMBER_VERSION);
     }
     update_option("ws_plugin__s2member_activated_version", WS_PLUGIN__S2MEMBER_VERSION);
     do_action("ws_plugin__s2member_after_activation", get_defined_vars());
     return;
 }