Example #1
0
 /**
  * Builds and handles the Download Options page.
  *
  * @package s2Member\Menu_Pages
  * @since 3.5
  */
 public static function down_ops_page()
 {
     do_action('ws_plugin__s2member_before_down_ops_page', get_defined_vars());
     c_ws_plugin__s2member_menu_pages::update_all_options();
     if (!empty($_REQUEST['ws_plugin__s2member_cf_options_reset']) && wp_verify_nonce($_REQUEST['ws_plugin__s2member_cf_options_reset'], 'ws-plugin--s2member-cf-options-reset')) {
         c_ws_plugin__s2member_files_in::reset_aws_cf_config_values();
         // A full CloudFront reset.
         c_ws_plugin__s2member_admin_notices::display_admin_notice('Amazon CloudFront configuration reset successfully.');
     }
     $files_dir = $GLOBALS['WS_PLUGIN__']['s2member']['c']['files_dir'];
     $htaccess = $GLOBALS['WS_PLUGIN__']['s2member']['c']['files_dir'] . '/.htaccess';
     $htaccess_contents = trim(c_ws_plugin__s2member_utilities::evl(file_get_contents($GLOBALS['WS_PLUGIN__']['s2member']['c']['files_dir_htaccess'])));
     $no_gzip_htaccess = ABSPATH . '.htaccess';
     // Always located in the absolute root path for WordPress.
     $no_gzip_htaccess_contents = trim(c_ws_plugin__s2member_utilities::evl(file_get_contents($GLOBALS['WS_PLUGIN__']['s2member']['c']['files_no_gzip_htaccess'])));
     if (!c_ws_plugin__s2member_files::no_gzip_rules_in_root_htaccess()) {
         // If s2Member's GZIP exclusions do NOT yet exist in the root `.htaccess` file.
         c_ws_plugin__s2member_files::write_no_gzip_into_root_htaccess() . clearstatcache();
     }
     // Handle the root `.htaccess` file now.
     if (!is_dir($files_dir) && is_writable(dirname(c_ws_plugin__s2member_utils_dirs::strip_dir_app_data($files_dir)))) {
         mkdir($files_dir, 0777, TRUE) . clearstatcache();
     }
     // Create this directory structure now.
     if (is_dir($files_dir) && is_writable($files_dir) && !file_exists($htaccess)) {
         // This file does NOT exist yet?
         file_put_contents($htaccess, $htaccess_contents) . clearstatcache();
     }
     // Create the `.htaccess` file now.
     if (!c_ws_plugin__s2member_files::no_gzip_rules_in_root_htaccess()) {
         // If s2Member's GZIP exclusions do NOT yet exist in the root `.htaccess` file.
         c_ws_plugin__s2member_admin_notices::display_admin_notice('Possible GZIP conflict on server. Unable to write GZIP exclusions into root .htaccess file (<code>' . esc_html(c_ws_plugin__s2member_utils_dirs::doc_root_path($no_gzip_htaccess)) . '</code>). Please read the panel below: <strong>Preventing GZIP Conflicts</strong>, and add this section yourself:<br /><pre>' . esc_html($no_gzip_htaccess_contents) . '</pre>', TRUE);
     }
     if (!is_dir($files_dir)) {
         // If the security-enabled files directory does not exist yet.
         c_ws_plugin__s2member_admin_notices::display_admin_notice('The security-enabled files directory (<code>' . esc_html(c_ws_plugin__s2member_utils_dirs::doc_root_path($files_dir)) . '</code>) does not exist. Please create this directory manually.', TRUE);
     }
     if (!file_exists($htaccess)) {
         // If the `.htaccess` file has not been created yet.
         c_ws_plugin__s2member_admin_notices::display_admin_notice('The .htaccess protection file (<code>' . esc_html(c_ws_plugin__s2member_utils_dirs::doc_root_path($htaccess)) . '</code>) does not exist. Please create this file manually. Inside your .htaccess file, add this:<br /><pre>' . esc_html($htaccess_contents) . '</pre>', TRUE);
     } else {
         if (!preg_match('/deny from all/i', file_get_contents($htaccess))) {
             // Else if the `.htaccess` file does not offer the required protection.
             c_ws_plugin__s2member_admin_notices::display_admin_notice('Unprotected. The .htaccess protection file (<code>' . esc_html(c_ws_plugin__s2member_utils_dirs::doc_root_path($htaccess)) . '</code>) does not contain <code>deny from all</code>. Inside your .htaccess file, add this:<br /><pre>' . esc_html($htaccess_contents) . '</pre>', TRUE);
         }
     }
     if (!empty($_POST['ws_plugin__s2member_amazon_cf_files_auto_configure_distros']) && ($nonce = $_POST['ws_plugin__s2member_amazon_cf_files_auto_configure_distros']) && wp_verify_nonce($nonce, 'ws-plugin--s2member-amazon-cf-files-auto-configure-distros')) {
         if (($amazon_cf_auto_configure_distros = c_ws_plugin__s2member_files_in::amazon_cf_auto_configure_distros()) && $amazon_cf_auto_configure_distros['success']) {
             c_ws_plugin__s2member_admin_notices::display_admin_notice('Amazon CloudFront Distributions auto-configured successfully. Please allow 30 minutes for initial propagation. <strong>Tip:</strong> If you try to stream over the RTMP protocol using something like the <code>[s2Stream /]</code> shortcode, and you keep getting an "ID Not Found" error while using JW Player; please note that it can <em>sometimes</em> take a full 24 hours for RTMP (i.e., streaming distributions) to begin working properly. This is because there are a few initialization routines that must complete on the AWS side when you first integrate with CloudFront. Please be patient.' . ($GLOBALS['WS_PLUGIN__']['s2member']['o']['amazon_cf_files_distro_downloads_cname'] ? '<br /><em>Downloads Distribution CNAME: <code>' . esc_html($GLOBALS['WS_PLUGIN__']['s2member']['o']['amazon_cf_files_distro_downloads_cname']) . ' &mdash;&raquo; ' . esc_html($GLOBALS['WS_PLUGIN__']['s2member']['o']['amazon_cf_files_distro_downloads_dname']) . '</code></em>' : '') . ($GLOBALS['WS_PLUGIN__']['s2member']['o']['amazon_cf_files_distro_streaming_cname'] ? '<br /><em>Streaming Distribution CNAME: <code>' . esc_html($GLOBALS['WS_PLUGIN__']['s2member']['o']['amazon_cf_files_distro_streaming_cname']) . ' &mdash;&raquo; ' . esc_html($GLOBALS['WS_PLUGIN__']['s2member']['o']['amazon_cf_files_distro_streaming_dname']) . '</code></em>' : ''));
         } else {
             // Else there was an error. We need to report this back to the site owner so they can understand what's going on.
             (c_ws_plugin__s2member_menu_pages::$pre_display_errors['cf_files_auto_configure_distros'] = TRUE) . c_ws_plugin__s2member_admin_notices::display_admin_notice('Unable to auto-configure Amazon CloudFront Distributions.<br />Error code: <code>' . esc_html($amazon_cf_auto_configure_distros['code']) . '</code>. Error Message: <code>' . esc_html($amazon_cf_auto_configure_distros['message']) . '</code>', TRUE);
         }
     }
     if (!empty($_POST['ws_plugin__s2member_amazon_s3_files_auto_configure_acls']) && ($nonce = $_POST['ws_plugin__s2member_amazon_s3_files_auto_configure_acls']) && wp_verify_nonce($nonce, 'ws-plugin--s2member-amazon-s3-files-auto-configure-acls')) {
         if (($amazon_s3_auto_configure_acls = c_ws_plugin__s2member_files_in::amazon_s3_auto_configure_acls()) && $amazon_s3_auto_configure_acls['success']) {
             c_ws_plugin__s2member_admin_notices::display_admin_notice('Amazon S3 ACLs auto-configured successfully.');
         } else {
             // Else there was an error. We need to report this back to the site owner so they can understand what's going on.
             (c_ws_plugin__s2member_menu_pages::$pre_display_errors['s3_files_auto_configure_acls'] = TRUE) . c_ws_plugin__s2member_admin_notices::display_admin_notice('Unable to auto-configure Amazon S3 ACLs.<br />Error code: <code>' . esc_html($amazon_s3_auto_configure_acls['code']) . '</code>. Error Message: <code>' . esc_html($amazon_s3_auto_configure_acls['message']) . '</code>', TRUE);
         }
     }
     include_once dirname(dirname(__FILE__)) . '/menu-pages/down-ops.inc.php';
     do_action('ws_plugin__s2member_after_down_ops_page', get_defined_vars());
 }
Example #2
0
 /**
  * Builds and handles the Download Options page.
  *
  * @package s2Member\Menu_Pages
  * @since 3.5
  *
  * @return null
  */
 public static function down_ops_page()
 {
     do_action("ws_plugin__s2member_before_down_ops_page", get_defined_vars());
     c_ws_plugin__s2member_menu_pages::update_all_options();
     $files_dir = $GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["files_dir"];
     $htaccess = $GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["files_dir"] . "/.htaccess";
     $htaccess_contents = trim(c_ws_plugin__s2member_utilities::evl(file_get_contents($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["files_dir_htaccess"])));
     $no_gzip_htaccess = ABSPATH . ".htaccess";
     $no_gzip_htaccess_contents = trim(c_ws_plugin__s2member_utilities::evl(file_get_contents($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["files_no_gzip_htaccess"])));
     if (!c_ws_plugin__s2member_files::no_gzip_rules_in_root_htaccess()) {
         c_ws_plugin__s2member_files::write_no_gzip_into_root_htaccess() . clearstatcache();
     }
     if (!is_dir($files_dir) && is_writable(dirname(c_ws_plugin__s2member_utils_dirs::strip_dir_app_data($files_dir)))) {
         mkdir($files_dir, 0777, true) . clearstatcache();
     }
     if (is_dir($files_dir) && is_writable($files_dir) && !file_exists($htaccess)) {
         file_put_contents($htaccess, $htaccess_contents) . clearstatcache();
     }
     if (!c_ws_plugin__s2member_files::no_gzip_rules_in_root_htaccess()) {
         c_ws_plugin__s2member_admin_notices::display_admin_notice('Possible GZIP conflict on server. Unable to write GZIP exclusions into root .htaccess file (<code>' . esc_html(c_ws_plugin__s2member_utils_dirs::doc_root_path($no_gzip_htaccess)) . '</code>). Please read the panel below: <strong>Preventing GZIP Conflicts</strong>, and add this section yourself:<br /><pre>' . esc_html($no_gzip_htaccess_contents) . '</pre>', true);
     }
     if (!is_dir($files_dir)) {
         c_ws_plugin__s2member_admin_notices::display_admin_notice('The security-enabled files directory (<code>' . esc_html(c_ws_plugin__s2member_utils_dirs::doc_root_path($files_dir)) . '</code>) does not exist. Please create this directory manually.', true);
     }
     if (!file_exists($htaccess)) {
         c_ws_plugin__s2member_admin_notices::display_admin_notice('The .htaccess protection file (<code>' . esc_html(c_ws_plugin__s2member_utils_dirs::doc_root_path($htaccess)) . '</code>) does not exist. Please create this file manually. Inside your .htaccess file, add this:<br /><pre>' . esc_html($htaccess_contents) . '</pre>', true);
     } else {
         if (!preg_match("/deny from all/i", file_get_contents($htaccess))) {
             c_ws_plugin__s2member_admin_notices::display_admin_notice('Unprotected. The .htaccess protection file (<code>' . esc_html(c_ws_plugin__s2member_utils_dirs::doc_root_path($htaccess)) . '</code>) does not contain <code>deny from all</code>. Inside your .htaccess file, add this:<br /><pre>' . esc_html($htaccess_contents) . '</pre>', true);
         }
     }
     if (!empty($_POST["ws_plugin__s2member_amazon_cf_files_auto_configure_distros"]) && ($nonce = $_POST["ws_plugin__s2member_amazon_cf_files_auto_configure_distros"]) && wp_verify_nonce($nonce, "ws-plugin--s2member-amazon-cf-files-auto-configure-distros")) {
         if (($amazon_cf_auto_configure_distros = c_ws_plugin__s2member_files_in::amazon_cf_auto_configure_distros()) && $amazon_cf_auto_configure_distros["success"]) {
             c_ws_plugin__s2member_admin_notices::display_admin_notice('Amazon CloudFront Distributions auto-configured successfully. Please allow 30 minutes for propagation.' . ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["amazon_cf_files_distro_downloads_cname"] ? '<br /><em>Downloads Distribution CNAME: <code>' . esc_html($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["amazon_cf_files_distro_downloads_cname"]) . ' &mdash;&raquo; ' . esc_html($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["amazon_cf_files_distro_downloads_dname"]) . '</code></em>' : '') . ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["amazon_cf_files_distro_streaming_cname"] ? '<br /><em>Streaming Distribution CNAME: <code>' . esc_html($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["amazon_cf_files_distro_streaming_cname"]) . ' &mdash;&raquo; ' . esc_html($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["amazon_cf_files_distro_streaming_dname"]) . '</code></em>' : ''));
         } else {
             // Else there was an error. We need to report this back to the site owner so they can understand what's going on.
             (c_ws_plugin__s2member_menu_pages::$pre_display_errors["cf_files_auto_configure_distros"] = true) . c_ws_plugin__s2member_admin_notices::display_admin_notice('Unable to auto-configure Amazon CloudFront Distributions.<br />Error code: <code>' . esc_html($amazon_cf_auto_configure_distros["code"]) . '</code>. Error Message: <code>' . esc_html($amazon_cf_auto_configure_distros["message"]) . '</code>', true);
         }
     }
     if (!empty($_POST["ws_plugin__s2member_amazon_s3_files_auto_configure_acls"]) && ($nonce = $_POST["ws_plugin__s2member_amazon_s3_files_auto_configure_acls"]) && wp_verify_nonce($nonce, "ws-plugin--s2member-amazon-s3-files-auto-configure-acls")) {
         if (($amazon_s3_auto_configure_acls = c_ws_plugin__s2member_files_in::amazon_s3_auto_configure_acls()) && $amazon_s3_auto_configure_acls["success"]) {
             c_ws_plugin__s2member_admin_notices::display_admin_notice('Amazon S3 ACLs auto-configured successfully.');
         } else {
             // Else there was an error. We need to report this back to the site owner so they can understand what's going on.
             (c_ws_plugin__s2member_menu_pages::$pre_display_errors["s3_files_auto_configure_acls"] = true) . c_ws_plugin__s2member_admin_notices::display_admin_notice('Unable to auto-configure Amazon S3 ACLs.<br />Error code: <code>' . esc_html($amazon_s3_auto_configure_acls["code"]) . '</code>. Error Message: <code>' . esc_html($amazon_s3_auto_configure_acls["message"]) . '</code>', true);
         }
     }
     include_once dirname(dirname(__FILE__)) . "/menu-pages/down-ops.inc.php";
     do_action("ws_plugin__s2member_after_down_ops_page", get_defined_vars());
     return;
 }
 /**
  * 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());
 }
 /**
  * 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;
 }