s2Member Framework (Member Roles, Capabilities, Membership, PayPal Members) - Version 140909

Version Description

= v140909 =

(Maintenance Release) Upgrade immediately.

Download this release

Release Info

Developer JasWSInc
Plugin Icon 128x128 s2Member Framework (Member Roles, Capabilities, Membership, PayPal Members)
Version 140909
Comparing to
See all releases

Code changes from version 140816 to 140909

checksum.txt CHANGED
@@ -1 +1 @@
1
- fe5b4d8fea0ad64e6be257a6b6bba04c
1
+ 3ee3f832a3c7897fa64963d6ac416878
includes/classes/admin-lockouts.inc.php CHANGED
@@ -78,7 +78,7 @@ if(!class_exists('c_ws_plugin__s2member_admin_lockouts'))
78
  $id = 's2-site-name'; // Give this a special/unique ID.
79
  $title = wp_html_excerpt(get_bloginfo('name'), 42); // A brief excerpt.
80
  $title = ($title !== get_bloginfo('name')) ? trim($title).'…' : $title;
81
- $href = site_url('/'); // Change to front page.
82
 
83
  $wp_admin_bar->add_node(array('id' => $id, 'title' => $title, 'href' => $href));
84
  $wp_admin_bar->remove_node('site-name');
78
  $id = 's2-site-name'; // Give this a special/unique ID.
79
  $title = wp_html_excerpt(get_bloginfo('name'), 42); // A brief excerpt.
80
  $title = ($title !== get_bloginfo('name')) ? trim($title).'…' : $title;
81
+ $href = home_url('/'); // Change to front page.
82
 
83
  $wp_admin_bar->add_node(array('id' => $id, 'title' => $title, 'href' => $href));
84
  $wp_admin_bar->remove_node('site-name');
includes/classes/constants.inc.php CHANGED
@@ -1371,7 +1371,7 @@ if (!class_exists ("c_ws_plugin__s2member_constants"))
1371
  * @see `Dashboard -› s2Member -› General Options -› Profile Modifications`
1372
  */
1373
  if (!defined ("S2MEMBER_CURRENT_USER_PROFILE_MODIFICATION_PAGE_URL"))
1374
- define ("S2MEMBER_CURRENT_USER_PROFILE_MODIFICATION_PAGE_URL", ($c[] = (string)site_url ("/?s2member_profile=1")));
1375
  /**
1376
  * A URL, which leads to the Download Limit Exceeded Page; as configured by the site owner.
1377
  *
@@ -1859,7 +1859,7 @@ if (!class_exists ("c_ws_plugin__s2member_constants"))
1859
  * @see `Dashboard -› s2Member -› PayPal Options -› IPN Integration`
1860
  */
1861
  if (!defined ("S2MEMBER_PAYPAL_NOTIFY_URL"))
1862
- define ("S2MEMBER_PAYPAL_NOTIFY_URL", ($c[] = (string)site_url ("/?s2member_paypal_notify=1")));
1863
  /**
1864
  * Full URL to PayPal Auto-Return/PDT handler, provided by s2Member.
1865
  *
@@ -1887,7 +1887,7 @@ if (!class_exists ("c_ws_plugin__s2member_constants"))
1887
  * @see `Dashboard -› s2Member -› PayPal Options -› Auto-Return/PDT Integration`
1888
  */
1889
  if (!defined ("S2MEMBER_PAYPAL_RETURN_URL"))
1890
- define ("S2MEMBER_PAYPAL_RETURN_URL", ($c[] = (string)site_url ("/?s2member_paypal_return=1")));
1891
  /**
1892
  * PayPal Business Email Address; as configured by the site owner.
1893
  *
1371
  * @see `Dashboard -› s2Member -› General Options -› Profile Modifications`
1372
  */
1373
  if (!defined ("S2MEMBER_CURRENT_USER_PROFILE_MODIFICATION_PAGE_URL"))
1374
+ define ("S2MEMBER_CURRENT_USER_PROFILE_MODIFICATION_PAGE_URL", ($c[] = (string)home_url ("/?s2member_profile=1")));
1375
  /**
1376
  * A URL, which leads to the Download Limit Exceeded Page; as configured by the site owner.
1377
  *
1859
  * @see `Dashboard -› s2Member -› PayPal Options -› IPN Integration`
1860
  */
1861
  if (!defined ("S2MEMBER_PAYPAL_NOTIFY_URL"))
1862
+ define ("S2MEMBER_PAYPAL_NOTIFY_URL", ($c[] = (string)home_url ("/?s2member_paypal_notify=1")));
1863
  /**
1864
  * Full URL to PayPal Auto-Return/PDT handler, provided by s2Member.
1865
  *
1887
  * @see `Dashboard -› s2Member -› PayPal Options -› Auto-Return/PDT Integration`
1888
  */
1889
  if (!defined ("S2MEMBER_PAYPAL_RETURN_URL"))
1890
+ define ("S2MEMBER_PAYPAL_RETURN_URL", ($c[] = (string)home_url ("/?s2member_paypal_return=1")));
1891
  /**
1892
  * PayPal Business Email Address; as configured by the site owner.
1893
  *
includes/classes/files-in.inc.php CHANGED
@@ -350,7 +350,7 @@ if(!class_exists('c_ws_plugin__s2member_files_in'))
350
  $url .= (isset($req['file_remote'])) ? (($remote) ? '&s2member_file_remote=yes' : '&s2member_file_remote=no') : '';
351
  $url .= (isset($req['skip_confirmation'])) ? (($skip_confirmation) ? '&s2member_skip_confirmation=yes' : '&s2member_skip_confirmation=no') : '';
352
 
353
- $url = site_url('/?'.ltrim($url.'&s2member_file_download=/'.$_url_e_file, '&'));
354
  $url = ($ssl) ? preg_replace('/^https?/', 'https', $url) : preg_replace('/^https?/', 'http', $url);
355
 
356
  return apply_filters('ws_plugin__s2member_file_download_access_url', $url, get_defined_vars());
350
  $url .= (isset($req['file_remote'])) ? (($remote) ? '&s2member_file_remote=yes' : '&s2member_file_remote=no') : '';
351
  $url .= (isset($req['skip_confirmation'])) ? (($skip_confirmation) ? '&s2member_skip_confirmation=yes' : '&s2member_skip_confirmation=no') : '';
352
 
353
+ $url = home_url('/?'.ltrim($url.'&s2member_file_download=/'.$_url_e_file, '&'));
354
  $url = ($ssl) ? preg_replace('/^https?/', 'https', $url) : preg_replace('/^https?/', 'http', $url);
355
 
356
  return apply_filters('ws_plugin__s2member_file_download_access_url', $url, get_defined_vars());
includes/classes/login-customizations.inc.php CHANGED
@@ -119,6 +119,7 @@ if(!class_exists('c_ws_plugin__s2member_login_customizations'))
119
 
120
  $a[] = 'div#login form p { margin:2px 0 16px 0'.$i.'; }'; // Handles paragraph margins inside the form.
121
  $a[] = 'div#login form input[type="text"], div#login form input[type="email"], div#login form input[type="password"], div#login form textarea, div#login form select { margin:0'.$i.'; padding:3px'.$i.'; border-radius:3px'.$i.'; box-sizing:border-box'.$i.'; width:100%'.$i.'; background:#FBFBFB repeat scroll 0 0'.$i.'; border:1px solid #E5E5E5'.$i.'; font-size:'.$GLOBALS['WS_PLUGIN__']['s2member']['o']['login_reg_font_field_size'].$i.'; font-weight:normal'.$i.'; color:#333333'.$i.'; }';
 
122
  $a[] = 'div#login form label { cursor:pointer'.$i.'; } div#login form label.ws-plugin--s2member-custom-reg-field-op-l { opacity:0.7'.$i.'; font-size:90%'.$i.'; vertical-align:middle'.$i.'; }';
123
  $a[] = 'div#login form input[type="checkbox"], div#login form input[type="radio"] { margin:0 3px 0 0'.$i.'; vertical-align:middle'.$i.'; }';
124
  $a[] = 'div#login form input#ws-plugin--s2member-custom-reg-field-user-pass2[type="password"] { margin-top:5px'.$i.'; }';
119
 
120
  $a[] = 'div#login form p { margin:2px 0 16px 0'.$i.'; }'; // Handles paragraph margins inside the form.
121
  $a[] = 'div#login form input[type="text"], div#login form input[type="email"], div#login form input[type="password"], div#login form textarea, div#login form select { margin:0'.$i.'; padding:3px'.$i.'; border-radius:3px'.$i.'; box-sizing:border-box'.$i.'; width:100%'.$i.'; background:#FBFBFB repeat scroll 0 0'.$i.'; border:1px solid #E5E5E5'.$i.'; font-size:'.$GLOBALS['WS_PLUGIN__']['s2member']['o']['login_reg_font_field_size'].$i.'; font-weight:normal'.$i.'; color:#333333'.$i.'; }';
122
+ $a[] = '@supports (-moz-appearance: none){ div#login form select { font-size:'.min((integer)$GLOBALS['WS_PLUGIN__']['s2member']['o']['login_reg_font_field_size'], 15).'px'.$i.'; } }'; // Mozilla doesn't like the larger font size. This corrects that issue in Firefox.
123
  $a[] = 'div#login form label { cursor:pointer'.$i.'; } div#login form label.ws-plugin--s2member-custom-reg-field-op-l { opacity:0.7'.$i.'; font-size:90%'.$i.'; vertical-align:middle'.$i.'; }';
124
  $a[] = 'div#login form input[type="checkbox"], div#login form input[type="radio"] { margin:0 3px 0 0'.$i.'; vertical-align:middle'.$i.'; }';
125
  $a[] = 'div#login form input#ws-plugin--s2member-custom-reg-field-user-pass2[type="password"] { margin-top:5px'.$i.'; }';
includes/classes/menu-pages.inc.php CHANGED
@@ -299,7 +299,7 @@ if(!class_exists('c_ws_plugin__s2member_menu_pages'))
299
  wp_enqueue_script('jquery-sprintf', $GLOBALS['WS_PLUGIN__']['s2member']['c']['dir_url'].'/includes/jquery/jquery.sprintf/jquery.sprintf-min.js', array('jquery'), c_ws_plugin__s2member_utilities::ver_checksum());
300
  wp_enqueue_script('jquery-json-ps', $GLOBALS['WS_PLUGIN__']['s2member']['c']['dir_url'].'/includes/jquery/jquery.json-ps/jquery.json-ps-min.js', array('jquery'), c_ws_plugin__s2member_utilities::ver_checksum());
301
  wp_enqueue_script('jquery-ui-effects', $GLOBALS['WS_PLUGIN__']['s2member']['c']['dir_url'].'/includes/jquery/jquery.ui-effects/jquery.ui-effects-min.js', array('jquery', 'jquery-ui-core'), c_ws_plugin__s2member_utilities::ver_checksum());
302
- wp_enqueue_script('ws-plugin--s2member-menu-pages', site_url('/?ws_plugin__s2member_menu_pages_js='.urlencode(mt_rand())), array('jquery', 'thickbox', 'media-upload', 'jquery-sprintf', 'jquery-json-ps', 'jquery-ui-core', 'jquery-ui-effects', 'password-strength-meter'), c_ws_plugin__s2member_utilities::ver_checksum());
303
 
304
  do_action('ws_plugin__s2member_during_add_admin_scripts', get_defined_vars());
305
  }
@@ -321,7 +321,7 @@ if(!class_exists('c_ws_plugin__s2member_menu_pages'))
321
  if(!empty($_GET['page']) && preg_match('/ws-plugin--s2member-/', $_GET['page']))
322
  {
323
  wp_enqueue_style('thickbox');
324
- wp_enqueue_style('ws-plugin--s2member-menu-pages', site_url('/?ws_plugin__s2member_menu_pages_css='.urlencode(mt_rand())), array('thickbox'), c_ws_plugin__s2member_utilities::ver_checksum(), 'all');
325
 
326
  do_action('ws_plugin__s2member_during_add_admin_styles', get_defined_vars());
327
  }
299
  wp_enqueue_script('jquery-sprintf', $GLOBALS['WS_PLUGIN__']['s2member']['c']['dir_url'].'/includes/jquery/jquery.sprintf/jquery.sprintf-min.js', array('jquery'), c_ws_plugin__s2member_utilities::ver_checksum());
300
  wp_enqueue_script('jquery-json-ps', $GLOBALS['WS_PLUGIN__']['s2member']['c']['dir_url'].'/includes/jquery/jquery.json-ps/jquery.json-ps-min.js', array('jquery'), c_ws_plugin__s2member_utilities::ver_checksum());
301
  wp_enqueue_script('jquery-ui-effects', $GLOBALS['WS_PLUGIN__']['s2member']['c']['dir_url'].'/includes/jquery/jquery.ui-effects/jquery.ui-effects-min.js', array('jquery', 'jquery-ui-core'), c_ws_plugin__s2member_utilities::ver_checksum());
302
+ wp_enqueue_script('ws-plugin--s2member-menu-pages', home_url('/?ws_plugin__s2member_menu_pages_js='.urlencode(mt_rand())), array('jquery', 'thickbox', 'media-upload', 'jquery-sprintf', 'jquery-json-ps', 'jquery-ui-core', 'jquery-ui-effects', 'password-strength-meter'), c_ws_plugin__s2member_utilities::ver_checksum());
303
 
304
  do_action('ws_plugin__s2member_during_add_admin_scripts', get_defined_vars());
305
  }
321
  if(!empty($_GET['page']) && preg_match('/ws-plugin--s2member-/', $_GET['page']))
322
  {
323
  wp_enqueue_style('thickbox');
324
+ wp_enqueue_style('ws-plugin--s2member-menu-pages', home_url('/?ws_plugin__s2member_menu_pages_css='.urlencode(mt_rand())), array('thickbox'), c_ws_plugin__s2member_utilities::ver_checksum(), 'all');
325
 
326
  do_action('ws_plugin__s2member_during_add_admin_styles', get_defined_vars());
327
  }
includes/classes/profile-in.inc.php CHANGED
@@ -51,7 +51,7 @@ if(!class_exists('c_ws_plugin__s2member_profile_in'))
51
 
52
  echo '<body style="'.esc_attr(apply_filters('ws_plugin__s2member_profile_body_styles', "background:#FFFFFF; color:#333333; font-family:'Verdana', sans-serif; font-size:13px;", get_defined_vars())).'">'."\n";
53
 
54
- echo '<form method="post" name="ws_plugin__s2member_profile" id="ws-plugin--s2member-profile" action="'.esc_attr(site_url('/')).'">'."\n";
55
 
56
  foreach(array_keys(get_defined_vars()) as $__v) $__refs[$__v] =& $$__v;
57
  do_action('ws_plugin__s2member_during_profile_before_table', get_defined_vars());
51
 
52
  echo '<body style="'.esc_attr(apply_filters('ws_plugin__s2member_profile_body_styles', "background:#FFFFFF; color:#333333; font-family:'Verdana', sans-serif; font-size:13px;", get_defined_vars())).'">'."\n";
53
 
54
+ echo '<form method="post" name="ws_plugin__s2member_profile" id="ws-plugin--s2member-profile" action="'.esc_attr(home_url('/')).'">'."\n";
55
 
56
  foreach(array_keys(get_defined_vars()) as $__v) $__refs[$__v] =& $$__v;
57
  do_action('ws_plugin__s2member_during_profile_before_table', get_defined_vars());
includes/classes/querys.inc.php CHANGED
@@ -83,25 +83,29 @@ if(!class_exists('c_ws_plugin__s2member_querys'))
83
  *
84
  * @todo Make it possible to force filtering, even when used in combination with Query Conditionals and ``get_posts()``, which auto-supresses.
85
  * Or, perhaps strengthen the existing ``$force`` parameter in this regard.
 
 
86
  */
87
  public static function query_level_access(&$wp_query = NULL, $force = FALSE)
88
  {
89
  global $wpdb; // Global DB object reference.
90
  static $initial_query = TRUE; // Tracks the initial query.
91
- c_ws_plugin__s2member_querys::$current_wp_query = & $wp_query;
92
 
93
  foreach(array_keys(get_defined_vars()) as $__v) $__refs[$__v] =& $$__v;
94
  do_action('ws_plugin__s2member_before_query_level_access', get_defined_vars());
95
  unset($__refs, $__v); // Housekeeping.
96
 
97
- c_ws_plugin__s2member_querys::_query_level_access_sys($wp_query); // Systematics.
 
 
98
 
99
  remove_filter('comment_feed_where', 'c_ws_plugin__s2member_querys::_query_level_access_coms', 100, 2);
100
  remove_filter('wp_get_nav_menu_items', 'c_ws_plugin__s2member_querys::_query_level_access_navs', 100);
101
 
102
  if(is_object($wpdb) && is_object($wp_query) && (($o = $GLOBALS['WS_PLUGIN__']['s2member']['o']['filter_wp_query']) || $force))
103
  {
104
- if(!is_admin() || c_ws_plugin__s2member_querys::_is_admin_ajax_search($wp_query))
105
  {
106
  $suppressing_filters = $wp_query->get('suppress_filters'); // Filter suppression on?
107
  if(!$suppressing_filters && $force // Forcing this routine bypasses all of these other conditionals. Works with API function ``attach_s2member_query_filters()``.
@@ -305,7 +309,7 @@ if(!class_exists('c_ws_plugin__s2member_querys'))
305
  public static function _query_level_access_navs($items = array())
306
  {
307
  global $wpdb; // Global DB object reference.
308
- $wp_query = & c_ws_plugin__s2member_querys::$current_wp_query;
309
 
310
  if(is_array($items) && !empty($items) && is_object($wpdb) && is_object($wp_query) && $wp_query->get('suppress_filters') !== 'n/a')
311
  {
@@ -403,7 +407,26 @@ if(!class_exists('c_ws_plugin__s2member_querys'))
403
  else if($GLOBALS['WS_PLUGIN__']['s2member']['o']['level'.$n.'_pages'] && !current_user_can('access_s2member_level'.$n))
404
  $excludes = array_merge($excludes, c_ws_plugin__s2member_utils_arrays::force_integers(preg_split('/['."\r\n\t".'\s;,]+/', $GLOBALS['WS_PLUGIN__']['s2member']['o']['level'.$n.'_pages'])));
405
  }
406
- return $excludes;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
407
  }
408
  }
409
  }
83
  *
84
  * @todo Make it possible to force filtering, even when used in combination with Query Conditionals and ``get_posts()``, which auto-supresses.
85
  * Or, perhaps strengthen the existing ``$force`` parameter in this regard.
86
+ *
87
+ * @see Workaround for bbPress and the `s` key. See: <http://bit.ly/1obLpv4>
88
  */
89
  public static function query_level_access(&$wp_query = NULL, $force = FALSE)
90
  {
91
  global $wpdb; // Global DB object reference.
92
  static $initial_query = TRUE; // Tracks the initial query.
93
+ c_ws_plugin__s2member_querys::$current_wp_query = &$wp_query;
94
 
95
  foreach(array_keys(get_defined_vars()) as $__v) $__refs[$__v] =& $$__v;
96
  do_action('ws_plugin__s2member_before_query_level_access', get_defined_vars());
97
  unset($__refs, $__v); // Housekeeping.
98
 
99
+ if(is_object($wp_query) && !$wp_query->get('___s2_is_bbp_has_replies'))
100
+ // Workaround for bbPress and the `s` key. See: <http://bit.ly/1obLpv4>
101
+ c_ws_plugin__s2member_querys::_query_level_access_sys($wp_query); // Systematics.
102
 
103
  remove_filter('comment_feed_where', 'c_ws_plugin__s2member_querys::_query_level_access_coms', 100, 2);
104
  remove_filter('wp_get_nav_menu_items', 'c_ws_plugin__s2member_querys::_query_level_access_navs', 100);
105
 
106
  if(is_object($wpdb) && is_object($wp_query) && (($o = $GLOBALS['WS_PLUGIN__']['s2member']['o']['filter_wp_query']) || $force))
107
  {
108
+ if((!is_admin() || c_ws_plugin__s2member_querys::_is_admin_ajax_search($wp_query)) && !$wp_query->get('___s2_is_bbp_has_replies') /* See: <http://bit.ly/1obLpv4> */)
109
  {
110
  $suppressing_filters = $wp_query->get('suppress_filters'); // Filter suppression on?
111
  if(!$suppressing_filters && $force // Forcing this routine bypasses all of these other conditionals. Works with API function ``attach_s2member_query_filters()``.
309
  public static function _query_level_access_navs($items = array())
310
  {
311
  global $wpdb; // Global DB object reference.
312
+ $wp_query = &c_ws_plugin__s2member_querys::$current_wp_query;
313
 
314
  if(is_array($items) && !empty($items) && is_object($wpdb) && is_object($wp_query) && $wp_query->get('suppress_filters') !== 'n/a')
315
  {
407
  else if($GLOBALS['WS_PLUGIN__']['s2member']['o']['level'.$n.'_pages'] && !current_user_can('access_s2member_level'.$n))
408
  $excludes = array_merge($excludes, c_ws_plugin__s2member_utils_arrays::force_integers(preg_split('/['."\r\n\t".'\s;,]+/', $GLOBALS['WS_PLUGIN__']['s2member']['o']['level'.$n.'_pages'])));
409
  }
410
+ return apply_filters('_ws_plugin__s2member_query_level_access_list_pages', $excludes, get_defined_vars());
411
+ }
412
+
413
+ /**
414
+ * Flags a WP Query has being a `bbp_has_replies()` query.
415
+ *
416
+ * @package s2Member\Queries
417
+ * @since 140906
418
+ *
419
+ * @attaches-to ``add_filter('bbp_has_replies_query');``
420
+ *
421
+ * @param array $args Query arguments passed by the filter.
422
+ *
423
+ * @return array The array of ``$args``.
424
+ *
425
+ * @see Workaround for bbPress and the `s` key. See: <http://bit.ly/1obLpv4>
426
+ */
427
+ public static function _bbp_flag_has_replies($args)
428
+ {
429
+ return array_merge($args, array('___s2_is_bbp_has_replies' => TRUE));
430
  }
431
  }
432
  }
includes/classes/register-access.inc.php CHANGED
@@ -50,7 +50,7 @@ if (!class_exists ("c_ws_plugin__s2member_register_access"))
50
  {
51
  $register = c_ws_plugin__s2member_utils_encryption::encrypt ("subscr_gateway_subscr_id_custom_item_number_time:.:|:.:" . $subscr_gateway . ":.:|:.:" . $subscr_id . ":.:|:.:" . $custom . ":.:|:.:" . $item_number . ":.:|:.:" . strtotime ("now"));
52
 
53
- $register_link = site_url ("/?s2member_register=" . urlencode ($register)); // Generate long URL/link.
54
 
55
  if ($shrink && ($shorter_url = c_ws_plugin__s2member_utils_urls::shorten ($register_link)))
56
  $register_link = $shorter_url . "#" . $_SERVER["HTTP_HOST"];
50
  {
51
  $register = c_ws_plugin__s2member_utils_encryption::encrypt ("subscr_gateway_subscr_id_custom_item_number_time:.:|:.:" . $subscr_gateway . ":.:|:.:" . $subscr_id . ":.:|:.:" . $custom . ":.:|:.:" . $item_number . ":.:|:.:" . strtotime ("now"));
52
 
53
+ $register_link = home_url ("/?s2member_register=" . urlencode ($register)); // Generate long URL/link.
54
 
55
  if ($shrink && ($shorter_url = c_ws_plugin__s2member_utils_urls::shorten ($register_link)))
56
  $register_link = $shorter_url . "#" . $_SERVER["HTTP_HOST"];
includes/classes/registrations.inc.php CHANGED
@@ -692,13 +692,13 @@ if (!class_exists ("c_ws_plugin__s2member_registrations"))
692
  if (($transient = "s2m_" . md5 ("s2member_transient_ipn_subscr_payment_" . $subscr_id)) && is_array($subscr_payment = get_transient ($transient)) && !empty($subscr_payment["subscr_gateway"]))
693
  {
694
  $proxy = array("s2member_paypal_proxy" => stripslashes ((string)$subscr_payment["subscr_gateway"]), "s2member_paypal_proxy_verification" => c_ws_plugin__s2member_paypal_utilities::paypal_proxy_key_gen ());
695
- c_ws_plugin__s2member_utils_urls::remote (site_url ("/?s2member_paypal_notify=1"), array_merge(stripslashes_deep ($subscr_payment), $proxy), array("timeout" => 20));
696
  delete_transient ($transient); // This can be deleted now.
697
  }
698
  if (($transient = "s2m_" . md5 ("s2member_transient_ipn_subscr_eot_" . $subscr_id)) && is_array($subscr_eot = get_transient ($transient)) && !empty($subscr_eot["subscr_gateway"]))
699
  {
700
  $proxy = array("s2member_paypal_proxy" => stripslashes ((string)$subscr_eot["subscr_gateway"]), "s2member_paypal_proxy_verification" => c_ws_plugin__s2member_paypal_utilities::paypal_proxy_key_gen ());
701
- c_ws_plugin__s2member_utils_urls::remote (site_url ("/?s2member_paypal_notify=1"), array_merge(stripslashes_deep ($subscr_eot), $proxy), array("timeout" => 20));
702
  delete_transient ($transient); // This can be deleted now.
703
  }
704
  if (!headers_sent ()) // Only if headers are NOT yet sent. Here we establish both Signup and Payment Tracking Cookies.
692
  if (($transient = "s2m_" . md5 ("s2member_transient_ipn_subscr_payment_" . $subscr_id)) && is_array($subscr_payment = get_transient ($transient)) && !empty($subscr_payment["subscr_gateway"]))
693
  {
694
  $proxy = array("s2member_paypal_proxy" => stripslashes ((string)$subscr_payment["subscr_gateway"]), "s2member_paypal_proxy_verification" => c_ws_plugin__s2member_paypal_utilities::paypal_proxy_key_gen ());
695
+ c_ws_plugin__s2member_utils_urls::remote (home_url ("/?s2member_paypal_notify=1"), array_merge(stripslashes_deep ($subscr_payment), $proxy), array("timeout" => 20));
696
  delete_transient ($transient); // This can be deleted now.
697
  }
698
  if (($transient = "s2m_" . md5 ("s2member_transient_ipn_subscr_eot_" . $subscr_id)) && is_array($subscr_eot = get_transient ($transient)) && !empty($subscr_eot["subscr_gateway"]))
699
  {
700
  $proxy = array("s2member_paypal_proxy" => stripslashes ((string)$subscr_eot["subscr_gateway"]), "s2member_paypal_proxy_verification" => c_ws_plugin__s2member_paypal_utilities::paypal_proxy_key_gen ());
701
+ c_ws_plugin__s2member_utils_urls::remote (home_url ("/?s2member_paypal_notify=1"), array_merge(stripslashes_deep ($subscr_eot), $proxy), array("timeout" => 20));
702
  delete_transient ($transient); // This can be deleted now.
703
  }
704
  if (!headers_sent ()) // Only if headers are NOT yet sent. Here we establish both Signup and Payment Tracking Cookies.
includes/classes/sc-paypal-button-in.inc.php CHANGED
@@ -74,7 +74,7 @@ if (!class_exists ("c_ws_plugin__s2member_sc_paypal_button_in"))
74
 
75
  $code = trim (c_ws_plugin__s2member_utilities::evl (file_get_contents (dirname (dirname (__FILE__)) . "/templates/buttons/paypal-cancellation-button.php")));
76
  $code = preg_replace ("/%%images%%/", c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr ($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["dir_url"] . "/images")), $code);
77
- $code = preg_replace ("/%%wpurl%%/", c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr (site_url ())), $code);
78
 
79
  $code = preg_replace ("/%%endpoint%%/", c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr (($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["paypal_sandbox"]) ? "www.sandbox.paypal.com" : "www.paypal.com")), $code);
80
  $code = preg_replace ("/%%paypal_business%%/", c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["paypal_business"])), $code);
@@ -106,18 +106,18 @@ if (!class_exists ("c_ws_plugin__s2member_sc_paypal_button_in"))
106
 
107
  $attr["sp_ids_exp"] = /* Combined "sp:ids:expiration hours". */ "sp:" . $attr["ids"] . ":" . $attr["exp"];
108
 
109
- $success_return_url = /* s2Member handles this all by itself. However, it can be Filtered. */ site_url ("/?s2member_paypal_return=1");
110
  $success_return_url = apply_filters("ws_plugin__s2member_during_sc_paypal_button_success_return_url", $success_return_url, get_defined_vars ());
111
 
112
  $code = trim (c_ws_plugin__s2member_utilities::evl (file_get_contents (dirname (dirname (__FILE__)) . "/templates/buttons/paypal-sp-checkout-button.php")));
113
  $code = preg_replace ("/%%images%%/", c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr ($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["dir_url"] . "/images")), $code);
114
- $code = preg_replace ("/%%wpurl%%/", c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr (site_url ())), $code);
115
 
116
  $code = preg_replace ("/%%endpoint%%/", c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr (($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["paypal_sandbox"]) ? "www.sandbox.paypal.com" : "www.paypal.com")), $code);
117
  $code = preg_replace ("/%%paypal_business%%/", c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["paypal_business"])), $code);
118
  $code = preg_replace ("/%%paypal_merchant_id%%/", c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["paypal_merchant_id"])), $code);
119
  $code = preg_replace ("/%%cancel_return%%/", c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr (home_url ("/"))), $code);
120
- $code = preg_replace ("/%%notify_url%%/", c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr (site_url ("/?s2member_paypal_notify=1"))), $code);
121
  $code = preg_replace ("/%%return%%/", c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr ($success_return_url)), $code);
122
  $code = preg_replace ("/%%custom%%/", c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr ($attr["custom"])), $code);
123
 
@@ -162,18 +162,18 @@ if (!class_exists ("c_ws_plugin__s2member_sc_paypal_button_in"))
162
  $attr["level_ccaps_eotper"] = ($attr["rr"] === "BN" && $attr["rt"] !== "L") ? $attr["level"] . ":" . $attr["ccaps"] . ":" . $attr["rp"] . " " . $attr["rt"] : $attr["level"] . ":" . $attr["ccaps"];
163
  $attr["level_ccaps_eotper"] = /* Clean any trailing separators from this string. */ rtrim ($attr["level_ccaps_eotper"], ":");
164
 
165
- $success_return_url = /* s2Member handles this all by itself. However, it can be Filtered. */ site_url ("/?s2member_paypal_return=1");
166
  $success_return_url = apply_filters("ws_plugin__s2member_during_sc_paypal_button_success_return_url", $success_return_url, get_defined_vars ());
167
 
168
  $code = trim (c_ws_plugin__s2member_utilities::evl (file_get_contents (dirname (dirname (__FILE__)) . "/templates/buttons/paypal-ccaps-checkout-button.php")));
169
  $code = preg_replace ("/%%images%%/", c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr ($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["dir_url"] . "/images")), $code);
170
- $code = preg_replace ("/%%wpurl%%/", c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr (site_url ())), $code);
171
 
172
  $code = preg_replace ("/%%endpoint%%/", c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr (($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["paypal_sandbox"]) ? "www.sandbox.paypal.com" : "www.paypal.com")), $code);
173
  $code = preg_replace ("/%%paypal_business%%/", c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["paypal_business"])), $code);
174
  $code = preg_replace ("/%%paypal_merchant_id%%/", c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["paypal_merchant_id"])), $code);
175
  $code = preg_replace ("/%%cancel_return%%/", c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr (home_url ("/"))), $code);
176
- $code = preg_replace ("/%%notify_url%%/", c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr (site_url ("/?s2member_paypal_notify=1"))), $code);
177
  $code = preg_replace ("/%%return%%/", c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr ($success_return_url)), $code);
178
  $code = preg_replace ("/%%custom%%/", c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr ($attr["custom"])), $code);
179
 
@@ -222,20 +222,20 @@ if (!class_exists ("c_ws_plugin__s2member_sc_paypal_button_in"))
222
 
223
  $success_return_tra = array("ta" => $attr["ta"], "tp" => $attr["tp"], "tt" => $attr["tt"], "ra" => $attr["ra"], "rp" => $attr["rp"], "rt" => $attr["rt"], "rr" => $attr["rr"], "rrt" => $attr["rrt"], "rra" => $attr["rra"], "invoice" => $paypal_invoice_input_value, "checksum" => md5 ($paypal_invoice_input_value . $_SERVER["REMOTE_ADDR"] . $attr["level_ccaps_eotper"]));
224
 
225
- $success_return_url = /* s2Member handles this all by itself. However, it can be Filtered (see below). */ site_url ("/?s2member_paypal_return=1");
226
  $success_return_url = add_query_arg ("s2member_paypal_return_tra", urlencode (c_ws_plugin__s2member_utils_encryption::encrypt (serialize ($success_return_tra))), $success_return_url);
227
  $success_return_url = apply_filters("ws_plugin__s2member_during_sc_paypal_button_success_return_url", $success_return_url, get_defined_vars ());
228
 
229
  $code = trim (c_ws_plugin__s2member_utilities::evl (file_get_contents (dirname (dirname (__FILE__)) . "/templates/buttons/paypal-checkout-button.php")));
230
  $code = preg_replace ("/%%images%%/", c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr ($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["dir_url"] . "/images")), $code);
231
- $code = preg_replace ("/%%wpurl%%/", c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr (site_url ())), $code);
232
 
233
  $code = preg_replace ("/%%endpoint%%/", c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr (($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["paypal_sandbox"]) ? "www.sandbox.paypal.com" : "www.paypal.com")), $code);
234
  $code = preg_replace ("/%%paypal_business%%/", c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["paypal_business"])), $code);
235
  $code = preg_replace ("/%%paypal_merchant_id%%/", c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["paypal_merchant_id"])), $code);
236
  $code = preg_replace ("/%%level_label%%/", c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["level" . $attr["level"] . "_label"])), $code);
237
  $code = preg_replace ("/%%cancel_return%%/", c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr (home_url ("/"))), $code); // This brings them back to Front Page.
238
- $code = preg_replace ("/%%notify_url%%/", c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr (site_url ("/?s2member_paypal_notify=1"))), $code);
239
  $code = preg_replace ("/%%return%%/", c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr ($success_return_url)), $code);
240
  $code = preg_replace ("/%%custom%%/", c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr ($attr["custom"])), $code);
241
  $code = preg_replace ("/%%level%%/", c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr ($attr["level"])), $code);
74
 
75
  $code = trim (c_ws_plugin__s2member_utilities::evl (file_get_contents (dirname (dirname (__FILE__)) . "/templates/buttons/paypal-cancellation-button.php")));
76
  $code = preg_replace ("/%%images%%/", c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr ($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["dir_url"] . "/images")), $code);
77
+ $code = preg_replace ("/%%wpurl%%/", c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr (home_url ())), $code);
78
 
79
  $code = preg_replace ("/%%endpoint%%/", c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr (($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["paypal_sandbox"]) ? "www.sandbox.paypal.com" : "www.paypal.com")), $code);
80
  $code = preg_replace ("/%%paypal_business%%/", c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["paypal_business"])), $code);
106
 
107
  $attr["sp_ids_exp"] = /* Combined "sp:ids:expiration hours". */ "sp:" . $attr["ids"] . ":" . $attr["exp"];
108
 
109
+ $success_return_url = /* s2Member handles this all by itself. However, it can be Filtered. */ home_url ("/?s2member_paypal_return=1");
110
  $success_return_url = apply_filters("ws_plugin__s2member_during_sc_paypal_button_success_return_url", $success_return_url, get_defined_vars ());
111
 
112
  $code = trim (c_ws_plugin__s2member_utilities::evl (file_get_contents (dirname (dirname (__FILE__)) . "/templates/buttons/paypal-sp-checkout-button.php")));
113
  $code = preg_replace ("/%%images%%/", c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr ($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["dir_url"] . "/images")), $code);
114
+ $code = preg_replace ("/%%wpurl%%/", c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr (home_url ())), $code);
115
 
116
  $code = preg_replace ("/%%endpoint%%/", c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr (($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["paypal_sandbox"]) ? "www.sandbox.paypal.com" : "www.paypal.com")), $code);
117
  $code = preg_replace ("/%%paypal_business%%/", c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["paypal_business"])), $code);
118
  $code = preg_replace ("/%%paypal_merchant_id%%/", c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["paypal_merchant_id"])), $code);
119
  $code = preg_replace ("/%%cancel_return%%/", c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr (home_url ("/"))), $code);
120
+ $code = preg_replace ("/%%notify_url%%/", c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr (home_url ("/?s2member_paypal_notify=1"))), $code);
121
  $code = preg_replace ("/%%return%%/", c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr ($success_return_url)), $code);
122
  $code = preg_replace ("/%%custom%%/", c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr ($attr["custom"])), $code);
123
 
162
  $attr["level_ccaps_eotper"] = ($attr["rr"] === "BN" && $attr["rt"] !== "L") ? $attr["level"] . ":" . $attr["ccaps"] . ":" . $attr["rp"] . " " . $attr["rt"] : $attr["level"] . ":" . $attr["ccaps"];
163
  $attr["level_ccaps_eotper"] = /* Clean any trailing separators from this string. */ rtrim ($attr["level_ccaps_eotper"], ":");
164
 
165
+ $success_return_url = /* s2Member handles this all by itself. However, it can be Filtered. */ home_url ("/?s2member_paypal_return=1");
166
  $success_return_url = apply_filters("ws_plugin__s2member_during_sc_paypal_button_success_return_url", $success_return_url, get_defined_vars ());
167
 
168
  $code = trim (c_ws_plugin__s2member_utilities::evl (file_get_contents (dirname (dirname (__FILE__)) . "/templates/buttons/paypal-ccaps-checkout-button.php")));
169
  $code = preg_replace ("/%%images%%/", c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr ($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["dir_url"] . "/images")), $code);
170
+ $code = preg_replace ("/%%wpurl%%/", c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr (home_url ())), $code);
171
 
172
  $code = preg_replace ("/%%endpoint%%/", c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr (($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["paypal_sandbox"]) ? "www.sandbox.paypal.com" : "www.paypal.com")), $code);
173
  $code = preg_replace ("/%%paypal_business%%/", c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["paypal_business"])), $code);
174
  $code = preg_replace ("/%%paypal_merchant_id%%/", c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["paypal_merchant_id"])), $code);
175
  $code = preg_replace ("/%%cancel_return%%/", c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr (home_url ("/"))), $code);
176
+ $code = preg_replace ("/%%notify_url%%/", c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr (home_url ("/?s2member_paypal_notify=1"))), $code);
177
  $code = preg_replace ("/%%return%%/", c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr ($success_return_url)), $code);
178
  $code = preg_replace ("/%%custom%%/", c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr ($attr["custom"])), $code);
179
 
222
 
223
  $success_return_tra = array("ta" => $attr["ta"], "tp" => $attr["tp"], "tt" => $attr["tt"], "ra" => $attr["ra"], "rp" => $attr["rp"], "rt" => $attr["rt"], "rr" => $attr["rr"], "rrt" => $attr["rrt"], "rra" => $attr["rra"], "invoice" => $paypal_invoice_input_value, "checksum" => md5 ($paypal_invoice_input_value . $_SERVER["REMOTE_ADDR"] . $attr["level_ccaps_eotper"]));
224
 
225
+ $success_return_url = /* s2Member handles this all by itself. However, it can be Filtered (see below). */ home_url ("/?s2member_paypal_return=1");
226
  $success_return_url = add_query_arg ("s2member_paypal_return_tra", urlencode (c_ws_plugin__s2member_utils_encryption::encrypt (serialize ($success_return_tra))), $success_return_url);
227
  $success_return_url = apply_filters("ws_plugin__s2member_during_sc_paypal_button_success_return_url", $success_return_url, get_defined_vars ());
228
 
229
  $code = trim (c_ws_plugin__s2member_utilities::evl (file_get_contents (dirname (dirname (__FILE__)) . "/templates/buttons/paypal-checkout-button.php")));
230
  $code = preg_replace ("/%%images%%/", c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr ($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["dir_url"] . "/images")), $code);
231
+ $code = preg_replace ("/%%wpurl%%/", c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr (home_url ())), $code);
232
 
233
  $code = preg_replace ("/%%endpoint%%/", c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr (($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["paypal_sandbox"]) ? "www.sandbox.paypal.com" : "www.paypal.com")), $code);
234
  $code = preg_replace ("/%%paypal_business%%/", c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["paypal_business"])), $code);
235
  $code = preg_replace ("/%%paypal_merchant_id%%/", c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["paypal_merchant_id"])), $code);
236
  $code = preg_replace ("/%%level_label%%/", c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["level" . $attr["level"] . "_label"])), $code);
237
  $code = preg_replace ("/%%cancel_return%%/", c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr (home_url ("/"))), $code); // This brings them back to Front Page.
238
+ $code = preg_replace ("/%%notify_url%%/", c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr (home_url ("/?s2member_paypal_notify=1"))), $code);
239
  $code = preg_replace ("/%%return%%/", c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr ($success_return_url)), $code);
240
  $code = preg_replace ("/%%custom%%/", c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr ($attr["custom"])), $code);
241
  $code = preg_replace ("/%%level%%/", c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr ($attr["level"])), $code);
includes/classes/security.inc.php CHANGED
@@ -1,86 +1,83 @@
1
  <?php
2
  /**
3
- * s2Member's Security Gate.
4
- *
5
- * Copyright: © 2009-2011
6
- * {@link http://www.websharks-inc.com/ WebSharks, Inc.}
7
- * (coded in the USA)
8
- *
9
- * Released under the terms of the GNU General Public License.
10
- * You should have received a copy of the GNU General Public License,
11
- * along with this software. In the main directory, see: /licensing/
12
- * If not, see: {@link http://www.gnu.org/licenses/}.
13
- *
14
- * @package s2Member\Security
15
- * @since 3.5
16
- */
17
- if (realpath (__FILE__) === realpath ($_SERVER["SCRIPT_FILENAME"]))
18
- exit("Do not access this file directly.");
19
 
20
- if (!class_exists ("c_ws_plugin__s2member_security"))
 
 
 
 
 
 
 
 
21
  {
22
  /**
23
- * s2Member's Security Gate.
24
- *
25
- * @package s2Member\Security
26
- * @since 3.5
27
- */
28
- class c_ws_plugin__s2member_security
29
- {
30
- /**
31
- * s2Member's Security Gate (protects WordPress content).
32
- *
33
- * @package s2Member\Security
34
- * @since 3.5
35
- *
36
- * @attaches-to ``add_action("wp");``
37
- *
38
- * @return null May redirect a browser *(exiting script execution)*, when/if content is NOT available to the current User/Member.
39
- */
40
- public static function security_gate () // s2Member's Security Gate.
41
- {
42
- do_action("ws_plugin__s2member_before_security_gate", get_defined_vars ());
43
 
44
- if (is_category ()) // Categories & other inclusives.
45
- c_ws_plugin__s2member_catgs::check_catg_level_access ();
46
 
47
- else if (is_tag ()) // Post/Page Tags & other inclusives.
48
- c_ws_plugin__s2member_ptags::check_ptag_level_access ();
49
 
50
- else if (is_single ()) // All Posts & other inclusives.
51
- c_ws_plugin__s2member_posts::check_post_level_access ();
52
 
53
- else if (is_page ()) // All Pages & other inclusives.
54
- c_ws_plugin__s2member_pages::check_page_level_access ();
55
 
56
- else // Else, we simply look at URIs & other inclusives.
57
- c_ws_plugin__s2member_ruris::check_ruri_level_access ();
58
 
59
- do_action("ws_plugin__s2member_after_security_gate", get_defined_vars ());
 
60
 
61
- return /* Return for uniformity. */;
62
- }
63
- /**
64
- * s2Member's Security Gate (protects WordPress queries).
65
- *
66
- * @package s2Member\Security
67
- * @since 3.5
68
- *
69
- * @attaches-to ``add_action("pre_get_posts");``
70
- *
71
- * @param object $wp_query Global ``$wp_query``, by reference.
72
- * @return null May filter WordPress queries, by hiding protected content which is NOT available to the current User/Member.
73
- */
74
- public static function security_gate_query (&$wp_query = FALSE) // s2Member's Security Gate.
75
- {
76
- do_action("ws_plugin__s2member_before_security_gate_query", get_defined_vars ());
77
-
78
- c_ws_plugin__s2member_querys::query_level_access ($wp_query); // By reference.
79
 
80
- do_action("ws_plugin__s2member_after_security_gate_query", get_defined_vars ());
81
 
82
- return /* Return for uniformity. */;
83
- }
84
- }
85
  }
86
- ?>
1
  <?php
2
  /**
3
+ * s2Member's Security Gate.
4
+ *
5
+ * Copyright: © 2009-2011
6
+ * {@link http://www.websharks-inc.com/ WebSharks, Inc.}
7
+ * (coded in the USA)
8
+ *
9
+ * Released under the terms of the GNU General Public License.
10
+ * You should have received a copy of the GNU General Public License,
11
+ * along with this software. In the main directory, see: /licensing/
12
+ * If not, see: {@link http://www.gnu.org/licenses/}.
13
+ *
14
+ * @package s2Member\Security
15
+ * @since 3.5
16
+ */
17
+ if(realpath(__FILE__) === realpath($_SERVER['SCRIPT_FILENAME']))
18
+ exit('Do not access this file directly.');
19
 
20
+ if(!class_exists('c_ws_plugin__s2member_security'))
21
+ {
22
+ /**
23
+ * s2Member's Security Gate.
24
+ *
25
+ * @package s2Member\Security
26
+ * @since 3.5
27
+ */
28
+ class c_ws_plugin__s2member_security
29
  {
30
  /**
31
+ * s2Member's Security Gate (protects WordPress content).
32
+ *
33
+ * @package s2Member\Security
34
+ * @since 3.5
35
+ *
36
+ * @attaches-to ``add_action('wp');``
37
+ *
38
+ * @return null May redirect a browser *(exiting script execution)*, when/if content is NOT available to the current User/Member.
39
+ */
40
+ public static function security_gate() // s2Member's Security Gate.
41
+ {
42
+ do_action('ws_plugin__s2member_before_security_gate', get_defined_vars());
 
 
 
 
 
 
 
 
43
 
44
+ if(is_category()) // Categories & other inclusives.
45
+ c_ws_plugin__s2member_catgs::check_catg_level_access();
46
 
47
+ else if(is_tag()) // Post/Page Tags & other inclusives.
48
+ c_ws_plugin__s2member_ptags::check_ptag_level_access();
49
 
50
+ else if(is_single()) // All Posts & other inclusives.
51
+ c_ws_plugin__s2member_posts::check_post_level_access();
52
 
53
+ else if(is_page()) // All Pages & other inclusives.
54
+ c_ws_plugin__s2member_pages::check_page_level_access();
55
 
56
+ else // Else, we simply look at URIs & other inclusives.
57
+ c_ws_plugin__s2member_ruris::check_ruri_level_access();
58
 
59
+ do_action('ws_plugin__s2member_after_security_gate', get_defined_vars());
60
+ }
61
 
62
+ /**
63
+ * s2Member's Security Gate (protects WordPress queries).
64
+ *
65
+ * @package s2Member\Security
66
+ * @since 3.5
67
+ *
68
+ * @attaches-to ``add_action('pre_get_posts');``
69
+ *
70
+ * @param WP_Query $wp_query Global ``$wp_query``, by reference.
71
+ *
72
+ * @return null May filter WordPress queries, by hiding protected content which is NOT available to the current User/Member.
73
+ */
74
+ public static function security_gate_query(&$wp_query = NULL) // s2Member's Security Gate.
75
+ {
76
+ do_action('ws_plugin__s2member_before_security_gate_query', get_defined_vars());
 
 
 
77
 
78
+ c_ws_plugin__s2member_querys::query_level_access($wp_query); // By reference.
79
 
80
+ do_action('ws_plugin__s2member_after_security_gate_query', get_defined_vars());
81
+ }
 
82
  }
83
+ }
includes/classes/tracking-codes.inc.php CHANGED
@@ -57,7 +57,7 @@ if(!class_exists("c_ws_plugin__s2member_tracking_codes"))
57
  {
58
  delete_transient($transient); // Only display this ONE time. Delete transient immediately.
59
 
60
- echo '<img src="'.esc_attr(site_url("/?s2member_delete_tracking_cookie=1")).'" alt="." style="width:1px; height:1px; border:0;" />'."\n";
61
 
62
  foreach(array_keys(get_defined_vars()) as $__v) $__refs[$__v] =& $$__v;
63
  do_action("ws_plugin__s2member_during_display_signup_tracking_codes", get_defined_vars());
@@ -102,7 +102,7 @@ if(!class_exists("c_ws_plugin__s2member_tracking_codes"))
102
  {
103
  delete_transient($transient); // Only display this ONE time. Delete transient immediately.
104
 
105
- echo '<img src="'.esc_attr(site_url("/?s2member_delete_tracking_cookie=1")).'" alt="." style="width:1px; height:1px; border:0;" />'."\n";
106
 
107
  foreach(array_keys(get_defined_vars()) as $__v) $__refs[$__v] =& $$__v;
108
  do_action("ws_plugin__s2member_during_display_modification_tracking_codes", get_defined_vars());
@@ -147,7 +147,7 @@ if(!class_exists("c_ws_plugin__s2member_tracking_codes"))
147
  {
148
  delete_transient($transient); // Only display this ONE time. Delete transient immediately.
149
 
150
- echo '<img src="'.esc_attr(site_url("/?s2member_delete_tracking_cookie=1")).'" alt="." style="width:1px; height:1px; border:0;" />'."\n";
151
 
152
  foreach(array_keys(get_defined_vars()) as $__v) $__refs[$__v] =& $$__v;
153
  do_action("ws_plugin__s2member_during_display_ccap_tracking_codes", get_defined_vars());
@@ -190,7 +190,7 @@ if(!class_exists("c_ws_plugin__s2member_tracking_codes"))
190
  {
191
  delete_transient($transient); // Only display this ONE time. Delete transient immediately.
192
 
193
- echo '<img src="'.esc_attr(site_url("/?s2member_delete_sp_tracking_cookie=1")).'" alt="." style="width:1px; height:1px; border:0;" />'."\n";
194
 
195
  foreach(array_keys(get_defined_vars()) as $__v) $__refs[$__v] =& $$__v;
196
  do_action("ws_plugin__s2member_during_display_sp_tracking_codes", get_defined_vars());
57
  {
58
  delete_transient($transient); // Only display this ONE time. Delete transient immediately.
59
 
60
+ echo '<img src="'.esc_attr(home_url("/?s2member_delete_tracking_cookie=1")).'" alt="." style="width:1px; height:1px; border:0;" />'."\n";
61
 
62
  foreach(array_keys(get_defined_vars()) as $__v) $__refs[$__v] =& $$__v;
63
  do_action("ws_plugin__s2member_during_display_signup_tracking_codes", get_defined_vars());
102
  {
103
  delete_transient($transient); // Only display this ONE time. Delete transient immediately.
104
 
105
+ echo '<img src="'.esc_attr(home_url("/?s2member_delete_tracking_cookie=1")).'" alt="." style="width:1px; height:1px; border:0;" />'."\n";
106
 
107
  foreach(array_keys(get_defined_vars()) as $__v) $__refs[$__v] =& $$__v;
108
  do_action("ws_plugin__s2member_during_display_modification_tracking_codes", get_defined_vars());
147
  {
148
  delete_transient($transient); // Only display this ONE time. Delete transient immediately.
149
 
150
+ echo '<img src="'.esc_attr(home_url("/?s2member_delete_tracking_cookie=1")).'" alt="." style="width:1px; height:1px; border:0;" />'."\n";
151
 
152
  foreach(array_keys(get_defined_vars()) as $__v) $__refs[$__v] =& $$__v;
153
  do_action("ws_plugin__s2member_during_display_ccap_tracking_codes", get_defined_vars());
190
  {
191
  delete_transient($transient); // Only display this ONE time. Delete transient immediately.
192
 
193
+ echo '<img src="'.esc_attr(home_url("/?s2member_delete_sp_tracking_cookie=1")).'" alt="." style="width:1px; height:1px; border:0;" />'."\n";
194
 
195
  foreach(array_keys(get_defined_vars()) as $__v) $__refs[$__v] =& $$__v;
196
  do_action("ws_plugin__s2member_during_display_sp_tracking_codes", get_defined_vars());
includes/classes/utilities.inc.php CHANGED
@@ -147,7 +147,7 @@ if (!class_exists ("c_ws_plugin__s2member_utilities"))
147
  if ($v && file_exists (($template = dirname (dirname (__FILE__)) . "/templates/badges/s-badge.php")))
148
  {
149
  $badge = trim (c_ws_plugin__s2member_utilities::evl (file_get_contents ($template)));
150
- $badge = preg_replace ("/%%site_url%%/i", urlencode (site_url ()), preg_replace ("/%%v%%/i", (string)$v, $badge));
151
  $badge = preg_replace ("/%%no_cache%%/i", (($no_cache) ? "&amp;no_cache=" . urlencode (mt_rand (0, PHP_INT_MAX)) : ""), $badge);
152
  $badge = preg_replace ("/%%display_on_failure%%/i", (($display_on_failure) ? "&amp;display_on_failure=1" : ""), $badge);
153
  }
147
  if ($v && file_exists (($template = dirname (dirname (__FILE__)) . "/templates/badges/s-badge.php")))
148
  {
149
  $badge = trim (c_ws_plugin__s2member_utilities::evl (file_get_contents ($template)));
150
+ $badge = preg_replace ("/%%site_url%%/i", urlencode (home_url ()), preg_replace ("/%%v%%/i", (string)$v, $badge));
151
  $badge = preg_replace ("/%%no_cache%%/i", (($no_cache) ? "&amp;no_cache=" . urlencode (mt_rand (0, PHP_INT_MAX)) : ""), $badge);
152
  $badge = preg_replace ("/%%display_on_failure%%/i", (($display_on_failure) ? "&amp;display_on_failure=1" : ""), $badge);
153
  }
includes/classes/utils-conds.inc.php CHANGED
@@ -148,6 +148,11 @@ if(!class_exists("c_ws_plugin__s2member_utils_conds"))
148
  {
149
  $parse["path"] = (!empty($parse["path"])) ? ((strpos($parse["path"], "/") === 0) ? $parse["path"] : "/".$parse["path"]) : "/";
150
 
 
 
 
 
 
151
  if(empty($parse["host"]) || strcasecmp($parse["host"], c_ws_plugin__s2member_utils_urls::parse_url(site_url(), PHP_URL_HOST)) === 0)
152
  if($parse["path"] === "/" || rtrim($parse["path"], "/") === rtrim(c_ws_plugin__s2member_utils_urls::parse_url(site_url(), PHP_URL_PATH), "/"))
153
  if(get_option("permalink_structure") || (empty($_GET["post_id"]) && empty($_GET["page_id"]) && empty($_GET["p"])))
148
  {
149
  $parse["path"] = (!empty($parse["path"])) ? ((strpos($parse["path"], "/") === 0) ? $parse["path"] : "/".$parse["path"]) : "/";
150
 
151
+ if(empty($parse["host"]) || strcasecmp($parse["host"], c_ws_plugin__s2member_utils_urls::parse_url(home_url(), PHP_URL_HOST)) === 0)
152
+ if($parse["path"] === "/" || rtrim($parse["path"], "/") === rtrim(c_ws_plugin__s2member_utils_urls::parse_url(home_url(), PHP_URL_PATH), "/"))
153
+ if(get_option("permalink_structure") || (empty($_GET["post_id"]) && empty($_GET["page_id"]) && empty($_GET["p"])))
154
+ return true;
155
+
156
  if(empty($parse["host"]) || strcasecmp($parse["host"], c_ws_plugin__s2member_utils_urls::parse_url(site_url(), PHP_URL_HOST)) === 0)
157
  if($parse["path"] === "/" || rtrim($parse["path"], "/") === rtrim(c_ws_plugin__s2member_utils_urls::parse_url(site_url(), PHP_URL_PATH), "/"))
158
  if(get_option("permalink_structure") || (empty($_GET["post_id"]) && empty($_GET["page_id"]) && empty($_GET["p"])))
includes/classes/utils-gets.inc.php CHANGED
@@ -33,13 +33,18 @@ if(!class_exists('c_ws_plugin__s2member_utils_gets'))
33
  * @package s2Member\Utilities
34
  * @since 3.5
35
  *
36
- * @uses {@link http://codex.wordpress.org/Function_Reference/get_all_category_ids get_all_category_ids()}
37
  *
38
  * @return array Unique array of all Category IDs *(as integers)*.
39
  */
40
  public static function get_all_category_ids()
41
  {
42
- if(is_array($category_ids = get_all_category_ids())) // Use a WP function for this.
 
 
 
 
 
43
  $category_ids = c_ws_plugin__s2member_utils_arrays::force_integers((array)$category_ids);
44
 
45
  return (!empty($category_ids) && is_array($category_ids)) ? array_unique($category_ids) : array();
33
  * @package s2Member\Utilities
34
  * @since 3.5
35
  *
36
+ * @uses {@link http://codex.wordpress.org/Function_Reference/get_terms get_terms()}
37
  *
38
  * @return array Unique array of all Category IDs *(as integers)*.
39
  */
40
  public static function get_all_category_ids()
41
  {
42
+ if(!($category_ids = wp_cache_get('all_category_ids', 'category')))
43
+ {
44
+ $category_ids = get_terms('category', array('fields' => 'ids', 'get' => 'all'));
45
+ wp_cache_add('all_category_ids', $category_ids, 'category');
46
+ }
47
+ if(is_array($category_ids)) // Use a WP function for this.
48
  $category_ids = c_ws_plugin__s2member_utils_arrays::force_integers((array)$category_ids);
49
 
50
  return (!empty($category_ids) && is_array($category_ids)) ? array_unique($category_ids) : array();
includes/classes/utils-s2o.inc.php CHANGED
@@ -60,7 +60,7 @@ if (!class_exists ("c_ws_plugin__s2member_utils_s2o"))
60
  * @param string $o_file Location of calling `*-o.php` file.
61
  * @return str|bool WordPress settings, else false on failure.
62
  */
63
- public static function wp_settings_as ($wp_dir = FALSE, $o_file = FALSE)
64
  {
65
  if ($wp_dir && is_dir ($wp_dir) && is_readable (($wp_settings = $wp_dir . "/wp-settings.php")) && $o_file && file_exists ($o_file) && ($_wp_settings = trim (file_get_contents ($wp_settings))))
66
  {
60
  * @param string $o_file Location of calling `*-o.php` file.
61
  * @return str|bool WordPress settings, else false on failure.
62
  */
63
+ public static function wp_settings_as ($wp_dir = '', $o_file = '')
64
  {
65
  if ($wp_dir && is_dir ($wp_dir) && is_readable (($wp_settings = $wp_dir . "/wp-settings.php")) && $o_file && file_exists ($o_file) && ($_wp_settings = trim (file_get_contents ($wp_settings))))
66
  {
includes/classes/utils-urls.inc.php CHANGED
@@ -62,7 +62,7 @@ if(!class_exists("c_ws_plugin__s2member_utils_urls"))
62
  public static function bp_register_url()
63
  {
64
  if( /* If BuddyPress is installed. */c_ws_plugin__s2member_utils_conds::bp_is_installed())
65
- return site_url(((function_exists("bp_get_signup_slug")) ? bp_get_signup_slug()."/" : BP_REGISTER_SLUG."/"));
66
 
67
  return /* Default return false. */ false;
68
  }
62
  public static function bp_register_url()
63
  {
64
  if( /* If BuddyPress is installed. */c_ws_plugin__s2member_utils_conds::bp_is_installed())
65
+ return home_url(((function_exists("bp_get_signup_slug")) ? bp_get_signup_slug()."/" : BP_REGISTER_SLUG."/"));
66
 
67
  return /* Default return false. */ false;
68
  }
includes/classes/utils-users.inc.php CHANGED
@@ -14,10 +14,10 @@
14
  * @package s2Member\Utilities
15
  * @since 3.5
16
  */
17
- if(realpath(__FILE__) === realpath($_SERVER["SCRIPT_FILENAME"]))
18
- exit ("Do not access this file directly.");
19
 
20
- if(!class_exists("c_ws_plugin__s2member_utils_users"))
21
  {
22
  /**
23
  * User utilities.
@@ -61,19 +61,20 @@ if(!class_exists("c_ws_plugin__s2member_utils_users"))
61
  */
62
  public static function get_user_custom_with($subscr_txn_baid_cid_id = '', $os0 = '')
63
  {
64
- global $wpdb; /** @var wpdb $wpdb */
 
65
 
66
  if($subscr_txn_baid_cid_id && $os0) // This case includes some additional routines that can use the ``$os0`` value.
67
  {
68
  if(($q = $wpdb->get_row("SELECT `user_id` FROM `".$wpdb->usermeta."` WHERE (`meta_key` = '".$wpdb->prefix."s2member_subscr_id' OR `meta_key` = '".$wpdb->prefix."s2member_subscr_baid' OR `meta_key` = '".$wpdb->prefix."s2member_subscr_cid' OR `meta_key` = '".$wpdb->prefix."s2member_first_payment_txn_id') AND (`meta_value` = '".esc_sql($subscr_txn_baid_cid_id)."' OR `meta_value` = '".esc_sql($os0)."') LIMIT 1"))
69
  || ($q = $wpdb->get_row("SELECT `ID` AS `user_id` FROM `".$wpdb->users."` WHERE `ID` = '".esc_sql($os0)."' LIMIT 1"))
70
- ) if(($custom = get_user_option("s2member_custom", $q->user_id)))
71
  return $custom;
72
  }
73
  else if($subscr_txn_baid_cid_id) // Otherwise, if all we have is a Subscr./Txn. ID value.
74
  {
75
  if(($q = $wpdb->get_row("SELECT `user_id` FROM `".$wpdb->usermeta."` WHERE (`meta_key` = '".$wpdb->prefix."s2member_subscr_id' OR `meta_key` = '".$wpdb->prefix."s2member_subscr_baid' OR `meta_key` = '".$wpdb->prefix."s2member_subscr_cid' OR `meta_key` = '".$wpdb->prefix."s2member_first_payment_txn_id') AND `meta_value` = '".esc_sql($subscr_txn_baid_cid_id)."' LIMIT 1")))
76
- if(($custom = get_user_option("s2member_custom", $q->user_id)))
77
  return $custom;
78
  }
79
  return FALSE; // Otherwise, return false.
@@ -165,13 +166,13 @@ if(!class_exists("c_ws_plugin__s2member_utils_users"))
165
  || (!$user_id && !$subscr_txn_baid_cid_id && is_object($user = wp_get_current_user()) && !empty($user->ID) && ($user_id = $user->ID))
166
  )
167
  {
168
- $_subscr_baid = get_user_option("s2member_subscr_baid", $user_id);
169
- $_subscr_cid = get_user_option("s2member_subscr_cid", $user_id);
170
- $_subscr_id = get_user_option("s2member_subscr_id", $user_id);
171
 
172
  if($_subscr_id && (!$subscr_txn_baid_cid_id || $subscr_txn_baid_cid_id === $_subscr_id || $subscr_txn_baid_cid_id === $_subscr_baid || $subscr_txn_baid_cid_id === $_subscr_cid))
173
- if(is_array($ipn_signup_vars = get_user_option("s2member_ipn_signup_vars", $user_id)))
174
- if($ipn_signup_vars["subscr_id"] === $_subscr_id)
175
  return $ipn_signup_vars;
176
  }
177
  return FALSE; // Otherwise, return false.
@@ -223,7 +224,7 @@ if(!class_exists("c_ws_plugin__s2member_utils_users"))
223
  || (!func_num_args() && (!is_object($user = (is_user_logged_in()) ? wp_get_current_user() : FALSE) || empty($user->ID)))
224
  ) return FALSE; // The ``$user`` was passed in but is NOT an object; or nobody is logged in.
225
 
226
- return ($subscr_id = get_user_option("s2member_subscr_id", $user->ID)) ? $subscr_id : $user->ID;
227
  }
228
 
229
  /**
@@ -334,39 +335,42 @@ if(!class_exists("c_ws_plugin__s2member_utils_users"))
334
  else if(isset ($user->data->{$wpdb->prefix.$field_id}))
335
  return $user->data->{$wpdb->prefix.$field_id};
336
 
337
- else if(strcasecmp($field_id, "full_name") === 0)
338
- return trim($user->first_name." ".$user->last_name);
339
 
340
- else if(preg_match("/^(email|user_email)$/i", $field_id))
341
  return $user->user_email;
342
 
343
- else if(preg_match("/^(login|user_login)$/i", $field_id))
344
  return $user->user_login;
345
 
346
- else if(strcasecmp($field_id, "s2member_access_role") === 0)
 
 
 
347
  return c_ws_plugin__s2member_user_access::user_access_role($user);
348
 
349
- else if(strcasecmp($field_id, "s2member_access_level") === 0)
350
  return c_ws_plugin__s2member_user_access::user_access_level($user);
351
 
352
- else if(strcasecmp($field_id, "s2member_access_label") === 0)
353
  return c_ws_plugin__s2member_user_access::user_access_label($user);
354
 
355
- else if(strcasecmp($field_id, "s2member_access_ccaps") === 0)
356
  return c_ws_plugin__s2member_user_access::user_access_ccaps($user);
357
 
358
- else if(strcasecmp($field_id, "ip") === 0 && is_object($current_user) && !empty($current_user->ID) && $current_user->ID === ($user_id = $user->ID))
359
- return $_SERVER["REMOTE_ADDR"];
360
 
361
- else if(strcasecmp($field_id, "s2member_registration_ip") === 0 || strcasecmp($field_id, "reg_ip") === 0 || strcasecmp($field_id, "ip") === 0)
362
- return get_user_option("s2member_registration_ip", $user_id);
363
 
364
- else if(strcasecmp($field_id, "s2member_subscr_or_wp_id") === 0)
365
- return ($subscr_id = get_user_option("s2member_subscr_id", $user_id)) ? $subscr_id : $user_id;
366
 
367
- else if(is_array($fields = get_user_option("s2member_custom_fields", $user_id)))
368
- if(isset ($fields[preg_replace("/[^a-z0-9]/i", "_", strtolower($field_id))]))
369
- return $fields[preg_replace("/[^a-z0-9]/i", "_", strtolower($field_id))];
370
  }
371
  return FALSE; // Otherwise, return false.
372
  }
14
  * @package s2Member\Utilities
15
  * @since 3.5
16
  */
17
+ if(realpath(__FILE__) === realpath($_SERVER['SCRIPT_FILENAME']))
18
+ exit ('Do not access this file directly.');
19
 
20
+ if(!class_exists('c_ws_plugin__s2member_utils_users'))
21
  {
22
  /**
23
  * User utilities.
61
  */
62
  public static function get_user_custom_with($subscr_txn_baid_cid_id = '', $os0 = '')
63
  {
64
+ global $wpdb;
65
+ /** @var wpdb $wpdb */
66
 
67
  if($subscr_txn_baid_cid_id && $os0) // This case includes some additional routines that can use the ``$os0`` value.
68
  {
69
  if(($q = $wpdb->get_row("SELECT `user_id` FROM `".$wpdb->usermeta."` WHERE (`meta_key` = '".$wpdb->prefix."s2member_subscr_id' OR `meta_key` = '".$wpdb->prefix."s2member_subscr_baid' OR `meta_key` = '".$wpdb->prefix."s2member_subscr_cid' OR `meta_key` = '".$wpdb->prefix."s2member_first_payment_txn_id') AND (`meta_value` = '".esc_sql($subscr_txn_baid_cid_id)."' OR `meta_value` = '".esc_sql($os0)."') LIMIT 1"))
70
  || ($q = $wpdb->get_row("SELECT `ID` AS `user_id` FROM `".$wpdb->users."` WHERE `ID` = '".esc_sql($os0)."' LIMIT 1"))
71
+ ) if(($custom = get_user_option('s2member_custom', $q->user_id)))
72
  return $custom;
73
  }
74
  else if($subscr_txn_baid_cid_id) // Otherwise, if all we have is a Subscr./Txn. ID value.
75
  {
76
  if(($q = $wpdb->get_row("SELECT `user_id` FROM `".$wpdb->usermeta."` WHERE (`meta_key` = '".$wpdb->prefix."s2member_subscr_id' OR `meta_key` = '".$wpdb->prefix."s2member_subscr_baid' OR `meta_key` = '".$wpdb->prefix."s2member_subscr_cid' OR `meta_key` = '".$wpdb->prefix."s2member_first_payment_txn_id') AND `meta_value` = '".esc_sql($subscr_txn_baid_cid_id)."' LIMIT 1")))
77
+ if(($custom = get_user_option('s2member_custom', $q->user_id)))
78
  return $custom;
79
  }
80
  return FALSE; // Otherwise, return false.
166
  || (!$user_id && !$subscr_txn_baid_cid_id && is_object($user = wp_get_current_user()) && !empty($user->ID) && ($user_id = $user->ID))
167
  )
168
  {
169
+ $_subscr_baid = get_user_option('s2member_subscr_baid', $user_id);
170
+ $_subscr_cid = get_user_option('s2member_subscr_cid', $user_id);
171
+ $_subscr_id = get_user_option('s2member_subscr_id', $user_id);
172
 
173
  if($_subscr_id && (!$subscr_txn_baid_cid_id || $subscr_txn_baid_cid_id === $_subscr_id || $subscr_txn_baid_cid_id === $_subscr_baid || $subscr_txn_baid_cid_id === $_subscr_cid))
174
+ if(is_array($ipn_signup_vars = get_user_option('s2member_ipn_signup_vars', $user_id)))
175
+ if($ipn_signup_vars['subscr_id'] === $_subscr_id)
176
  return $ipn_signup_vars;
177
  }
178
  return FALSE; // Otherwise, return false.
224
  || (!func_num_args() && (!is_object($user = (is_user_logged_in()) ? wp_get_current_user() : FALSE) || empty($user->ID)))
225
  ) return FALSE; // The ``$user`` was passed in but is NOT an object; or nobody is logged in.
226
 
227
+ return ($subscr_id = get_user_option('s2member_subscr_id', $user->ID)) ? $subscr_id : $user->ID;
228
  }
229
 
230
  /**
335
  else if(isset ($user->data->{$wpdb->prefix.$field_id}))
336
  return $user->data->{$wpdb->prefix.$field_id};
337
 
338
+ else if(strcasecmp($field_id, 'full_name') === 0)
339
+ return trim($user->first_name.' '.$user->last_name);
340
 
341
+ else if(preg_match('/^(email|user_email)$/i', $field_id))
342
  return $user->user_email;
343
 
344
+ else if(preg_match('/^(login|user_login)$/i', $field_id))
345
  return $user->user_login;
346
 
347
+ else if(preg_match('/^(s2member_)?registration_time$/i', $field_id))
348
+ return $user->user_registered;
349
+
350
+ else if(strcasecmp($field_id, 's2member_access_role') === 0)
351
  return c_ws_plugin__s2member_user_access::user_access_role($user);
352
 
353
+ else if(strcasecmp($field_id, 's2member_access_level') === 0)
354
  return c_ws_plugin__s2member_user_access::user_access_level($user);
355
 
356
+ else if(strcasecmp($field_id, 's2member_access_label') === 0)
357
  return c_ws_plugin__s2member_user_access::user_access_label($user);
358
 
359
+ else if(strcasecmp($field_id, 's2member_access_ccaps') === 0)
360
  return c_ws_plugin__s2member_user_access::user_access_ccaps($user);
361
 
362
+ else if(strcasecmp($field_id, 'ip') === 0 && is_object($current_user) && !empty($current_user->ID) && $current_user->ID === ($user_id = $user->ID))
363
+ return $_SERVER['REMOTE_ADDR'];
364
 
365
+ else if(strcasecmp($field_id, 's2member_registration_ip') === 0 || strcasecmp($field_id, 'reg_ip') === 0 || strcasecmp($field_id, 'ip') === 0)
366
+ return get_user_option('s2member_registration_ip', $user_id);
367
 
368
+ else if(strcasecmp($field_id, 's2member_subscr_or_wp_id') === 0)
369
+ return ($subscr_id = get_user_option('s2member_subscr_id', $user_id)) ? $subscr_id : $user_id;
370
 
371
+ else if(is_array($fields = get_user_option('s2member_custom_fields', $user_id)))
372
+ if(isset ($fields[preg_replace('/[^a-z0-9]/i', '_', strtolower($field_id))]))
373
+ return $fields[preg_replace('/[^a-z0-9]/i', '_', strtolower($field_id))];
374
  }
375
  return FALSE; // Otherwise, return false.
376
  }
includes/hooks.inc.php CHANGED
@@ -55,6 +55,7 @@ add_action('init', 'c_ws_plugin__s2member_login_checks::monitor_simultaneous_log
55
  add_action('admin_init', 'c_ws_plugin__s2member_menu_pages::log_file_downloader');
56
  add_action('admin_init', 'c_ws_plugin__s2member_menu_pages::logs_zip_downloader');
57
 
 
58
  add_action('pre_get_posts', 'c_ws_plugin__s2member_security::security_gate_query', 100);
59
 
60
  add_action('wp', 'c_ws_plugin__s2member_ssl::check_force_ssl', 1);
55
  add_action('admin_init', 'c_ws_plugin__s2member_menu_pages::log_file_downloader');
56
  add_action('admin_init', 'c_ws_plugin__s2member_menu_pages::logs_zip_downloader');
57
 
58
+ add_filter('bbp_has_replies_query', 'c_ws_plugin__s2member_querys::_bbp_flag_has_replies');
59
  add_action('pre_get_posts', 'c_ws_plugin__s2member_security::security_gate_query', 100);
60
 
61
  add_action('wp', 'c_ws_plugin__s2member_ssl::check_force_ssl', 1);
includes/menu-pages/down-ops.inc.php CHANGED
@@ -64,7 +64,7 @@ if(!class_exists("c_ws_plugin__s2member_menu_page_down_ops"))
64
  echo '<div class="ws-menu-page-hr"></div>'."\n";
65
 
66
  echo '<p><strong>Upload restricted files to this security-enabled directory:</strong><br /><code>'.esc_html(c_ws_plugin__s2member_utils_dirs::doc_root_path($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["files_dir"])).'</code></p>'."\n";
67
- echo '<p>- Now, you can link to any protected file, using this special format:<br />&nbsp;&nbsp;<code>'.esc_html(site_url("/?s2member_file_download=example-file.zip")).'</code><br />&nbsp;&nbsp;<small><em><strong>s2member_file_download</strong> = file, relative to the /'.esc_html(c_ws_plugin__s2member_utils_dirs::basename_dir_app_data($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["files_dir"])).'/ directory. In other words, just the file name.</em></small></p>'."\n";
68
  echo '<p>- Or, use: <code>[s2File download="example-file.zip" /]</code> <em>(easier Shortcode if you prefer)</em><br />&nbsp;&nbsp;<small><em><strong>Shortcode equivalent:</strong> <code>[s2File /]</code> produces the entire URL for you, easier.</em></small></p>'."\n";
69
 
70
  echo '<div class="ws-menu-page-hr"></div>'."\n";
@@ -164,11 +164,11 @@ if(!class_exists("c_ws_plugin__s2member_menu_page_down_ops"))
164
 
165
  echo '<div class="ws-menu-page-hr"></div>'."\n";
166
 
167
- echo '<p>'.esc_html(site_url("/?s2member_file_download=example-file.zip")).'<code>&amp;s2member_file_download_key=&lt;?php echo s2member_file_download_key("example-file.zip"); ?&gt;</code><br />&nbsp;&nbsp;<small><em><strong>s2member_file_download_key</strong> = &lt;?php echo s2member_file_download_key("file, relative to the /'.esc_html(c_ws_plugin__s2member_utils_dirs::basename_dir_app_data($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["files_dir"])).'/ directory"); ?&gt;</em></small></p>'."\n";
168
 
169
  echo '<div class="ws-menu-page-hr"></div>'."\n";
170
 
171
- echo '<p>'.esc_html(site_url("/?s2member_file_download=example-file.zip")).'<code>&amp;s2member_file_download_key=[s2Key file_download="example-file.zip" /]</code><br />&nbsp;&nbsp;<small><em><strong>Shortcode equivalent:</strong> <code>[s2Key file_download="example-file.zip" /]</code></em></small></p>'."\n";
172
 
173
  echo '<div class="ws-menu-page-hr"></div>'."\n";
174
 
@@ -261,7 +261,7 @@ if(!class_exists("c_ws_plugin__s2member_menu_page_down_ops"))
261
  echo '<div class="ws-menu-page-hr"></div>'."\n";
262
 
263
  echo '<p><em><strong>Dev Note w/Technical Details:</strong> s2Member uses "Digitally Signed URLs", authenticated by the Amazon S3 API. Documented for developers <a href="http://docs.amazonwebservices.com/AmazonS3/latest/dev/index.html?RESTAuthentication.html" target="_blank" rel="external">here</a>. To put it simply, s2Member will generate Amazon S3 URLs (internally); which allow Customers temporary access to specific files inside your S3 Bucket. s2Member\'s Digitally Signed URLs leading to Amazon S3, give a Customer 24 hours to connect to the file inside your S3 Bucket. This connection period of 24 hours is largely irrelevant when used in combination with s2Member, because access is renewed for another 24 hours each time you make a file available to a User/Member, and they are authenticated by your configuration of s2Member. This connection period of 24 hours is just a secondary line of defense to further prevent the possibility of link sharing. If you need to change this connection timeout of <code>24 hours</code> for some reason (not likely), you can use this WordPress Filter: <code>ws_plugin__s2member_amazon_s3_file_expires_time</code>.</em></p>'."\n";
264
- echo '<p><em><strong>Linking To Protected Files:</strong> Nothing changes. s2Member\'s integration with Amazon S3 serves protected files through the same links that all s2Member site owners use. For example, you might use: <code>'.esc_html(site_url("/?s2member_file_download=example-file.zip")).'</code>, where <strong>s2member_file_download</strong> = the file, relative to the root of your Amazon S3 Bucket. In other words, just the file name in most cases. s2Member will redirect Users/Members to a digitally signed Amazon S3 URL, which allows them access to a particular file via Amazon S3. For further details, please review this section of your Dashboard: <code>s2Member -› Download Options -› Basic Download Restrictions</code>. Also see: <code>s2Member -› Download Options -› Advanced Mod-Rewrite Linkage</code>.</em></p>'."\n";
265
  echo '<p><em><strong>Content Type, Disposition &amp; Inline Files:</strong> The query string parameter <code>&amp;s2member_file_inline=yes</code> DOES work for files served directly through Amazon S3. s2Member DOES have control over the <code>Content-Type</code> and <code>Content-Disposition</code> headers for files being served through Amazon S3. However, Amazon CloudFront servers do NOT automatically determine the MIME type for the objects they serve. If you integrate both Amazon S3 and CloudFront, s2Member will NOT have control over headers. Therefore, when you upload a file to your Amazon S3 Bucket, you should set its Content-Type header. Again, with the Amazon S3/CloudFront combination, you MUST configure headers yourself (such as <code>Content-Type: video/webm</code>, or <code>Content-Disposition: inline|attachment</code>) that you want Amazon CloudFront to send for a particular file. It\'s quite easy. You do this by setting <code>Properties -› Metadata (i.e. headers)</code> on a per-file basis, from inside your Amazon S3 Management Console. In short, when you upload a file to your Amazon S3 Bucket, if you want that file to be served a certain way, be sure to configure its <code>Properties -› Metadata</code> accordingly.</em></p>'."\n";
266
 
267
  echo '<div class="ws-menu-page-hr"></div>'."\n";
@@ -349,7 +349,7 @@ if(!class_exists("c_ws_plugin__s2member_menu_page_down_ops"))
349
 
350
  echo '<p><em><strong>Dev Note w/Technical Details:</strong> s2Member\'s auto-configuration routines for Amazon CloudFront (below), are designed to create &amp; configure various components on your Amazon Web Services account, which are all requirements for you to <a href="http://docs.amazonwebservices.com/AmazonCloudFront/2010-11-01/DeveloperGuide/index.html?HowToPrivateContent.html" target="_blank" rel="external">serve protected files through the Amazon S3/CloudFront combination</a>. These components include: an Origin Access Identity, read permissions for the Origin Access Identity, and two private content Distributions. One private content Distribution for file downloads, and another private content Distribution for streaming media files; both connected to and sourced by your Amazon S3 Bucket. In addition, s2Member will automatically configure an ACL &amp; Policy (i.e. permissions) on your Amazon S3 Bucket to make sure your protected object/files are NOT available to the public.</em></p>'."\n";
351
  echo '<p><em><strong>Dev Note w/Technical Details:</strong> s2Member uses "Digitally Signed URLs", authenticated by the Amazon CloudFront API. Documented for developers <a href="http://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/PrivateContent.html" target="_blank" rel="external">here</a>. To put it simply, s2Member will generate Amazon CloudFront URLs (internally); which allow Customers temporary access to specific files inside your S3 Bucket — via CloudFront Distributions. s2Member\'s Digitally Signed URLs leading to Amazon S3/CloudFront, give a Customer 24 hours to connect to the file inside your S3 Bucket. This connection period of 24 hours is largely irrelevant when used in combination with s2Member, because access is renewed for another 24 hours each time you make a file available to a User/Member, and they are authenticated by your configuration of s2Member. This connection period of 24 hours is just a secondary line of defense to further prevent the possibility of link sharing. If you need to change this connection timeout of <code>24 hours</code> for some reason (not likely), you can use this WordPress Filter: <code>ws_plugin__s2member_amazon_cf_file_expires_time</code>.</em></p>'."\n";
352
- echo '<p><em><strong>Linking To Protected Files:</strong> RTMP streams are special, but nothing else changes. s2Member\'s integration with Amazon S3/CloudFront serves protected files through the same links that all s2Member site owners use. For example, you might use: <code>'.esc_html(site_url("/?s2member_file_download=example-file.zip")).'</code>, where <strong>s2member_file_download</strong> = the file, relative to the root of your Amazon S3 Bucket. In other words, just the file name in most cases. s2Member will redirect Users/Members to a digitally signed Amazon CloudFront URL, which allows them access to a particular file via Amazon CloudFront. For further details, please review this section of your Dashboard: <code>s2Member -› Download Options -› Basic Download Restrictions</code>. Also see: <code>s2Member -› Download Options -› Advanced Mod-Rewrite Linkage</code>. If you\'re streaming audio/video files over the RTMP protocol, please review the section below: <code>JW Player &amp; RTMP Protocol Examples</code>.</em></p>'."\n";
353
  echo '<p><em><strong>Content Type, Disposition &amp; Inline Files:</strong> An IMPORTANT issue. The query string parameter <code>&amp;s2member_file_inline=yes</code> does NOTHING for files served via Amazon CloudFront. s2Member has NO control over the <code>Content-Type</code> and/or <code>Content-Disposition</code> headers for a file being served through Amazon CloudFront, and CloudFront servers do NOT automatically determine the MIME type for the objects they serve. Therefore, when you upload a file to your Amazon S3 Bucket, you should set its Content-Type header. That is, you MUST configure headers yourself (such as <code>Content-Type: video/webm</code>, or <code>Content-Disposition: inline|attachment</code>) that you want Amazon CloudFront to send for a particular file. It\'s quite easy. You do this by setting <code>Properties -› Metadata (i.e. headers)</code> on a per-file basis, from inside your Amazon S3 Management Console. In short, when you upload a file to your Amazon S3 Bucket, if you want that file to be served a certain way, be sure to configure its <code>Properties -› Metadata</code> accordingly.</em></p>'."\n";
354
  echo (stripos(PHP_OS, "win") === 0 && c_ws_plugin__s2member_utils_conds::is_localhost()) ? '<p><em><strong>Localhost Developers:</strong> s2Member\'s Amazon CloudFront integration requires the <a href="http://php.net/manual/en/function.openssl-sign.php" target="_blank" rel="external">openssl_sign()</a> function in PHP so it can digitially sign CloudFront URLs. This function is sometimes problematic on localhost servers such as WAMP &amp; EasyPHP. We recommend installing <a href="http://www.slproweb.com/products/Win32OpenSSL.html" target="_blank" rel="external">this lightweight alternative for Windows</a> while you\'re developing. s2Member will automatically find it here: <code>C:\OpenSSL-Win[32/64]\bin\openssl.exe</code>.'.((file_exists("c:\openssl-win32\bin\openssl.exe") || file_exists("c:\openssl-win64\bin\openssl.exe")) ? ' <strong class="ws-menu-page-hilite">( s2Member has detected that OpenSSL-Win[32/64] IS installed in the correct location, thank you! )</strong>' : ' <strong class="ws-menu-page-hilite">(s2Member has detected that OpenSSL-Win[32/64] is NOT currently available)</strong>').'</em></p>'."\n" : '';
355
 
@@ -393,7 +393,7 @@ if(!class_exists("c_ws_plugin__s2member_menu_page_down_ops"))
393
 
394
  echo '<td>'."\n";
395
  echo '<input type="hidden" name="ws_plugin__s2member_amazon_cf_files_private_key" id="ws-plugin--s2member-amazon-cf-files-private-key" value="'.format_to_edit($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["amazon_cf_files_private_key"]).'" data-s-prev-config-value="'.format_to_edit($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["amazon_cf_files_private_key"]).'" />'."\n";
396
- echo '<textarea name="ws_plugin__s2member_amazon_cf_files_private_key_entry" id="ws-plugin--s2member-amazon-cf-files-private-key-entry" rows="3" wrap="off" spellcheck="false" class="monospace">'.format_to_edit($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["amazon_cf_files_private_key"]).'</textarea><br />'."\n";
397
  echo 'See: <code>Amazon Web Services Account -› Security Credentials -› CloudFront Key Pairs</code><br />'."\n";
398
  echo '<em>* Note, s2Member needs your <strong>Private Key file</strong>, NOT your Public Key file.</em>'."\n";
399
  echo '</td>'."\n";
@@ -443,7 +443,7 @@ if(!class_exists("c_ws_plugin__s2member_menu_page_down_ops"))
443
 
444
  echo '<td>'."\n";
445
  echo '<input type="text" autocomplete="off" name="ws_plugin__s2member_amazon_cf_files_distro_downloads_cname" id="ws-plugin--s2member-amazon-cf-files-downloads-distro-cname" value="'.format_to_edit($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["amazon_cf_files_distro_downloads_cname"]).'" /><br />'."\n";
446
- echo 'Example: <code>s2-file-downloads.'.esc_html(c_ws_plugin__s2member_utils_urls::parse_url(site_url(), PHP_URL_HOST)).'</code>.<br />'."\n";
447
  echo '<em>* Optional, do NOT fill this in unless you know what you\'re doing. This requires DNS changes.</em>'."\n";
448
  echo '</td>'."\n";
449
 
@@ -461,7 +461,7 @@ if(!class_exists("c_ws_plugin__s2member_menu_page_down_ops"))
461
 
462
  echo '<td>'."\n";
463
  echo '<input type="text" autocomplete="off" name="ws_plugin__s2member_amazon_cf_files_distro_streaming_cname" id="ws-plugin--s2member-amazon-cf-files-streaming-distro-cname" value="'.format_to_edit($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["amazon_cf_files_distro_streaming_cname"]).'" /><br />'."\n";
464
- echo 'Example: <code>s2-streaming-files.'.esc_html(c_ws_plugin__s2member_utils_urls::parse_url(site_url(), PHP_URL_HOST)).'</code>.<br />'."\n";
465
  echo '<em>* Optional, do NOT fill this in unless you know what you\'re doing. This requires DNS changes.</em>'."\n";
466
  echo '</td>'."\n";
467
 
64
  echo '<div class="ws-menu-page-hr"></div>'."\n";
65
 
66
  echo '<p><strong>Upload restricted files to this security-enabled directory:</strong><br /><code>'.esc_html(c_ws_plugin__s2member_utils_dirs::doc_root_path($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["files_dir"])).'</code></p>'."\n";
67
+ echo '<p>- Now, you can link to any protected file, using this special format:<br />&nbsp;&nbsp;<code>'.esc_html(home_url("/?s2member_file_download=example-file.zip")).'</code><br />&nbsp;&nbsp;<small><em><strong>s2member_file_download</strong> = file, relative to the /'.esc_html(c_ws_plugin__s2member_utils_dirs::basename_dir_app_data($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["files_dir"])).'/ directory. In other words, just the file name.</em></small></p>'."\n";
68
  echo '<p>- Or, use: <code>[s2File download="example-file.zip" /]</code> <em>(easier Shortcode if you prefer)</em><br />&nbsp;&nbsp;<small><em><strong>Shortcode equivalent:</strong> <code>[s2File /]</code> produces the entire URL for you, easier.</em></small></p>'."\n";
69
 
70
  echo '<div class="ws-menu-page-hr"></div>'."\n";
164
 
165
  echo '<div class="ws-menu-page-hr"></div>'."\n";
166
 
167
+ echo '<p>'.esc_html(home_url("/?s2member_file_download=example-file.zip")).'<code>&amp;s2member_file_download_key=&lt;?php echo s2member_file_download_key("example-file.zip"); ?&gt;</code><br />&nbsp;&nbsp;<small><em><strong>s2member_file_download_key</strong> = &lt;?php echo s2member_file_download_key("file, relative to the /'.esc_html(c_ws_plugin__s2member_utils_dirs::basename_dir_app_data($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["files_dir"])).'/ directory"); ?&gt;</em></small></p>'."\n";
168
 
169
  echo '<div class="ws-menu-page-hr"></div>'."\n";
170
 
171
+ echo '<p>'.esc_html(home_url("/?s2member_file_download=example-file.zip")).'<code>&amp;s2member_file_download_key=[s2Key file_download="example-file.zip" /]</code><br />&nbsp;&nbsp;<small><em><strong>Shortcode equivalent:</strong> <code>[s2Key file_download="example-file.zip" /]</code></em></small></p>'."\n";
172
 
173
  echo '<div class="ws-menu-page-hr"></div>'."\n";
174
 
261
  echo '<div class="ws-menu-page-hr"></div>'."\n";
262
 
263
  echo '<p><em><strong>Dev Note w/Technical Details:</strong> s2Member uses "Digitally Signed URLs", authenticated by the Amazon S3 API. Documented for developers <a href="http://docs.amazonwebservices.com/AmazonS3/latest/dev/index.html?RESTAuthentication.html" target="_blank" rel="external">here</a>. To put it simply, s2Member will generate Amazon S3 URLs (internally); which allow Customers temporary access to specific files inside your S3 Bucket. s2Member\'s Digitally Signed URLs leading to Amazon S3, give a Customer 24 hours to connect to the file inside your S3 Bucket. This connection period of 24 hours is largely irrelevant when used in combination with s2Member, because access is renewed for another 24 hours each time you make a file available to a User/Member, and they are authenticated by your configuration of s2Member. This connection period of 24 hours is just a secondary line of defense to further prevent the possibility of link sharing. If you need to change this connection timeout of <code>24 hours</code> for some reason (not likely), you can use this WordPress Filter: <code>ws_plugin__s2member_amazon_s3_file_expires_time</code>.</em></p>'."\n";
264
+ echo '<p><em><strong>Linking To Protected Files:</strong> Nothing changes. s2Member\'s integration with Amazon S3 serves protected files through the same links that all s2Member site owners use. For example, you might use: <code>'.esc_html(home_url("/?s2member_file_download=example-file.zip")).'</code>, where <strong>s2member_file_download</strong> = the file, relative to the root of your Amazon S3 Bucket. In other words, just the file name in most cases. s2Member will redirect Users/Members to a digitally signed Amazon S3 URL, which allows them access to a particular file via Amazon S3. For further details, please review this section of your Dashboard: <code>s2Member -› Download Options -› Basic Download Restrictions</code>. Also see: <code>s2Member -› Download Options -› Advanced Mod-Rewrite Linkage</code>.</em></p>'."\n";
265
  echo '<p><em><strong>Content Type, Disposition &amp; Inline Files:</strong> The query string parameter <code>&amp;s2member_file_inline=yes</code> DOES work for files served directly through Amazon S3. s2Member DOES have control over the <code>Content-Type</code> and <code>Content-Disposition</code> headers for files being served through Amazon S3. However, Amazon CloudFront servers do NOT automatically determine the MIME type for the objects they serve. If you integrate both Amazon S3 and CloudFront, s2Member will NOT have control over headers. Therefore, when you upload a file to your Amazon S3 Bucket, you should set its Content-Type header. Again, with the Amazon S3/CloudFront combination, you MUST configure headers yourself (such as <code>Content-Type: video/webm</code>, or <code>Content-Disposition: inline|attachment</code>) that you want Amazon CloudFront to send for a particular file. It\'s quite easy. You do this by setting <code>Properties -› Metadata (i.e. headers)</code> on a per-file basis, from inside your Amazon S3 Management Console. In short, when you upload a file to your Amazon S3 Bucket, if you want that file to be served a certain way, be sure to configure its <code>Properties -› Metadata</code> accordingly.</em></p>'."\n";
266
 
267
  echo '<div class="ws-menu-page-hr"></div>'."\n";
349
 
350
  echo '<p><em><strong>Dev Note w/Technical Details:</strong> s2Member\'s auto-configuration routines for Amazon CloudFront (below), are designed to create &amp; configure various components on your Amazon Web Services account, which are all requirements for you to <a href="http://docs.amazonwebservices.com/AmazonCloudFront/2010-11-01/DeveloperGuide/index.html?HowToPrivateContent.html" target="_blank" rel="external">serve protected files through the Amazon S3/CloudFront combination</a>. These components include: an Origin Access Identity, read permissions for the Origin Access Identity, and two private content Distributions. One private content Distribution for file downloads, and another private content Distribution for streaming media files; both connected to and sourced by your Amazon S3 Bucket. In addition, s2Member will automatically configure an ACL &amp; Policy (i.e. permissions) on your Amazon S3 Bucket to make sure your protected object/files are NOT available to the public.</em></p>'."\n";
351
  echo '<p><em><strong>Dev Note w/Technical Details:</strong> s2Member uses "Digitally Signed URLs", authenticated by the Amazon CloudFront API. Documented for developers <a href="http://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/PrivateContent.html" target="_blank" rel="external">here</a>. To put it simply, s2Member will generate Amazon CloudFront URLs (internally); which allow Customers temporary access to specific files inside your S3 Bucket — via CloudFront Distributions. s2Member\'s Digitally Signed URLs leading to Amazon S3/CloudFront, give a Customer 24 hours to connect to the file inside your S3 Bucket. This connection period of 24 hours is largely irrelevant when used in combination with s2Member, because access is renewed for another 24 hours each time you make a file available to a User/Member, and they are authenticated by your configuration of s2Member. This connection period of 24 hours is just a secondary line of defense to further prevent the possibility of link sharing. If you need to change this connection timeout of <code>24 hours</code> for some reason (not likely), you can use this WordPress Filter: <code>ws_plugin__s2member_amazon_cf_file_expires_time</code>.</em></p>'."\n";
352
+ echo '<p><em><strong>Linking To Protected Files:</strong> RTMP streams are special, but nothing else changes. s2Member\'s integration with Amazon S3/CloudFront serves protected files through the same links that all s2Member site owners use. For example, you might use: <code>'.esc_html(home_url("/?s2member_file_download=example-file.zip")).'</code>, where <strong>s2member_file_download</strong> = the file, relative to the root of your Amazon S3 Bucket. In other words, just the file name in most cases. s2Member will redirect Users/Members to a digitally signed Amazon CloudFront URL, which allows them access to a particular file via Amazon CloudFront. For further details, please review this section of your Dashboard: <code>s2Member -› Download Options -› Basic Download Restrictions</code>. Also see: <code>s2Member -› Download Options -› Advanced Mod-Rewrite Linkage</code>. If you\'re streaming audio/video files over the RTMP protocol, please review the section below: <code>JW Player &amp; RTMP Protocol Examples</code>.</em></p>'."\n";
353
  echo '<p><em><strong>Content Type, Disposition &amp; Inline Files:</strong> An IMPORTANT issue. The query string parameter <code>&amp;s2member_file_inline=yes</code> does NOTHING for files served via Amazon CloudFront. s2Member has NO control over the <code>Content-Type</code> and/or <code>Content-Disposition</code> headers for a file being served through Amazon CloudFront, and CloudFront servers do NOT automatically determine the MIME type for the objects they serve. Therefore, when you upload a file to your Amazon S3 Bucket, you should set its Content-Type header. That is, you MUST configure headers yourself (such as <code>Content-Type: video/webm</code>, or <code>Content-Disposition: inline|attachment</code>) that you want Amazon CloudFront to send for a particular file. It\'s quite easy. You do this by setting <code>Properties -› Metadata (i.e. headers)</code> on a per-file basis, from inside your Amazon S3 Management Console. In short, when you upload a file to your Amazon S3 Bucket, if you want that file to be served a certain way, be sure to configure its <code>Properties -› Metadata</code> accordingly.</em></p>'."\n";
354
  echo (stripos(PHP_OS, "win") === 0 && c_ws_plugin__s2member_utils_conds::is_localhost()) ? '<p><em><strong>Localhost Developers:</strong> s2Member\'s Amazon CloudFront integration requires the <a href="http://php.net/manual/en/function.openssl-sign.php" target="_blank" rel="external">openssl_sign()</a> function in PHP so it can digitially sign CloudFront URLs. This function is sometimes problematic on localhost servers such as WAMP &amp; EasyPHP. We recommend installing <a href="http://www.slproweb.com/products/Win32OpenSSL.html" target="_blank" rel="external">this lightweight alternative for Windows</a> while you\'re developing. s2Member will automatically find it here: <code>C:\OpenSSL-Win[32/64]\bin\openssl.exe</code>.'.((file_exists("c:\openssl-win32\bin\openssl.exe") || file_exists("c:\openssl-win64\bin\openssl.exe")) ? ' <strong class="ws-menu-page-hilite">( s2Member has detected that OpenSSL-Win[32/64] IS installed in the correct location, thank you! )</strong>' : ' <strong class="ws-menu-page-hilite">(s2Member has detected that OpenSSL-Win[32/64] is NOT currently available)</strong>').'</em></p>'."\n" : '';
355
 
393
 
394
  echo '<td>'."\n";
395
  echo '<input type="hidden" name="ws_plugin__s2member_amazon_cf_files_private_key" id="ws-plugin--s2member-amazon-cf-files-private-key" value="'.format_to_edit($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["amazon_cf_files_private_key"]).'" data-s-prev-config-value="'.format_to_edit($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["amazon_cf_files_private_key"]).'" />'."\n";
396
+ echo '<textarea name="ws_plugin__s2member_amazon_cf_files_private_key_entry" id="ws-plugin--s2member-amazon-cf-files-private-key-entry" rows="3" wrap="off" spellcheck="false">'.format_to_edit($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["amazon_cf_files_private_key"]).'</textarea><br />'."\n";
397
  echo 'See: <code>Amazon Web Services Account -› Security Credentials -› CloudFront Key Pairs</code><br />'."\n";
398
  echo '<em>* Note, s2Member needs your <strong>Private Key file</strong>, NOT your Public Key file.</em>'."\n";
399
  echo '</td>'."\n";
443
 
444
  echo '<td>'."\n";
445
  echo '<input type="text" autocomplete="off" name="ws_plugin__s2member_amazon_cf_files_distro_downloads_cname" id="ws-plugin--s2member-amazon-cf-files-downloads-distro-cname" value="'.format_to_edit($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["amazon_cf_files_distro_downloads_cname"]).'" /><br />'."\n";
446
+ echo 'Example: <code>s2-file-downloads.'.esc_html(c_ws_plugin__s2member_utils_urls::parse_url(home_url(), PHP_URL_HOST)).'</code>.<br />'."\n";
447
  echo '<em>* Optional, do NOT fill this in unless you know what you\'re doing. This requires DNS changes.</em>'."\n";
448
  echo '</td>'."\n";
449
 
461
 
462
  echo '<td>'."\n";
463
  echo '<input type="text" autocomplete="off" name="ws_plugin__s2member_amazon_cf_files_distro_streaming_cname" id="ws-plugin--s2member-amazon-cf-files-streaming-distro-cname" value="'.format_to_edit($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["amazon_cf_files_distro_streaming_cname"]).'" /><br />'."\n";
464
+ echo 'Example: <code>s2-streaming-files.'.esc_html(c_ws_plugin__s2member_utils_urls::parse_url(home_url(), PHP_URL_HOST)).'</code>.<br />'."\n";
465
  echo '<em>* Optional, do NOT fill this in unless you know what you\'re doing. This requires DNS changes.</em>'."\n";
466
  echo '</td>'."\n";
467
 
includes/menu-pages/els-ops.inc.php CHANGED
@@ -199,7 +199,7 @@ if(!class_exists("c_ws_plugin__s2member_menu_page_els_ops"))
199
  echo '<div class="ws-menu-page-group" title="AWeber Integration">'."\n";
200
 
201
  echo '<div class="ws-menu-page-section ws-plugin--s2member-aweber-section">'."\n";
202
- echo '<a href="http://www.s2member.com/aweber" target="_blank"><img src="'.esc_attr($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["dir_url"]).'/images/aweber-logo.png" class="ws-menu-page-right screenshot" style="width:125px; height:125px; border:0;" alt="." /></a>'."\n";
203
  echo '<h3>AWeber List Server Integration (optional)</h3>'."\n";
204
  echo '<p>s2Member can be integrated with AWeber. AWeber is an email marketing service. Whether you\'re looking to get your first email campaign off the ground, or you\'re a seasoned veteran who wants to dig into advanced tools like detailed email web analytics, activity based segmentation, geo-targeting and broadcast split-testing, AWeber\'s got just what you need to make email marketing work for you.</p>'."\n";
205
  echo '<p>You can have your Members automatically subscribed to your AWeber marketing lists <em>(e.g. newsletters / auto-responders)</em>. You\'ll need an <a href="http://www.s2member.com/aweber" target="_blank" rel="external">AWeber account</a> and your <a href="#" onclick="alert(\'To obtain your AWeber List ID(s), log into your AWeber account. Click on the Lists tab. On that page you\\\'ll find a Unique List ID associated with each of your lists. AWeber sometimes refers to this as a List Name instead of a List ID.\'); return false;">AWeber List IDs</a>. You will ALSO need to configure a <a href="http://www.s2member.com/kb/aweber-email-parser-for-s2member/" target="_blank" rel="external">Custom Email Parser</a> inside your AWeber account.</p>'."\n";
199
  echo '<div class="ws-menu-page-group" title="AWeber Integration">'."\n";
200
 
201
  echo '<div class="ws-menu-page-section ws-plugin--s2member-aweber-section">'."\n";
202
+ echo '<a href="http://www.s2member.com/aweber" target="_blank"><img src="'.esc_attr($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["dir_url"]).'/images/aweber-logo.png" class="ws-menu-page-right ws-menu-page-bordered" style="width:125px; height:125px; border:0;" alt="." /></a>'."\n";
203
  echo '<h3>AWeber List Server Integration (optional)</h3>'."\n";
204
  echo '<p>s2Member can be integrated with AWeber. AWeber is an email marketing service. Whether you\'re looking to get your first email campaign off the ground, or you\'re a seasoned veteran who wants to dig into advanced tools like detailed email web analytics, activity based segmentation, geo-targeting and broadcast split-testing, AWeber\'s got just what you need to make email marketing work for you.</p>'."\n";
205
  echo '<p>You can have your Members automatically subscribed to your AWeber marketing lists <em>(e.g. newsletters / auto-responders)</em>. You\'ll need an <a href="http://www.s2member.com/aweber" target="_blank" rel="external">AWeber account</a> and your <a href="#" onclick="alert(\'To obtain your AWeber List ID(s), log into your AWeber account. Click on the Lists tab. On that page you\\\'ll find a Unique List ID associated with each of your lists. AWeber sometimes refers to this as a List Name instead of a List ID.\'); return false;">AWeber List IDs</a>. You will ALSO need to configure a <a href="http://www.s2member.com/kb/aweber-email-parser-for-s2member/" target="_blank" rel="external">Custom Email Parser</a> inside your AWeber account.</p>'."\n";
includes/menu-pages/gen-ops.inc.php CHANGED
@@ -211,7 +211,7 @@ if(!class_exists("c_ws_plugin__s2member_menu_page_gen_ops"))
211
  echo '<div class="ws-menu-page-right">'.c_ws_plugin__s2member_utilities::s_badge_gen("1", TRUE, TRUE).'</div>'."\n";
212
  echo '<p>An s2Member Security Badge <em>(optional)</em>, can be used to express your site\'s concern for security; demonstrating to all Users/Members that your site <em>(and the s2Member software)</em>, takes security seriously. However, in order to qualify your site, you MUST generate a Security Encryption Key <em>(previous section)</em>, and then click "Save All Changes". Only then, will s2Member officially verify your installation <em>(verification occurs automatically)</em>.</p>'."\n";
213
  echo '<p>Once you\'ve <a href="http://www.s2member.com/kb/security-badges/" target="_blank" rel="external">properly configured all security aspects of s2Member</a>, your s2Member Security Badge will be verified. To see the "verified" version of your Security Badge, you might need to refresh your browser after saving all changes <em>(i.e. after you create a Security Encryption Key)</em>. Also, s2Member will NOT "verify" your site if you turn off Unique IP Restrictions, Brute Force Login Protection, or if your <code>/wp-config.php</code> file lacks <a href="http://codex.wordpress.org/Editing_wp-config.php#Security_Keys" target="_blank" rel="external">Security Keys</a> <em>(each at least 60 chars in length)</em>. In addition, it\'s NOT possible for s2Member to verify your Security Badge, if your site is in a <code>localhost</code> environment; i.e. not connected to the web.</p>'."\n";
214
- echo '<p><strong>How does s2Member know when my site is secure?</strong><br />If enabled below, an API call for "Security Badge Status", will allow web service connections to determine your status. Clicking <a href="'.esc_attr(site_url("/?s2member_s_badge_status=1")).'" target="_blank" rel="external">this link</a> will report <code>1</code> <em>(secure)</em>, <code>0</code> <em>(at risk)</em>, or <code>-</code> <em>(API disabled)</em>. Once all security considerations are satisfied, s2Member will report <code>1</code> <em>(secure)</em> for your installation. *Note, this simple API will NOT, and should not, report any other information. It will ONLY report the current status of your Security Badge, as determined by your installation of s2Member. When/if you install the s2Member Security Badge, s2Member will make a connection to your site "once per day", to test your status.</p>'."\n";
215
  do_action("ws_plugin__s2member_during_gen_ops_page_during_left_sections_during_s_badge_wp_footer_code", get_defined_vars());
216
 
217
  echo '<table class="form-table">'."\n";
@@ -249,7 +249,7 @@ if(!class_exists("c_ws_plugin__s2member_menu_page_gen_ops"))
249
  echo '<tr>'."\n";
250
 
251
  echo '<td>'."\n";
252
- echo '<textarea name="ws_plugin__s2member_wp_footer_code" id="ws-plugin--s2member-wp-footer-code" rows="8" wrap="off" spellcheck="false" class="monospace">'.format_to_edit($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["wp_footer_code"]).'</textarea><br />'."\n";
253
  echo 'Any valid XHTML / JavaScript'.((is_multisite() && c_ws_plugin__s2member_utils_conds::is_multisite_farm() && !is_main_site()) ? '' : ' (or even PHP)').' code will work just fine here.'."\n";
254
  echo '</td>'."\n";
255
 
@@ -324,7 +324,7 @@ if(!class_exists("c_ws_plugin__s2member_menu_page_gen_ops"))
324
  echo '<td>'."\n";
325
  echo '<input type="text" autocomplete="off" name="ws_plugin__s2member_reg_email_support_link" id="ws-plugin--s2member-reg-email-support-link" value="'.format_to_edit($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["reg_email_support_link"]).'" /><br />'."\n";
326
  echo 'Ex: <code>mailto:support@your-domain.com</code> (<em>mailto link</em>).<br />'."\n";
327
- echo 'Or: <code>'.esc_html(site_url("/contact-us/")).'</code>.'."\n";
328
  echo '</td>'."\n";
329
 
330
  echo '</tr>'."\n";
@@ -1271,7 +1271,7 @@ if(!class_exists("c_ws_plugin__s2member_menu_page_gen_ops"))
1271
 
1272
  echo '<td>'."\n";
1273
  echo '<input type="text" autocomplete="off" name="ws_plugin__s2member_login_redirection_override" id="ws-plugin--s2member-login-redirection-override" value="'.format_to_edit($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["login_redirection_override"]).'" /><br />'."\n";
1274
- echo 'Or, you may configure a Special Redirection URL, if you prefer. You\'ll need to type in the full URL, starting with: <code>http://</code>. <em>A few <a href="#" onclick="alert(\'Replacement Codes:\\n\\n%%current_user_login%% = The current User\\\'s Username, lowercase (deprecated, please use %%current_user_nicename%%).\\n\\n%%current_user_nicename%% = The current User\\\'s Nicename in lowercase format (i.e. a cleaner version of the username for URLs; recommended for best compatibility).\\n\\n%%current_user_id%% = The current User\\\'s ID.\\n\\n%%current_user_level%% = The current User\\\'s s2Member Level.\\n\\n%%current_user_role%% = The current User\\\'s WordPress Role.'.((!is_multisite() || !c_ws_plugin__s2member_utils_conds::is_multisite_farm() || is_main_site()) ? '\\n\\n%%current_user_ccaps%% = The current User\\\'s Custom Capabilities.' : '').'\\n\\n%%current_user_logins%% = Number of times the current User has logged in.\\n\\nFor example, if you\\\'re using BuddyPress, and you want to redirect Members to their BuddyPress Profile page after logging in, you would setup a Special Redirection URL, like this: '.site_url("/members/%%current_user_nicename%%/profile/").'\\n\\nOr ... using %%current_user_level%%, you could have a separate Login Welcome Page for each Membership Level that you plan to offer. BuddyPress not required.\'); return false;">Replacement Codes</a> are also supported here.</em>'."\n";
1275
  echo '</td>'."\n";
1276
 
1277
  echo '</tr>'."\n";
@@ -1396,7 +1396,7 @@ if(!class_exists("c_ws_plugin__s2member_menu_page_gen_ops"))
1396
  echo '<h3>Giving Members The Ability To Modify Their Profile</h3>'."\n";
1397
  echo '<p>s2Member can be configured to redirect Members away from the <a href="'.esc_attr(admin_url("/profile.php")).'" target="_blank" rel="external">default Profile Editing Panel</a> that is built into WordPress. When/if a Member attempts to access the default Profile Editing Panel, they\'ll instead, be redirected to the Login Welcome Page that you\'ve configured through s2Member. <strong>Why would I redirect?</strong> Unless you\'ve made some drastic modifications to your WordPress installation, the default Profile Editing Panel that ships with WordPress, is NOT really suited for public access, even by a Member.</p>'."\n";
1398
  echo '<p>So instead of using this default Profile Editing Panel; s2Member creates an added layer of functionality, on top of WordPress. It does this by providing you <em>(as the site owner)</em>, with a special Shortcode: <code>[s2Member-Profile /]</code> that you can place into your Login Welcome Page, or any Post/Page for that matter <em>(even into a Text Widget)</em>. This Shortcode produces an Inline Profile Editing Form that supports all aspects of s2Member, including Password changes; and any Custom Registration/Profile Fields that you\'ve configured with s2Member.</p>'."\n";
1399
- echo '<p>Alternatively, s2Member also gives you the ability to send your Members to a <a href="'.esc_attr(site_url("/?s2member_profile=1")).'" target="_blank" rel="external">special Stand-Alone version</a>. This Stand-Alone version has been designed <em>(with a bare-bones format)</em>, intentionally. This makes it possible for you to <a href="#" onclick="if(!window.open(\''.site_url("/?s2member_profile=1").'\', \'_popup\', \'width=600,height=400,left=100,screenX=100,top=100,screenY=100,location=0,menubar=0,toolbar=0,status=0,scrollbars=1,resizable=1\')) alert(\'Please disable popup blockers and try again!\'); return false;" rel="external">open it up in a popup window</a>, or embed it into your Login Welcome Page using an IFRAME. Code samples are provided below.</p>'."\n";
1400
  echo (c_ws_plugin__s2member_utils_conds::bp_is_installed()) ? '<p><em><strong>BuddyPress:</strong> BuddyPress already provides Users/Members with a Profile Editing Panel, powered by your theme. If you\'ve configured Custom Registration/Profile Fields with s2Member, you can also enable s2Member\'s Profile Field integration with BuddyPress (recommended). For further details, see: <code>s2Member -› General Options -› Registration/Profile Fields</code>.</em></p>'."\n" : '';
1401
  do_action("ws_plugin__s2member_during_gen_ops_page_during_left_sections_during_profile_modifications", get_defined_vars());
1402
 
@@ -1428,10 +1428,10 @@ if(!class_exists("c_ws_plugin__s2member_menu_page_gen_ops"))
1428
  echo '<div class="ws-menu-page-hr"></div>'."\n";
1429
 
1430
  echo '<p><strong>Shortcode (copy/paste)</strong>, for an Inline Profile Modification Form:<br />'."\n";
1431
- echo '<p><input type="text" autocomplete="off" value="'.format_to_edit('[s2Member-Profile /]').'" class="monospace" onclick="this.select ();" /></p>'."\n";
1432
 
1433
  echo '<p style="margin-top:20px;"><strong>Stand-Alone (copy/paste)</strong>, for popup window:</p>'."\n";
1434
- echo '<p><input type="text" autocomplete="off" value="'.format_to_edit(preg_replace("/\<\?php echo S2MEMBER_CURRENT_USER_PROFILE_MODIFICATION_PAGE_URL; \?\>/", c_ws_plugin__s2member_utils_strings::esc_refs(site_url("/?s2member_profile=1")), file_get_contents(dirname(__FILE__)."/code-samples/current-user-profile-modification-page-url-2-ops.x-php"))).'" class="monospace" onclick="this.select ();" /></p>'."\n";
1435
  echo '</div>'."\n";
1436
 
1437
  echo '</div>'."\n";
211
  echo '<div class="ws-menu-page-right">'.c_ws_plugin__s2member_utilities::s_badge_gen("1", TRUE, TRUE).'</div>'."\n";
212
  echo '<p>An s2Member Security Badge <em>(optional)</em>, can be used to express your site\'s concern for security; demonstrating to all Users/Members that your site <em>(and the s2Member software)</em>, takes security seriously. However, in order to qualify your site, you MUST generate a Security Encryption Key <em>(previous section)</em>, and then click "Save All Changes". Only then, will s2Member officially verify your installation <em>(verification occurs automatically)</em>.</p>'."\n";
213
  echo '<p>Once you\'ve <a href="http://www.s2member.com/kb/security-badges/" target="_blank" rel="external">properly configured all security aspects of s2Member</a>, your s2Member Security Badge will be verified. To see the "verified" version of your Security Badge, you might need to refresh your browser after saving all changes <em>(i.e. after you create a Security Encryption Key)</em>. Also, s2Member will NOT "verify" your site if you turn off Unique IP Restrictions, Brute Force Login Protection, or if your <code>/wp-config.php</code> file lacks <a href="http://codex.wordpress.org/Editing_wp-config.php#Security_Keys" target="_blank" rel="external">Security Keys</a> <em>(each at least 60 chars in length)</em>. In addition, it\'s NOT possible for s2Member to verify your Security Badge, if your site is in a <code>localhost</code> environment; i.e. not connected to the web.</p>'."\n";
214
+ echo '<p><strong>How does s2Member know when my site is secure?</strong><br />If enabled below, an API call for "Security Badge Status", will allow web service connections to determine your status. Clicking <a href="'.esc_attr(home_url("/?s2member_s_badge_status=1")).'" target="_blank" rel="external">this link</a> will report <code>1</code> <em>(secure)</em>, <code>0</code> <em>(at risk)</em>, or <code>-</code> <em>(API disabled)</em>. Once all security considerations are satisfied, s2Member will report <code>1</code> <em>(secure)</em> for your installation. *Note, this simple API will NOT, and should not, report any other information. It will ONLY report the current status of your Security Badge, as determined by your installation of s2Member. When/if you install the s2Member Security Badge, s2Member will make a connection to your site "once per day", to test your status.</p>'."\n";
215
  do_action("ws_plugin__s2member_during_gen_ops_page_during_left_sections_during_s_badge_wp_footer_code", get_defined_vars());
216
 
217
  echo '<table class="form-table">'."\n";
249
  echo '<tr>'."\n";
250
 
251
  echo '<td>'."\n";
252
+ echo '<textarea name="ws_plugin__s2member_wp_footer_code" id="ws-plugin--s2member-wp-footer-code" rows="8" wrap="off" spellcheck="false">'.format_to_edit($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["wp_footer_code"]).'</textarea><br />'."\n";
253
  echo 'Any valid XHTML / JavaScript'.((is_multisite() && c_ws_plugin__s2member_utils_conds::is_multisite_farm() && !is_main_site()) ? '' : ' (or even PHP)').' code will work just fine here.'."\n";
254
  echo '</td>'."\n";
255
 
324
  echo '<td>'."\n";
325
  echo '<input type="text" autocomplete="off" name="ws_plugin__s2member_reg_email_support_link" id="ws-plugin--s2member-reg-email-support-link" value="'.format_to_edit($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["reg_email_support_link"]).'" /><br />'."\n";
326
  echo 'Ex: <code>mailto:support@your-domain.com</code> (<em>mailto link</em>).<br />'."\n";
327
+ echo 'Or: <code>'.esc_html(home_url("/contact-us/")).'</code>.'."\n";
328
  echo '</td>'."\n";
329
 
330
  echo '</tr>'."\n";
1271
 
1272
  echo '<td>'."\n";
1273
  echo '<input type="text" autocomplete="off" name="ws_plugin__s2member_login_redirection_override" id="ws-plugin--s2member-login-redirection-override" value="'.format_to_edit($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["login_redirection_override"]).'" /><br />'."\n";
1274
+ echo 'Or, you may configure a Special Redirection URL, if you prefer. You\'ll need to type in the full URL, starting with: <code>http://</code>. <em>A few <a href="#" onclick="alert(\'Replacement Codes:\\n\\n%%current_user_login%% = The current User\\\'s Username, lowercase (deprecated, please use %%current_user_nicename%%).\\n\\n%%current_user_nicename%% = The current User\\\'s Nicename in lowercase format (i.e. a cleaner version of the username for URLs; recommended for best compatibility).\\n\\n%%current_user_id%% = The current User\\\'s ID.\\n\\n%%current_user_level%% = The current User\\\'s s2Member Level.\\n\\n%%current_user_role%% = The current User\\\'s WordPress Role.'.((!is_multisite() || !c_ws_plugin__s2member_utils_conds::is_multisite_farm() || is_main_site()) ? '\\n\\n%%current_user_ccaps%% = The current User\\\'s Custom Capabilities.' : '').'\\n\\n%%current_user_logins%% = Number of times the current User has logged in.\\n\\nFor example, if you\\\'re using BuddyPress, and you want to redirect Members to their BuddyPress Profile page after logging in, you would setup a Special Redirection URL, like this: '.home_url("/members/%%current_user_nicename%%/profile/").'\\n\\nOr ... using %%current_user_level%%, you could have a separate Login Welcome Page for each Membership Level that you plan to offer. BuddyPress not required.\'); return false;">Replacement Codes</a> are also supported here.</em>'."\n";
1275
  echo '</td>'."\n";
1276
 
1277
  echo '</tr>'."\n";
1396
  echo '<h3>Giving Members The Ability To Modify Their Profile</h3>'."\n";
1397
  echo '<p>s2Member can be configured to redirect Members away from the <a href="'.esc_attr(admin_url("/profile.php")).'" target="_blank" rel="external">default Profile Editing Panel</a> that is built into WordPress. When/if a Member attempts to access the default Profile Editing Panel, they\'ll instead, be redirected to the Login Welcome Page that you\'ve configured through s2Member. <strong>Why would I redirect?</strong> Unless you\'ve made some drastic modifications to your WordPress installation, the default Profile Editing Panel that ships with WordPress, is NOT really suited for public access, even by a Member.</p>'."\n";
1398
  echo '<p>So instead of using this default Profile Editing Panel; s2Member creates an added layer of functionality, on top of WordPress. It does this by providing you <em>(as the site owner)</em>, with a special Shortcode: <code>[s2Member-Profile /]</code> that you can place into your Login Welcome Page, or any Post/Page for that matter <em>(even into a Text Widget)</em>. This Shortcode produces an Inline Profile Editing Form that supports all aspects of s2Member, including Password changes; and any Custom Registration/Profile Fields that you\'ve configured with s2Member.</p>'."\n";
1399
+ echo '<p>Alternatively, s2Member also gives you the ability to send your Members to a <a href="'.esc_attr(home_url("/?s2member_profile=1")).'" target="_blank" rel="external">special Stand-Alone version</a>. This Stand-Alone version has been designed <em>(with a bare-bones format)</em>, intentionally. This makes it possible for you to <a href="#" onclick="if(!window.open(\''.home_url("/?s2member_profile=1").'\', \'_popup\', \'width=600,height=400,left=100,screenX=100,top=100,screenY=100,location=0,menubar=0,toolbar=0,status=0,scrollbars=1,resizable=1\')) alert(\'Please disable popup blockers and try again!\'); return false;" rel="external">open it up in a popup window</a>, or embed it into your Login Welcome Page using an IFRAME. Code samples are provided below.</p>'."\n";
1400
  echo (c_ws_plugin__s2member_utils_conds::bp_is_installed()) ? '<p><em><strong>BuddyPress:</strong> BuddyPress already provides Users/Members with a Profile Editing Panel, powered by your theme. If you\'ve configured Custom Registration/Profile Fields with s2Member, you can also enable s2Member\'s Profile Field integration with BuddyPress (recommended). For further details, see: <code>s2Member -› General Options -› Registration/Profile Fields</code>.</em></p>'."\n" : '';
1401
  do_action("ws_plugin__s2member_during_gen_ops_page_during_left_sections_during_profile_modifications", get_defined_vars());
1402
 
1428
  echo '<div class="ws-menu-page-hr"></div>'."\n";
1429
 
1430
  echo '<p><strong>Shortcode (copy/paste)</strong>, for an Inline Profile Modification Form:<br />'."\n";
1431
+ echo '<p><input type="text" autocomplete="off" value="'.format_to_edit('[s2Member-Profile /]').'" onclick="this.select ();" /></p>'."\n";
1432
 
1433
  echo '<p style="margin-top:20px;"><strong>Stand-Alone (copy/paste)</strong>, for popup window:</p>'."\n";
1434
+ echo '<p><input type="text" autocomplete="off" value="'.format_to_edit(preg_replace("/\<\?php echo S2MEMBER_CURRENT_USER_PROFILE_MODIFICATION_PAGE_URL; \?\>/", c_ws_plugin__s2member_utils_strings::esc_refs(home_url("/?s2member_profile=1")), file_get_contents(dirname(__FILE__)."/code-samples/current-user-profile-modification-page-url-2-ops.x-php"))).'" onclick="this.select ();" /></p>'."\n";
1435
  echo '</div>'."\n";
1436
 
1437
  echo '</div>'."\n";
includes/menu-pages/logs.inc.php CHANGED
@@ -1,351 +1,348 @@
1
  <?php
2
  /**
3
- * Menu page for the s2Member plugin (Logs page).
4
- *
5
- * Copyright: © 2009-2011
6
- * {@link http://www.websharks-inc.com/ WebSharks, Inc.}
7
- * (coded in the USA)
8
- *
9
- * Released under the terms of the GNU General Public License.
10
- * You should have received a copy of the GNU General Public License,
11
- * along with this software. In the main directory, see: /licensing/
12
- * If not, see: {@link http://www.gnu.org/licenses/}.
13
- *
14
- * @package s2Member\Menu_Pages
15
- * @since 130210
16
- */
17
  if(realpath(__FILE__) === realpath($_SERVER["SCRIPT_FILENAME"]))
18
  exit("Do not access this file directly.");
19
 
20
  if(!class_exists("c_ws_plugin__s2member_menu_page_logs"))
 
 
 
 
 
 
 
 
21
  {
22
- /**
23
- * Menu page for the s2Member plugin (Integrations page).
24
- *
25
- * @package s2Member\Menu_Pages
26
- * @since 110531
27
- */
28
- class c_ws_plugin__s2member_menu_page_logs
29
- {
30
- public function __construct()
31
- {
32
- echo '<div class="wrap ws-menu-page">'."\n";
33
 
34
- echo '<div class="ws-menu-page-toolbox">'."\n";
35
- c_ws_plugin__s2member_menu_pages_tb::display ();
36
- echo '</div>'."\n";
37
 
38
- echo '<h2>Log Files</h2>'."\n";
39
 
40
- echo '<table class="ws-menu-page-table">'."\n";
41
- echo '<tbody class="ws-menu-page-table-tbody">'."\n";
42
- echo '<tr class="ws-menu-page-table-tr">'."\n";
43
- echo '<td class="ws-menu-page-table-l">'."\n";
44
 
45
- do_action("ws_plugin__s2member_during_logs_page_before_left_sections", get_defined_vars());
46
 
47
- if (apply_filters("ws_plugin__s2member_during_logs_page_during_left_sections_display_help", true, get_defined_vars ()))
48
- {
49
- do_action("ws_plugin__s2member_during_logs_page_during_left_sections_before_help", get_defined_vars ());
50
 
51
- echo '<div class="ws-menu-page-group" title="Getting Help">' . "\n";
52
 
53
- echo '<div class="ws-menu-page-section ws-plugin--s2member-help">' . "\n";
54
- echo '<h3>Getting Help w/ s2Member (Troubleshooting)</h3>' . "\n";
55
- echo '<p>s2Member is pretty easy to setup and install initially. Most of the official documentation is right here in your Dashboard (i.e. there is a lot of inline documentation built into the software). That being said, it CAN take some time to master everything there is to know about s2Member\'s advanced features. If you need assistance with s2Member, please search the <a href="http://www.s2member.com/kb/" target="_blank" rel="external">s2Member Knowledge Base</a>, <a href="http://www.s2member.com/videos/" target="_blank" rel="external">Video Tutorials</a>, <a href="http://www.s2member.com/forums/" target="_blank" rel="external">Forums</a> and <a href="http://www.s2member.com/codex/" target="_blank" rel="external">Codex</a>. If you are planning to do something creative with s2Member, you might want to <a href="http://jobs.wordpress.net" target="_blank" rel="external">hire a freelance developer</a> to assist you.</p>' . "\n";
56
- echo '<p><strong>See also:</strong> <a href="http://www.s2member.com/kb/common-troubleshooting-tips/" target="_blank" rel="external">s2Member Troubleshooting Guide</a> (please read this first if you\'re having trouble).</p>'."\n";
57
 
58
- echo '<div class="ws-menu-page-hr"></div>' . "\n";
59
 
60
- echo '<h3>Testing Server Compatibility</h3>'."\n";
61
- echo '<p>Please download the <a href="http://www.s2member.com/r/server-check-tool/">s2Member Server Scanner</a>. Unzip, upload via FTP; then open in a browser for a full report.</p>'."\n";
62
 
63
- echo '<div class="ws-menu-page-hr"></div>' . "\n";
64
 
65
- echo '<h3>Troubleshooting Payment Gateway Integrations</h3>'."\n";
66
- echo '<p>Please use the s2Member Log Viewer (below). Log files can be very helpful.</p>'."\n";
67
 
68
- echo '<div class="ws-menu-page-hr"></div>' . "\n";
69
 
70
- echo '<h3>Search s2Member KB Articles, Forums, Codex and more<em>!</em></h3>'."\n";
71
- echo '<form method="get" action="http://www.s2member.com/quick-s.php" target="_blank" onsubmit="if(this.q.value === \'enter search terms...\') this.q.value = \'\';">'."\n";
72
- echo '<p><input type="text" name="q" value="enter search terms..." style="width:60%;" onfocus="if(this.value === \'enter search terms...\') this.value = \'\';" onblur="if(this.value === \'\') this.value = \'enter search terms...\';" /> <input type="submit" value="Search" style="font-size:120%; font-weight:normal;" /></p>'."\n";
73
- echo '</form>'."\n";
74
 
75
- do_action("ws_plugin__s2member_during_logs_page_during_left_sections_during_help", get_defined_vars ());
76
- echo '</div>' . "\n";
77
- echo '</div>' . "\n";
78
 
79
- do_action("ws_plugin__s2member_during_logs_page_during_left_sections_after_help", get_defined_vars ());
80
- }
 
 
 
81
 
82
- if(apply_filters("ws_plugin__s2member_during_logs_page_during_left_sections_display_log_settings", true, get_defined_vars()))
83
- {
84
- do_action("ws_plugin__s2member_during_logs_page_during_left_sections_before_log_settings", get_defined_vars());
85
 
86
- echo '<div class="ws-menu-page-group" title="Logging Configuration">'."\n";
87
- echo '<div class="ws-menu-page-section ws-plugin--s2member-log-settings-section">'."\n";
88
 
89
- echo '<h3>Logging Configuration</h3>'."\n";
 
 
 
90
 
91
- echo '<div class="info">'."\n";
92
- echo '<p style="font-size:110%; margin-top:0;"><span>We HIGHLY recommend that you enable logging during your initial testing phase. Logs produce lots of useful details that can help in debugging. Logs can help you find issues in your configuration and/or problems that occur during processing. Enable logging here, and then view your log files below; in the s2Member Log Viewer.</span></p>'."\n";
93
- echo '<p style="font-size:110%; margin-bottom:0;"><span class="ws-menu-page-error">However, it is VERY IMPORTANT to disable logging once you go live. Log files may contain personally identifiable information, credit card numbers, secret API credentials, passwords and/or other sensitive information. We STRONGLY suggest that logging be disabled on a live site (for security reasons).</span></p>'."\n";
94
- echo '</div>'."\n";
95
 
96
- echo '<div class="notice" style="margin-bottom:0;">'."\n";
97
- echo '<p style="font-size:110%; margin-bottom:0;"><span>Regarding s2Member Security Badges. If debug logging is enabled, your site will NOT qualify for an s2Member Security Badge until you disable logging (and you must ALSO download, and then delete any existing log files). For further details, please see KB Article: <a href="http://www.s2member.com/kb/security-badges/" target="_blank" rel="external">s2Member Security Badges</a>.</span></p>'."\n";
98
- echo '</div>'."\n";
99
 
100
- echo '<div class="ws-menu-page-hr"></div>'."\n";
101
 
102
- do_action("ws_plugin__s2member_during_logs_page_during_left_sections_during_log_settings", get_defined_vars());
 
103
 
104
- echo '<form method="post" name="ws_plugin__s2member_options_form" id="ws-plugin--s2member-options-form">' . "\n";
105
- echo '<input type="hidden" name="ws_plugin__s2member_options_save" id="ws-plugin--s2member-options-save" value="' . esc_attr (wp_create_nonce ("ws-plugin--s2member-options-save")) . '" />' . "\n";
 
106
 
107
- echo '<table class="form-table">' . "\n";
108
- echo '<tbody>' . "\n";
109
- echo '<tr>' . "\n";
 
 
110
 
111
- echo '<th>'."\n";
112
- echo '<label for="ws-plugin--s2member-gateway-debug-logs">'."\n";
113
- echo 'Enable Logging Routines?'."\n";
114
- echo '</label>'."\n";
115
- echo '</th>'."\n";
116
 
117
- echo '</tr>'."\n";
118
- echo '<tr>'."\n";
 
 
 
119
 
120
- echo '<td>'."\n";
121
- echo '<input type="radio" name="ws_plugin__s2member_gateway_debug_logs" id="ws-plugin--s2member-gateway-debug-logs-0" value="0"'.((!$GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["gateway_debug_logs"]) ? ' checked="checked"' : '').' /> <label for="ws-plugin--s2member-gateway-debug-logs-0">No</label> &nbsp;&nbsp;&nbsp; <input type="radio" name="ws_plugin__s2member_gateway_debug_logs" id="ws-plugin--s2member-gateway-debug-logs-1" value="1"'.(($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["gateway_debug_logs"]) ? ' checked="checked"' : '').' /> <label for="ws-plugin--s2member-gateway-debug-logs-1">Yes, enable debugging w/ HTTP, API, IPN &amp; Return Page logging (and List Server API logs too).</label><br />'."\n";
122
- echo '<em>This enables logging overall. Includes s2Member HTTP, API, IPN and Return Page logging. Also logs any List Server integrations.</em><br />'."\n";
123
- echo '<em>* Use only for debugging. This should NEVER be enabled on a live site.<br />* The log files are stored here: <code>'.esc_html(c_ws_plugin__s2member_utils_dirs::doc_root_path($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["logs_dir"])).'</code></em>'."\n";
124
- echo '</td>'."\n";
125
 
126
- echo '</tr>'."\n";
127
- echo '<tr>' . "\n";
 
 
 
128
 
129
- echo '<th>'."\n";
130
- echo '<label for="ws-plugin--s2member-gateway-debug-logs-extensive">'."\n";
131
- echo 'Enable Additional Logging Routines?'."\n";
132
- echo '</label>'."\n";
133
- echo '</th>'."\n";
134
 
135
- echo '</tr>'."\n";
136
- echo '<tr>'."\n";
 
 
137
 
138
- echo '<td>'."\n";
139
- echo '<input type="radio" name="ws_plugin__s2member_gateway_debug_logs_extensive" id="ws-plugin--s2member-gateway-debug-logs-extensive-0" value="0"'.((!$GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["gateway_debug_logs_extensive"]) ? ' checked="checked"' : '').' /> <label for="ws-plugin--s2member-gateway-debug-logs-extensive-0">No</label> &nbsp;&nbsp;&nbsp; <input type="radio" name="ws_plugin__s2member_gateway_debug_logs_extensive" id="ws-plugin--s2member-gateway-debug-logs-extensive-1" value="1"'.(($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["gateway_debug_logs_extensive"]) ? ' checked="checked"' : '').' /> <label for="ws-plugin--s2member-gateway-debug-logs-extensive-1">Yes, enable debugging w/ HTTP connection logging for ALL of WordPress.</label><br />'."\n";
140
- echo '<em>This enables HTTP connection logging for ALL of WordPress (quite extensive).<br />* Use only for debugging. This should NEVER be enabled on a live site.<br />* Creates the additional log file: <code>wp-http-api-debug.log</code></em>'."\n";
141
- echo '</td>'."\n";
142
 
143
- echo '</tr>'."\n";
144
- echo '</tbody>' . "\n";
145
- echo '</table>' . "\n";
146
 
147
- echo '<p class="submit" style="margin-top:20px;">'."\n";
148
- echo '<input type="submit" value="Update Logging Configuration" />'."\n";
149
- echo '</p>' . "\n";
150
 
151
- echo '</form>'."\n";
 
152
 
153
- echo '</div>'."\n";
154
- echo '</div>'."\n";
 
 
 
155
 
156
- do_action("ws_plugin__s2member_during_logs_page_during_left_sections_after_log_settings", get_defined_vars());
157
- }
158
 
159
- if(apply_filters("ws_plugin__s2member_during_logs_page_during_left_sections_display_logs", true, get_defined_vars()))
160
- {
161
- do_action("ws_plugin__s2member_during_logs_page_during_left_sections_before_logs", get_defined_vars());
162
 
163
- echo '<div class="ws-menu-page-group" title="Logs Viewer" default-state="open">'."\n";
164
 
165
- echo '<div class="ws-menu-page-section ws-plugin--s2member-logs-section">'."\n";
166
- echo '<h3>Debugging Tools/Tips &amp; Other Important Details (<a href="#" onclick="jQuery(\'div#ws-plugin--s2member-debugging-tips-details\').toggle(); return false;" class="ws-dotted-link">click here to toggle</a>)</h3>'."\n";
167
 
168
- echo '<div id="ws-plugin--s2member-debugging-tips-details" style="display:none;">'."\n";
 
 
 
169
 
170
- echo '<div class="ws-menu-page-hr"></div>' . "\n";
 
 
 
171
 
172
- echo '<form method="post" onsubmit="if(!confirm(\'Archive all existing log files?\n\nAll of your current log files will be archived (e.g. they will simply be renamed with an ARCHIVED tag &amp; date in their file name); and new log files will be created automatically the next time s2Member logs something on your installation.\n\nPlease click OK to confirm this action.\')) return false;">'."\n";
173
- echo '<input type="hidden" name="ws_plugin__s2member_logs_archive_start_fresh" value="'.esc_attr(wp_create_nonce ("ws-plugin--s2member-logs-archive-start-fresh")).'" />'."\n";
174
- echo '<input type="submit" value="Archive All Current Log Files" class="ws-menu-page-right ws-plugin--s2member-archive-logs-start-fresh-button" style="font-size:110%; font-weight:normal; clear:right; min-width:200px;" />'."\n";
175
- echo '</form>'."\n";
176
 
177
- echo '<form method="post" onsubmit="if(!confirm(\'Delete all existing log files?\n\nThis will permanently delete ALL of your existing log files (including any archived log files).\n\nPlease click OK to confirm this action.\')) return false;">'."\n";
178
- echo '<input type="hidden" name="ws_plugin__s2member_logs_delete_start_fresh" value="'.esc_attr(wp_create_nonce ("ws-plugin--s2member-logs-delete-start-fresh")).'" />'."\n";
179
- echo '<input type="submit" value="Permanently Delete All Log Files" class="ws-menu-page-right ws-plugin--s2member-delete-logs-start-fresh-button" style="font-size:110%; font-weight:normal; clear:right; min-width:200px;" />'."\n";
180
- echo '</form>'."\n";
 
181
 
182
- echo '<form method="post">'."\n";
183
- echo '<input type="hidden" name="ws_plugin__s2member_logs_download_zip" value="'.esc_attr(wp_create_nonce ("ws-plugin--s2member-logs-download-zip")).'" />'."\n";
184
- echo '<input type="submit" value="Download All Log Files (Zip File)" class="ws-menu-page-right ws-plugin--s2member-logs-download-zip-button" style="font-size:110%; font-weight:normal; clear:right; min-width:200px;" />'."\n";
185
- echo '</form>'."\n";
186
 
187
- echo '<p><strong>Debugging Tips:</strong> &nbsp;&nbsp; It is normal to see a few errors in your log files. This is because s2Member logs ALL of its communication with Payment Gateways. Everything — not just successes. With that in mind, there will be some failures that s2Member expects (to a certain extent); and s2Member deals with these gracefully. What you\'re looking for here, are things that jump right out at you as being a major issue (e.g. when s2Member makes a point of providing details to you in a log entry about problems that should be corrected on your installation). Please read carefully.</p>'."\n";
188
- echo '<p><strong>Test Transaction Tips:</strong> &nbsp;&nbsp; Generally speaking, it is best to run test transactions for yourself. Be sure to run your final test transactions against a live Payment Gateway that is NOT in Sandbox/Test Mode (<a href="#" onclick="alert(\'While some Payment Gateways make it possible for you to run test transactions in Sandbox/Test Mode, these are NOT a reliable way to test s2Member.\n\nOften times (particularly with PayPal) Sandbox/Test mode behaves somewhat differently — often with buggy behavior. This can really create frustration for site owners. Therefore, it is always a good idea to run low dollar test transactions against a live Payment Gateway.\n\nAlso, please be sure that you are NOT logged in as an Administrator when running test transactions. For most test transactions, you will want to be completely logged out of your site before completing checkout (just a new Customer would be). If you are testing an upgrade or downgrade (where you DO need to be logged-in), please do NOT attempt this under an Administrative account. s2Member will NOT upgrade/downgrade Administrative accounts — for security purposes.\'); return false;">click here for details</a>). After running test transactions, please review the log file entries pertaining to your transaction. Does s2Member report any major issues? If so, please read through any details that s2Member provides in the log file. If you need assistance, please <a href="http://www.s2member.com/quick-s.php" target="_blank" rel="external">search s2Member.com</a> for answers to common questions.</p>'."\n";
189
- echo '<p><strong>s2 Core Processors:</strong> &nbsp;&nbsp; It is normal to have a <code>paypay-ipn.log</code> and/or a <code>paypay-rtn.log</code> file at all times. Ultimately, all Payment Gateway integrations supported by s2Member pass through it\'s core PayPal processors; even if you\'ve integrated with another Payment Gateway. If you are having trouble, and you don\'t find any errors in your Payment Gateway log files, please check the <code>paypay-ipn.log</code> and <code>paypay-rtn.log</code> files too. Regarding s2Member Pro Forms... If you\'ve integrated s2Member Pro Forms, you will NOT have a <code>paypay-rtn.log</code> file, because that particular processor is not used with Pro Form integrations. However, you will have a <code>paypay-ipn.log</code> file, and you will need to make a point of inspecting this file to ensure there were no post-processing issues.</p>'."\n";
190
- echo '<p><strong>s2 HTTP API Logs:</strong> &nbsp;&nbsp; If s2Member is not behaving as expected, and you cannot find errors anywhere in your Payment Gateway log files (or with any core PayPal processors), please review your <code>s2-http-api-debug.log</code> file too. Look for any HTTP connections where s2Member is getting <code>403</code>, <code>404</code>, <code>503</code> errors from your server. This can sometimes happen due to <a href="http://www.s2member.com/kb/mod-security-random-503-403-errors/" target="_blank" rel="external">paranoid Mod Security configurations</a>, and it may require you to contact your hosting company for assistance.</p>'."\n";
191
- echo '<p style="font-style:italic;"><strong>Archived Log Files:</strong> &nbsp;&nbsp; All s2Member log files are stored here: <code>'.esc_html(c_ws_plugin__s2member_utils_dirs::doc_root_path($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["logs_dir"])).'</code>. Any log files that contain the word <code>ARCHIVED</code> in their name, are files that reached a size of more than 2MB, so s2Member archived them automatically to prevent any single log file from becoming too large. Archived log file names will also contain the date/time they were archived by s2Member. These archived log files typically contain much older (and possibly outdated) log entries.</p>'."\n";
192
 
193
- echo '<div class="ws-menu-page-hr"></div>' . "\n";
194
 
195
- echo '<h3>s2Member Log File Descriptions (for ALL possible log file names)</h3>'."\n";
 
 
 
 
196
 
197
- echo '<div class="ws-menu-page-hr"></div>' . "\n";
198
 
199
- echo '<ul class="ws-menu-page-li-margins">'."\n";
200
- foreach(c_ws_plugin__s2member_utils_logs::$log_file_descriptions as $_k => $_v)
201
- echo '<li style="font-family:\'Georgia\', serif;"><code><strong>'.esc_html(preg_replace('/^\/|\/$/', '', $_k)).'.log</strong></code> &nbsp;&nbsp; '.esc_html($_v["long"]).'</li>'."\n";
202
- unset($_k, $_v); // Housekeeping.
203
- echo '</ul>'."\n";
204
 
205
- echo '<div class="ws-menu-page-hr"></div>' . "\n";
206
 
207
- echo '</div>'."\n";
 
 
208
 
209
- do_action("ws_plugin__s2member_during_logs_page_during_left_sections_during_logs", get_defined_vars());
 
 
 
210
 
211
- $log_file_options = ""; // Initialize to an empty string.
212
- $view_log_file = (!empty($_POST["ws_plugin__s2member_log_file"])) ? esc_html($_POST["ws_plugin__s2member_log_file"]) : "";
213
- $logs_dir = $GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["logs_dir"];
 
214
 
215
- if(is_dir($logs_dir)) // Do we have a logs directory on this installation?
 
216
  {
217
- $log_files = scandir($logs_dir); sort($log_files, SORT_STRING);
218
-
219
- $log_file_options .= '<optgroup label="Current Log Files">';
220
- foreach($log_files as $_log_file) // Build options for each current log file.
221
- {
222
- $_log_file_description = array("short" => "No description available.", "long" => "No description available.");
223
-
224
- foreach(c_ws_plugin__s2member_utils_logs::$log_file_descriptions as $_k => $_v)
225
- if(preg_match($_k, $_log_file))
226
- {
227
- $_log_file_description = $_v;
228
- break; // Stop here.
229
- }
230
- unset($_k, $_v); // Housekeeping.
231
-
232
- if(preg_match("/\.log$/", $_log_file) && stripos($_log_file, "-ARCHIVED-") === FALSE)
233
- $log_file_options .= '<option data-type="current" title="'.esc_attr($_log_file_description["long"]).'" value="'.esc_attr($_log_file).'"'.(($view_log_file === $_log_file) ? ' style="font-weight:bold;" selected="selected"' : '').'>'.esc_html($_log_file).' — '.esc_html($_log_file_description["short"]).'</option>';
234
- }
235
- unset($_log_file_description, $_log_file); // Housekeeping.
236
- $log_file_options .= '</optgroup>';
237
-
238
- if(stripos($log_file_options, '<option data-type="current"') === FALSE)
239
- $log_file_options .= '<option value="" disabled="disabled">— No current log files yet. —</option>';
240
-
241
- $log_file_options .= '<option value="" disabled="disabled"></option>';
242
-
243
- $log_file_options .= '<optgroup label="Archived Log Files">';
244
- foreach($log_files as $_log_file) // Build options for each ARCHIVED log file.
245
- {
246
- if(preg_match("/\.log$/", $_log_file) && stripos($_log_file, "-ARCHIVED-") !== FALSE)
247
- $log_file_options .= '<option data-type="archived" value="'.esc_attr($_log_file).'"'.(($view_log_file === $_log_file) ? ' style="font-weight:bold;" selected="selected"' : '').'>'.esc_html($_log_file).'</option>';
248
- }
249
- $log_file_options .= '</optgroup>';
250
-
251
- if(stripos($log_file_options, '<option data-type="archived"') === FALSE)
252
- $log_file_options .= '<option value="" disabled="disabled">— No log files archived yet. —</option>';
253
  }
254
- $log_file_options = '<option value="">— Choose a Log File to View —</option>'.
255
- '<option value="" disabled="disabled"></option>'.
256
- $log_file_options;
257
 
258
- echo '<form method="post" name="ws_plugin__s2member_log_viewer" id="ws-plugin--s2member-log-viewer">' . "\n";
 
 
 
 
259
 
260
- echo '<table class="form-table">' . "\n";
261
- echo '<tbody>' . "\n";
262
- echo '<tr>' . "\n";
263
 
264
- echo '<td style="width:80%;">' . "\n";
265
- echo '<select name="ws_plugin__s2member_log_file" id="ws-plugin--s2member-log-file">' . "\n";
266
- echo $log_file_options."\n";
267
- echo '</select>' . "\n";
268
- echo '</td>' . "\n";
269
 
270
- echo '<td style="width:20%; padding-left:5px;">' . "\n";
271
- echo '<input type="submit" value="View" style="font-size:120%; font-weight:normal;" />'."\n";
272
- echo '</td>' . "\n";
 
 
 
 
273
 
274
- echo '</tr>' . "\n";
275
- echo '</tbody>' . "\n";
276
- echo '</table>' . "\n";
 
 
 
277
 
278
- echo '<table class="form-table">' . "\n";
279
- echo '<tbody>' . "\n";
280
- echo '<tr>' . "\n";
281
 
282
- echo '<td>' . "\n";
 
 
283
 
284
- if($view_log_file && file_exists($logs_dir."/".$view_log_file) && filesize($logs_dir."/".$view_log_file))
285
- {
286
- $_log_file_description = array("short" => "", "long" => "");
 
 
287
 
288
- foreach(c_ws_plugin__s2member_utils_logs::$log_file_descriptions as $_k => $_v)
289
- if(preg_match($_k, $view_log_file))
290
- {
291
- $_log_file_description = $_v;
292
- break; // Stop here.
293
- }
294
- unset($_k, $_v); // Housekeeping.
295
 
296
- if(!empty($_log_file_description["long"])) // Do we have a description that we can display here?
297
- echo '<p style="clear:both; width:80%; font-family:\'Georgia\', serif; font-style:italic;"><strong>Description for <a href="'.esc_attr(add_query_arg(array("ws_plugin__s2member_download_log_file" => $view_log_file, "ws_plugin__s2member_download_log_file_v" => wp_create_nonce ("ws-plugin--s2member-download-log-file-v")))).'">'.esc_html($view_log_file).'</a></strong>: '.esc_html($_log_file_description["long"]).'</p>'."\n";
298
- unset($_log_file_description); // Just a little housekeeping here.
299
 
300
- echo '<p style="float:left; text-align:left;"><strong>Viewing:</strong> <a href="'.esc_attr(add_query_arg(array("ws_plugin__s2member_download_log_file" => $view_log_file, "ws_plugin__s2member_download_log_file_v" => wp_create_nonce ("ws-plugin--s2member-download-log-file-v")))).'">'.esc_html($view_log_file).'</a> (log entries oldest to newest)</p>'."\n";
301
- echo '<p style="float:right; text-align:right;">[ <a href="'.esc_attr(add_query_arg(array("ws_plugin__s2member_download_log_file" => $view_log_file, "ws_plugin__s2member_download_log_file_v" => wp_create_nonce ("ws-plugin--s2member-download-log-file-v")))).'"><strong>download file</strong></a> ]</p>'."\n";
302
- echo '<p style="margin-right:10px; float:right; text-align:right;"><a href="#" class="ws-plugin--s2member-log-file-viewport-toggle" style="text-decoration:none;">&#8659; expand viewport &#8659;</a></p>'."\n";
303
 
304
- echo '<textarea id="ws-plugin--s2member-log-file-viewer" rows="20" wrap="on" spellcheck="false" style="box-shadow:inset 0 0 5px rgba(0,0,0,0.5); background:#EEEEEE; color:#000000; overflow-y:scroll;" class="monospace">'.htmlspecialchars(file_get_contents($logs_dir."/".$view_log_file)).'</textarea>' . "\n";
305
 
306
- echo '<p style="float:left; text-align:left;"><strong>Viewing:</strong> <a href="'.esc_attr(add_query_arg(array("ws_plugin__s2member_download_log_file" => $view_log_file, "ws_plugin__s2member_download_log_file_v" => wp_create_nonce ("ws-plugin--s2member-download-log-file-v")))).'">'.esc_html($view_log_file).'</a> (log entries oldest to newest)</p>'."\n";
307
- echo '<p style="float:right; text-align:right;">[ <a href="'.esc_attr(add_query_arg(array("ws_plugin__s2member_download_log_file" => $view_log_file, "ws_plugin__s2member_download_log_file_v" => wp_create_nonce ("ws-plugin--s2member-download-log-file-v")))).'"><strong>download file</strong></a> ]</p>'."\n";
308
- echo '<p style="margin-right:10px; float:right; text-align:right;"><a href="#" class="ws-plugin--s2member-log-file-viewport-toggle" style="text-decoration:none;">&#8659; expand viewport &#8659;</a></p>'."\n";
309
- }
310
- else if($view_log_file && file_exists($logs_dir."/".$view_log_file))
311
- echo '<textarea id="ws-plugin--s2member-log-file-viewer" rows="20" wrap="on" spellcheck="false" style="box-shadow:inset 0 0 5px rgba(0,0,0,0.5); background:#EEEEEE; color:#000000; overflow-y:scroll; font-style:italic;" class="monospace">— Empty at this time —</textarea>' . "\n";
312
 
313
- else if($view_log_file && !file_exists($logs_dir."/".$view_log_file))
314
- echo '<textarea id="ws-plugin--s2member-log-file-viewer" rows="20" wrap="on" spellcheck="false" style="box-shadow:inset 0 0 5px rgba(0,0,0,0.5); background:#EEEEEE; color:#000000; overflow-y:scroll; font-style:italic;" class="monospace">— File no longer exists —</textarea>' . "\n";
 
 
 
 
 
315
 
316
- else // Display an empty textarea in this default scenario.
317
- echo '<textarea id="ws-plugin--s2member-log-file-viewer" rows="20" wrap="on" spellcheck="false" style="box-shadow:inset 0 0 5px rgba(0,0,0,0.5); background:#EEEEEE; color:#000000; overflow-y:scroll; font-style:italic;" class="monospace"></textarea>' . "\n";
 
318
 
319
- echo '</td>' . "\n";
 
 
320
 
321
- echo '</tr>' . "\n";
322
- echo '</tbody>' . "\n";
323
- echo '</table>' . "\n";
324
 
325
- echo '</form>'."\n";
 
 
 
 
 
326
 
327
- echo '</div>'."\n";
328
- echo '</div>'."\n";
329
 
330
- do_action("ws_plugin__s2member_during_logs_page_during_left_sections_after_logs", get_defined_vars());
331
- }
332
 
333
- do_action("ws_plugin__s2member_during_logs_page_after_left_sections", get_defined_vars());
334
 
335
- echo '</td>'."\n";
 
 
336
 
337
- echo '<td class="ws-menu-page-table-r">'."\n";
338
- c_ws_plugin__s2member_menu_pages_rs::display();
339
- echo '</td>'."\n";
340
 
341
- echo '</tr>'."\n";
342
- echo '</tbody>'."\n";
343
- echo '</table>'."\n";
344
 
345
- echo '</div>'."\n";
346
- }
347
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
348
  }
 
349
 
350
- new c_ws_plugin__s2member_menu_page_logs();
351
- ?>
1
  <?php
2
  /**
3
+ * Menu page for the s2Member plugin (Logs page).
4
+ *
5
+ * Copyright: © 2009-2011
6
+ * {@link http://www.websharks-inc.com/ WebSharks, Inc.}
7
+ * (coded in the USA)
8
+ *
9
+ * Released under the terms of the GNU General Public License.
10
+ * You should have received a copy of the GNU General Public License,
11
+ * along with this software. In the main directory, see: /licensing/
12
+ * If not, see: {@link http://www.gnu.org/licenses/}.
13
+ *
14
+ * @package s2Member\Menu_Pages
15
+ * @since 130210
16
+ */
17
  if(realpath(__FILE__) === realpath($_SERVER["SCRIPT_FILENAME"]))
18
  exit("Do not access this file directly.");
19
 
20
  if(!class_exists("c_ws_plugin__s2member_menu_page_logs"))
21
+ {
22
+ /**
23
+ * Menu page for the s2Member plugin (Integrations page).
24
+ *
25
+ * @package s2Member\Menu_Pages
26
+ * @since 110531
27
+ */
28
+ class c_ws_plugin__s2member_menu_page_logs
29
  {
30
+ public function __construct()
31
+ {
32
+ echo '<div class="wrap ws-menu-page">'."\n";
 
 
 
 
 
 
 
 
33
 
34
+ echo '<div class="ws-menu-page-toolbox">'."\n";
35
+ c_ws_plugin__s2member_menu_pages_tb::display();
36
+ echo '</div>'."\n";
37
 
38
+ echo '<h2>Log Files</h2>'."\n";
39
 
40
+ echo '<table class="ws-menu-page-table">'."\n";
41
+ echo '<tbody class="ws-menu-page-table-tbody">'."\n";
42
+ echo '<tr class="ws-menu-page-table-tr">'."\n";
43
+ echo '<td class="ws-menu-page-table-l">'."\n";
44
 
45
+ do_action("ws_plugin__s2member_during_logs_page_before_left_sections", get_defined_vars());
46
 
47
+ if(apply_filters("ws_plugin__s2member_during_logs_page_during_left_sections_display_help", TRUE, get_defined_vars()))
48
+ {
49
+ do_action("ws_plugin__s2member_during_logs_page_during_left_sections_before_help", get_defined_vars());
50
 
51
+ echo '<div class="ws-menu-page-group" title="Getting Help">'."\n";
52
 
53
+ echo '<div class="ws-menu-page-section ws-plugin--s2member-help">'."\n";
54
+ echo '<h3>Getting Help w/ s2Member (Troubleshooting)</h3>'."\n";
55
+ echo '<p>s2Member is pretty easy to setup and install initially. Most of the official documentation is right here in your Dashboard (i.e. there is a lot of inline documentation built into the software). That being said, it CAN take some time to master everything there is to know about s2Member\'s advanced features. If you need assistance with s2Member, please search the <a href="http://www.s2member.com/kb/" target="_blank" rel="external">s2Member Knowledge Base</a>, <a href="http://www.s2member.com/videos/" target="_blank" rel="external">Video Tutorials</a>, <a href="http://www.s2member.com/forums/" target="_blank" rel="external">Forums</a> and <a href="http://www.s2member.com/codex/" target="_blank" rel="external">Codex</a>. If you are planning to do something creative with s2Member, you might want to <a href="http://jobs.wordpress.net" target="_blank" rel="external">hire a freelance developer</a> to assist you.</p>'."\n";
56
+ echo '<p><strong>See also:</strong> <a href="http://www.s2member.com/kb/common-troubleshooting-tips/" target="_blank" rel="external">s2Member Troubleshooting Guide</a> (please read this first if you\'re having trouble).</p>'."\n";
57
 
58
+ echo '<div class="ws-menu-page-hr"></div>'."\n";
59
 
60
+ echo '<h3>Testing Server Compatibility</h3>'."\n";
61
+ echo '<p>Please download the <a href="http://www.s2member.com/r/server-check-tool/">s2Member Server Scanner</a>. Unzip, upload via FTP; then open in a browser for a full report.</p>'."\n";
62
 
63
+ echo '<div class="ws-menu-page-hr"></div>'."\n";
64
 
65
+ echo '<h3>Troubleshooting Payment Gateway Integrations</h3>'."\n";
66
+ echo '<p>Please use the s2Member Log Viewer (below). Log files can be very helpful.</p>'."\n";
67
 
68
+ echo '<div class="ws-menu-page-hr"></div>'."\n";
69
 
70
+ echo '<h3>Search s2Member KB Articles, Forums, Codex and more<em>!</em></h3>'."\n";
71
+ echo '<form method="get" action="http://www.s2member.com/quick-s.php" target="_blank" onsubmit="if(this.q.value === \'enter search terms...\') this.q.value = \'\';">'."\n";
72
+ echo '<p><input type="text" name="q" value="enter search terms..." style="width:60%;" onfocus="if(this.value === \'enter search terms...\') this.value = \'\';" onblur="if(this.value === \'\') this.value = \'enter search terms...\';" /> <input type="submit" value="Search" style="font-size:120%; font-weight:normal;" /></p>'."\n";
73
+ echo '</form>'."\n";
74
 
75
+ do_action("ws_plugin__s2member_during_logs_page_during_left_sections_during_help", get_defined_vars());
76
+ echo '</div>'."\n";
77
+ echo '</div>'."\n";
78
 
79
+ do_action("ws_plugin__s2member_during_logs_page_during_left_sections_after_help", get_defined_vars());
80
+ }
81
+ if(apply_filters("ws_plugin__s2member_during_logs_page_during_left_sections_display_log_settings", TRUE, get_defined_vars()))
82
+ {
83
+ do_action("ws_plugin__s2member_during_logs_page_during_left_sections_before_log_settings", get_defined_vars());
84
 
85
+ echo '<div class="ws-menu-page-group" title="Logging Configuration">'."\n";
86
+ echo '<div class="ws-menu-page-section ws-plugin--s2member-log-settings-section">'."\n";
 
87
 
88
+ echo '<h3>Logging Configuration</h3>'."\n";
 
89
 
90
+ echo '<div class="info">'."\n";
91
+ echo '<p style="font-size:110%; margin-top:0;"><span>We HIGHLY recommend that you enable logging during your initial testing phase. Logs produce lots of useful details that can help in debugging. Logs can help you find issues in your configuration and/or problems that occur during processing. Enable logging here, and then view your log files below, in the s2Member Log Viewer.</span></p>'."\n";
92
+ echo '<p style="font-size:110%; margin-bottom:0;"><span class="ws-menu-page-error">However, it is VERY IMPORTANT to disable logging once you go live. Log files may contain personally identifiable information, credit card numbers, secret API credentials, passwords and/or other sensitive information. We STRONGLY suggest that logging be disabled on a live site (for security reasons).</span></p>'."\n";
93
+ echo '</div>'."\n";
94
 
95
+ echo '<div class="notice" style="margin-bottom:0;">'."\n";
96
+ echo '<p style="font-size:110%; margin-bottom:0;"><span>Regarding s2Member Security Badges. If debug logging is enabled, your site will NOT qualify for an s2Member Security Badge until you disable logging (and you must ALSO download, and then delete any existing log files). For further details, please see KB Article: <a href="http://www.s2member.com/kb/security-badges/" target="_blank" rel="external">s2Member Security Badges</a>.</span></p>'."\n";
97
+ echo '</div>'."\n";
 
98
 
99
+ echo '<div class="ws-menu-page-hr"></div>'."\n";
 
 
100
 
101
+ do_action("ws_plugin__s2member_during_logs_page_during_left_sections_during_log_settings", get_defined_vars());
102
 
103
+ echo '<form method="post" name="ws_plugin__s2member_options_form" id="ws-plugin--s2member-options-form">'."\n";
104
+ echo '<input type="hidden" name="ws_plugin__s2member_options_save" id="ws-plugin--s2member-options-save" value="'.esc_attr(wp_create_nonce("ws-plugin--s2member-options-save")).'" />'."\n";
105
 
106
+ echo '<table class="form-table">'."\n";
107
+ echo '<tbody>'."\n";
108
+ echo '<tr>'."\n";
109
 
110
+ echo '<th>'."\n";
111
+ echo '<label for="ws-plugin--s2member-gateway-debug-logs">'."\n";
112
+ echo 'Enable Logging Routines?'."\n";
113
+ echo '</label>'."\n";
114
+ echo '</th>'."\n";
115
 
116
+ echo '</tr>'."\n";
117
+ echo '<tr>'."\n";
 
 
 
118
 
119
+ echo '<td>'."\n";
120
+ echo '<input type="radio" name="ws_plugin__s2member_gateway_debug_logs" id="ws-plugin--s2member-gateway-debug-logs-0" value="0"'.((!$GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["gateway_debug_logs"]) ? ' checked="checked"' : '').' /> <label for="ws-plugin--s2member-gateway-debug-logs-0">No</label> &nbsp;&nbsp;&nbsp; <input type="radio" name="ws_plugin__s2member_gateway_debug_logs" id="ws-plugin--s2member-gateway-debug-logs-1" value="1"'.(($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["gateway_debug_logs"]) ? ' checked="checked"' : '').' /> <label for="ws-plugin--s2member-gateway-debug-logs-1">Yes, enable debugging w/ HTTP, API, IPN &amp; Return Page logging (and List Server API logs too).</label><br />'."\n";
121
+ echo '<em>This enables logging overall. Includes s2Member HTTP, API, IPN and Return Page logging. Also logs any List Server integrations.</em><br />'."\n";
122
+ echo '<em>* Use only for debugging. This should NEVER be enabled on a live site.<br />* The log files are stored here: <code>'.esc_html(c_ws_plugin__s2member_utils_dirs::doc_root_path($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["logs_dir"])).'</code></em>'."\n";
123
+ echo '</td>'."\n";
124
 
125
+ echo '</tr>'."\n";
126
+ echo '<tr>'."\n";
 
 
 
127
 
128
+ echo '<th>'."\n";
129
+ echo '<label for="ws-plugin--s2member-gateway-debug-logs-extensive">'."\n";
130
+ echo 'Enable Additional Logging Routines?'."\n";
131
+ echo '</label>'."\n";
132
+ echo '</th>'."\n";
133
 
134
+ echo '</tr>'."\n";
135
+ echo '<tr>'."\n";
 
 
 
136
 
137
+ echo '<td>'."\n";
138
+ echo '<input type="radio" name="ws_plugin__s2member_gateway_debug_logs_extensive" id="ws-plugin--s2member-gateway-debug-logs-extensive-0" value="0"'.((!$GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["gateway_debug_logs_extensive"]) ? ' checked="checked"' : '').' /> <label for="ws-plugin--s2member-gateway-debug-logs-extensive-0">No</label> &nbsp;&nbsp;&nbsp; <input type="radio" name="ws_plugin__s2member_gateway_debug_logs_extensive" id="ws-plugin--s2member-gateway-debug-logs-extensive-1" value="1"'.(($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["gateway_debug_logs_extensive"]) ? ' checked="checked"' : '').' /> <label for="ws-plugin--s2member-gateway-debug-logs-extensive-1">Yes, enable debugging w/ HTTP connection logging for ALL of WordPress.</label><br />'."\n";
139
+ echo '<em>This enables HTTP connection logging for ALL of WordPress (quite extensive).<br />* Use only for debugging. This should NEVER be enabled on a live site.<br />* Creates the additional log file: <code>wp-http-api-debug.log</code></em>'."\n";
140
+ echo '</td>'."\n";
141
 
142
+ echo '</tr>'."\n";
143
+ echo '</tbody>'."\n";
144
+ echo '</table>'."\n";
 
145
 
146
+ echo '<p class="submit" style="margin-top:20px;">'."\n";
147
+ echo '<input type="submit" value="Update Logging Configuration" />'."\n";
148
+ echo '</p>'."\n";
149
 
150
+ echo '</form>'."\n";
 
 
151
 
152
+ echo '</div>'."\n";
153
+ echo '</div>'."\n";
154
 
155
+ do_action("ws_plugin__s2member_during_logs_page_during_left_sections_after_log_settings", get_defined_vars());
156
+ }
157
+ if(apply_filters("ws_plugin__s2member_during_logs_page_during_left_sections_display_logs", TRUE, get_defined_vars()))
158
+ {
159
+ do_action("ws_plugin__s2member_during_logs_page_during_left_sections_before_logs", get_defined_vars());
160
 
161
+ echo '<div class="ws-menu-page-group" title="Logs Viewer" default-state="open">'."\n";
 
162
 
163
+ echo '<div class="ws-menu-page-section ws-plugin--s2member-logs-section">'."\n";
164
+ echo '<h3>Debugging Tools/Tips &amp; Other Important Details (<a href="#" onclick="jQuery(\'div#ws-plugin--s2member-debugging-tips-details\').toggle(); return false;" class="ws-dotted-link">click here to toggle</a>)</h3>'."\n";
 
165
 
166
+ echo '<div id="ws-plugin--s2member-debugging-tips-details" style="display:none;">'."\n";
167
 
168
+ echo '<div class="ws-menu-page-hr"></div>'."\n";
 
169
 
170
+ echo '<form method="post" onsubmit="if(!confirm(\'Archive all existing log files?\n\nAll of your current log files will be archived (e.g. they will simply be renamed with an ARCHIVED tag &amp; date in their file name); and new log files will be created automatically the next time s2Member logs something on your installation.\n\nPlease click OK to confirm this action.\')) return false;">'."\n";
171
+ echo '<input type="hidden" name="ws_plugin__s2member_logs_archive_start_fresh" value="'.esc_attr(wp_create_nonce("ws-plugin--s2member-logs-archive-start-fresh")).'" />'."\n";
172
+ echo '<input type="submit" value="Archive All Current Log Files" class="ws-menu-page-right ws-plugin--s2member-archive-logs-start-fresh-button" style="font-size:110%; font-weight:normal; clear:right; min-width:200px;" />'."\n";
173
+ echo '</form>'."\n";
174
 
175
+ echo '<form method="post" onsubmit="if(!confirm(\'Delete all existing log files?\n\nThis will permanently delete ALL of your existing log files (including any archived log files).\n\nPlease click OK to confirm this action.\')) return false;">'."\n";
176
+ echo '<input type="hidden" name="ws_plugin__s2member_logs_delete_start_fresh" value="'.esc_attr(wp_create_nonce("ws-plugin--s2member-logs-delete-start-fresh")).'" />'."\n";
177
+ echo '<input type="submit" value="Permanently Delete All Log Files" class="ws-menu-page-right ws-plugin--s2member-delete-logs-start-fresh-button" style="font-size:110%; font-weight:normal; clear:right; min-width:200px;" />'."\n";
178
+ echo '</form>'."\n";
179
 
180
+ echo '<form method="post">'."\n";
181
+ echo '<input type="hidden" name="ws_plugin__s2member_logs_download_zip" value="'.esc_attr(wp_create_nonce("ws-plugin--s2member-logs-download-zip")).'" />'."\n";
182
+ echo '<input type="submit" value="Download All Log Files (Zip File)" class="ws-menu-page-right ws-plugin--s2member-logs-download-zip-button" style="font-size:110%; font-weight:normal; clear:right; min-width:200px;" />'."\n";
183
+ echo '</form>'."\n";
184
 
185
+ echo '<p><strong>Debugging Tips:</strong> &nbsp;&nbsp; It is normal to see a few errors in your log files. This is because s2Member logs ALL of its communication with Payment Gateways. Everything — not just successes. With that in mind, there will be some failures that s2Member expects (to a certain extent); and s2Member deals with these gracefully. What you\'re looking for here, are things that jump right out at you as being a major issue (e.g. when s2Member makes a point of providing details to you in a log entry about problems that should be corrected on your installation). Please read carefully.</p>'."\n";
186
+ echo '<p><strong>Test Transaction Tips:</strong> &nbsp;&nbsp; Generally speaking, it is best to run test transactions for yourself. Be sure to run your final test transactions against a live Payment Gateway that is NOT in Sandbox/Test Mode (<a href="#" onclick="alert(\'While some Payment Gateways make it possible for you to run test transactions in Sandbox/Test Mode, these are NOT a reliable way to test s2Member.\n\nOften times (particularly with PayPal) Sandbox/Test mode behaves somewhat differently — often with buggy behavior. This can really create frustration for site owners. Therefore, it is always a good idea to run low-dollar test transactions against a live Payment Gateway.\n\nAlso, please be sure that you are NOT logged in as an Administrator when running test transactions. For most test transactions, you will want to be completely logged out of your site before completing checkout (just like a new Customer would be). If you are testing an upgrade or downgrade (where you DO need to be logged-in), please do NOT attempt this under an Administrative account. s2Member will NOT upgrade/downgrade Administrative accounts — for security purposes.\'); return false;">click here for details</a>). After running test transactions, please review the log file entries pertaining to your transaction. Does s2Member report any major issues? If so, please read through any details that s2Member provides in the log file. If you need assistance, please <a href="http://www.s2member.com/quick-s.php" target="_blank" rel="external">search s2Member.com</a> for answers to common questions.</p>'."\n";
187
+ echo '<p><strong>s2 Core Processors:</strong> &nbsp;&nbsp; It is normal to have a <code>paypay-ipn.log</code> and/or a <code>paypay-rtn.log</code> file at all times. Ultimately, all Payment Gateway integrations supported by s2Member pass through it\'s core PayPal processors; even if you\'ve integrated with another Payment Gateway. If you are having trouble, and you don\'t find any errors in your Payment Gateway log files, please check the <code>paypay-ipn.log</code> and <code>paypay-rtn.log</code> files too. Regarding s2Member Pro Forms... If you\'ve integrated s2Member Pro Forms, you will NOT have a <code>paypay-rtn.log</code> file, because that particular processor is not used with Pro Form integrations. However, you will have a <code>paypay-ipn.log</code> file, and you will need to make a point of inspecting this file to ensure there were no post-processing issues.</p>'."\n";
188
+ echo '<p><strong>s2 HTTP API Logs:</strong> &nbsp;&nbsp; If s2Member is not behaving as expected, and you cannot find errors anywhere in your Payment Gateway log files (or with any core PayPal processors), please review your <code>s2-http-api-debug.log</code> file too. Look for any HTTP connections where s2Member is getting <code>403</code>, <code>404</code>, <code>503</code> errors from your server. This can sometimes happen due to <a href="http://www.s2member.com/kb/mod-security-random-503-403-errors/" target="_blank" rel="external">paranoid Mod Security configurations</a>, and it may require you to contact your hosting company for assistance.</p>'."\n";
189
+ echo '<p style="font-style:italic;"><strong>Archived Log Files:</strong> &nbsp;&nbsp; All s2Member log files are stored here: <code>'.esc_html(c_ws_plugin__s2member_utils_dirs::doc_root_path($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["logs_dir"])).'</code>. Any log files that contain the word <code>ARCHIVED</code> in their name, are files that reached a size of more than 2MB, so s2Member archived them automatically to prevent any single log file from becoming too large. Archived log file names will also contain the date/time they were archived by s2Member. These archived log files typically contain much older (and possibly outdated) log entries.</p>'."\n";
190
 
191
+ echo '<div class="ws-menu-page-hr"></div>'."\n";
 
 
 
192
 
193
+ echo '<h3>s2Member Log File Descriptions (for ALL possible log file names)</h3>'."\n";
 
 
 
 
194
 
195
+ echo '<div class="ws-menu-page-hr"></div>'."\n";
196
 
197
+ echo '<ul class="ws-menu-page-li-margins">'."\n";
198
+ foreach(c_ws_plugin__s2member_utils_logs::$log_file_descriptions as $_k => $_v)
199
+ echo '<li><code><strong>'.esc_html(preg_replace(array('/^\/|\/$/', '/\\\\+/'), '', $_k)).'.log</strong></code> &nbsp;&nbsp; '.esc_html($_v["long"]).'</li>'."\n";
200
+ unset($_k, $_v); // Housekeeping.
201
+ echo '</ul>'."\n";
202
 
203
+ echo '<div class="ws-menu-page-hr"></div>'."\n";
204
 
205
+ echo '</div>'."\n";
 
 
 
 
206
 
207
+ do_action("ws_plugin__s2member_during_logs_page_during_left_sections_during_logs", get_defined_vars());
208
 
209
+ $log_file_options = ""; // Initialize to an empty string.
210
+ $view_log_file = (!empty($_POST["ws_plugin__s2member_log_file"])) ? esc_html($_POST["ws_plugin__s2member_log_file"]) : "";
211
+ $logs_dir = $GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["logs_dir"];
212
 
213
+ if(is_dir($logs_dir)) // Do we have a logs directory on this installation?
214
+ {
215
+ $log_files = scandir($logs_dir);
216
+ sort($log_files, SORT_STRING);
217
 
218
+ $log_file_options .= '<optgroup label="Current Log Files">';
219
+ foreach($log_files as $_log_file) // Build options for each current log file.
220
+ {
221
+ $_log_file_description = array("short" => "No description available.", "long" => "No description available.");
222
 
223
+ foreach(c_ws_plugin__s2member_utils_logs::$log_file_descriptions as $_k => $_v)
224
+ if(preg_match($_k, $_log_file))
225
  {
226
+ $_log_file_description = $_v;
227
+ break; // Stop here.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
228
  }
229
+ unset($_k, $_v); // Housekeeping.
 
 
230
 
231
+ if(preg_match("/\.log$/", $_log_file) && stripos($_log_file, "-ARCHIVED-") === FALSE)
232
+ $log_file_options .= '<option data-type="current" title="'.esc_attr($_log_file_description["long"]).'" value="'.esc_attr($_log_file).'"'.(($view_log_file === $_log_file) ? ' style="font-weight:bold;" selected="selected"' : '').'>'.esc_html($_log_file).' — '.esc_html($_log_file_description["short"]).'</option>';
233
+ }
234
+ unset($_log_file_description, $_log_file); // Housekeeping.
235
+ $log_file_options .= '</optgroup>';
236
 
237
+ if(stripos($log_file_options, '<option data-type="current"') === FALSE)
238
+ $log_file_options .= '<option value="" disabled="disabled">— No current log files yet. —</option>';
 
239
 
240
+ $log_file_options .= '<option value="" disabled="disabled"></option>';
 
 
 
 
241
 
242
+ $log_file_options .= '<optgroup label="Archived Log Files">';
243
+ foreach($log_files as $_log_file) // Build options for each ARCHIVED log file.
244
+ {
245
+ if(preg_match("/\.log$/", $_log_file) && stripos($_log_file, "-ARCHIVED-") !== FALSE)
246
+ $log_file_options .= '<option data-type="archived" value="'.esc_attr($_log_file).'"'.(($view_log_file === $_log_file) ? ' style="font-weight:bold;" selected="selected"' : '').'>'.esc_html($_log_file).'</option>';
247
+ }
248
+ $log_file_options .= '</optgroup>';
249
 
250
+ if(stripos($log_file_options, '<option data-type="archived"') === FALSE)
251
+ $log_file_options .= '<option value="" disabled="disabled">— No log files archived yet. —</option>';
252
+ }
253
+ $log_file_options = '<option value="">— Choose a Log File to View —</option>'.
254
+ '<option value="" disabled="disabled"></option>'.
255
+ $log_file_options;
256
 
257
+ echo '<form method="post" name="ws_plugin__s2member_log_viewer" id="ws-plugin--s2member-log-viewer">'."\n";
 
 
258
 
259
+ echo '<table class="form-table">'."\n";
260
+ echo '<tbody>'."\n";
261
+ echo '<tr>'."\n";
262
 
263
+ echo '<td style="width:80%;">'."\n";
264
+ echo '<select name="ws_plugin__s2member_log_file" id="ws-plugin--s2member-log-file">'."\n";
265
+ echo $log_file_options."\n";
266
+ echo '</select>'."\n";
267
+ echo '</td>'."\n";
268
 
269
+ echo '<td style="width:20%; padding-left:5px;">'."\n";
270
+ echo '<input type="submit" value="View" style="font-size:120%; font-weight:normal;" />'."\n";
271
+ echo '</td>'."\n";
 
 
 
 
272
 
273
+ echo '</tr>'."\n";
274
+ echo '</tbody>'."\n";
275
+ echo '</table>'."\n";
276
 
277
+ echo '<table class="form-table">'."\n";
278
+ echo '<tbody>'."\n";
279
+ echo '<tr>'."\n";
280
 
281
+ echo '<td>'."\n";
282
 
283
+ if($view_log_file && file_exists($logs_dir."/".$view_log_file) && filesize($logs_dir."/".$view_log_file))
284
+ {
285
+ $_log_file_description = array("short" => "", "long" => "");
 
 
 
286
 
287
+ foreach(c_ws_plugin__s2member_utils_logs::$log_file_descriptions as $_k => $_v)
288
+ if(preg_match($_k, $view_log_file))
289
+ {
290
+ $_log_file_description = $_v;
291
+ break; // Stop here.
292
+ }
293
+ unset($_k, $_v); // Housekeeping.
294
 
295
+ if(!empty($_log_file_description["long"])) // Do we have a description that we can display here?
296
+ echo '<p style="clear:both; width:80%; font-family:\'Georgia\', serif; font-style:italic;"><strong>Description for <a href="'.esc_attr(add_query_arg(array("ws_plugin__s2member_download_log_file" => $view_log_file, "ws_plugin__s2member_download_log_file_v" => wp_create_nonce("ws-plugin--s2member-download-log-file-v")))).'">'.esc_html($view_log_file).'</a></strong>: '.esc_html($_log_file_description["long"]).'</p>'."\n";
297
+ unset($_log_file_description); // Just a little housekeeping here.
298
 
299
+ echo '<p style="float:left; text-align:left;"><strong>Viewing:</strong> <a href="'.esc_attr(add_query_arg(array("ws_plugin__s2member_download_log_file" => $view_log_file, "ws_plugin__s2member_download_log_file_v" => wp_create_nonce("ws-plugin--s2member-download-log-file-v")))).'">'.esc_html($view_log_file).'</a> (log entries oldest to newest)</p>'."\n";
300
+ echo '<p style="float:right; text-align:right;">[ <a href="'.esc_attr(add_query_arg(array("ws_plugin__s2member_download_log_file" => $view_log_file, "ws_plugin__s2member_download_log_file_v" => wp_create_nonce("ws-plugin--s2member-download-log-file-v")))).'"><strong>download file</strong></a> ]</p>'."\n";
301
+ echo '<p style="margin-right:10px; float:right; text-align:right;"><a href="#" class="ws-plugin--s2member-log-file-viewport-toggle" style="text-decoration:none;">&#8659; expand viewport &#8659;</a></p>'."\n";
302
 
303
+ echo '<textarea id="ws-plugin--s2member-log-file-viewer" rows="20" wrap="on" spellcheck="false" style="box-shadow:inset 0 0 5px rgba(0,0,0,0.5); background:#EEEEEE; color:#000000; overflow-y:scroll;">'.htmlspecialchars(file_get_contents($logs_dir."/".$view_log_file)).'</textarea>'."\n";
 
 
304
 
305
+ echo '<p style="float:left; text-align:left;"><strong>Viewing:</strong> <a href="'.esc_attr(add_query_arg(array("ws_plugin__s2member_download_log_file" => $view_log_file, "ws_plugin__s2member_download_log_file_v" => wp_create_nonce("ws-plugin--s2member-download-log-file-v")))).'">'.esc_html($view_log_file).'</a> (log entries oldest to newest)</p>'."\n";
306
+ echo '<p style="float:right; text-align:right;">[ <a href="'.esc_attr(add_query_arg(array("ws_plugin__s2member_download_log_file" => $view_log_file, "ws_plugin__s2member_download_log_file_v" => wp_create_nonce("ws-plugin--s2member-download-log-file-v")))).'"><strong>download file</strong></a> ]</p>'."\n";
307
+ echo '<p style="margin-right:10px; float:right; text-align:right;"><a href="#" class="ws-plugin--s2member-log-file-viewport-toggle" style="text-decoration:none;">&#8659; expand viewport &#8659;</a></p>'."\n";
308
+ }
309
+ else if($view_log_file && file_exists($logs_dir."/".$view_log_file))
310
+ echo '<textarea id="ws-plugin--s2member-log-file-viewer" rows="20" wrap="on" spellcheck="false" style="box-shadow:inset 0 0 5px rgba(0,0,0,0.5); background:#EEEEEE; color:#000000; overflow-y:scroll; font-style:italic;">— Empty at this time —</textarea>'."\n";
311
 
312
+ else if($view_log_file && !file_exists($logs_dir."/".$view_log_file))
313
+ echo '<textarea id="ws-plugin--s2member-log-file-viewer" rows="20" wrap="on" spellcheck="false" style="box-shadow:inset 0 0 5px rgba(0,0,0,0.5); background:#EEEEEE; color:#000000; overflow-y:scroll; font-style:italic;">— File no longer exists —</textarea>'."\n";
314
 
315
+ else // Display an empty textarea in this default scenario.
316
+ echo '<textarea id="ws-plugin--s2member-log-file-viewer" rows="20" wrap="on" spellcheck="false" style="box-shadow:inset 0 0 5px rgba(0,0,0,0.5); background:#EEEEEE; color:#000000; overflow-y:scroll; font-style:italic;"></textarea>'."\n";
317
 
318
+ echo '</td>'."\n";
319
 
320
+ echo '</tr>'."\n";
321
+ echo '</tbody>'."\n";
322
+ echo '</table>'."\n";
323
 
324
+ echo '</form>'."\n";
 
 
325
 
326
+ echo '</div>'."\n";
327
+ echo '</div>'."\n";
 
328
 
329
+ do_action("ws_plugin__s2member_during_logs_page_during_left_sections_after_logs", get_defined_vars());
 
330
  }
331
+ do_action("ws_plugin__s2member_during_logs_page_after_left_sections", get_defined_vars());
332
+
333
+ echo '</td>'."\n";
334
+
335
+ echo '<td class="ws-menu-page-table-r">'."\n";
336
+ c_ws_plugin__s2member_menu_pages_rs::display();
337
+ echo '</td>'."\n";
338
+
339
+ echo '</tr>'."\n";
340
+ echo '</tbody>'."\n";
341
+ echo '</table>'."\n";
342
+
343
+ echo '</div>'."\n";
344
+ }
345
  }
346
+ }
347
 
348
+ new c_ws_plugin__s2member_menu_page_logs();
 
includes/menu-pages/menu-pages.css CHANGED
@@ -16,7 +16,6 @@
16
  * @since x.xx
17
  */
18
  @import url('//maxcdn.bootstrapcdn.com/font-awesome/4.1.0/css/font-awesome.min.css');
19
-
20
  /*
21
  Alter WordPress wrap on s2Member menu pages.
22
  */
@@ -24,7 +23,6 @@ body[class*='s2member'] #wpwrap
24
  {
25
  background : #C7C7C7;
26
  }
27
-
28
  /*
29
  Align these with menu page.
30
  */
@@ -33,7 +31,6 @@ div.updated, div.error
33
  font-size : 120%;
34
  margin : 25px 25px 25px 5px;
35
  }
36
-
37
  /*
38
  These CSS selectors address common layout styles.
39
  */
@@ -49,6 +46,11 @@ div.ws-menu-page
49
  box-shadow : 0 0 8px 0 rgba(0, 0, 0, 0.2) !important;
50
  background : #FFFFFF url('<?php echo $i; ?>/trans-bg.png') repeat left top;
51
  }
 
 
 
 
 
52
  div.ws-menu-page a
53
  {
54
  color : #003E75;
@@ -125,7 +127,7 @@ div.ws-menu-page code
125
  border-radius : 3px;
126
  padding : 1px 5px 1px 5px;
127
  background : rgba(255, 255, 255, 0.25);
128
- font-family : 'Monaco', 'Menlo', 'Consolas', 'Courier New', monospace;
129
  }
130
  div.ws-menu-page pre.code
131
  {
@@ -164,27 +166,23 @@ div.ws-menu-page img
164
  {
165
  border : 0;
166
  }
167
- div.ws-menu-page img.screenshot
168
  {
169
- float : right;
170
- margin : 0 0 15px 25px;
171
-
172
- border-radius : 5px;
173
- border : 1px solid #AFAFAF;
174
-
175
- box-shadow : 0 0 5px 0 rgba(0, 0, 0, 0.2) inset, 0 0 1px 0 rgba(72, 155, 88, 0.2);
176
- background : #FFFFFF;
177
  padding : 10px;
 
 
 
178
  }
179
  div.ws-menu-page .ws-menu-page-right
180
  {
181
- float : right;
182
  margin-left : 25px;
 
183
  }
184
  div.ws-menu-page .ws-menu-page-left
185
  {
186
- float : left;
187
  margin-right : 25px;
 
188
  }
189
  div.ws-menu-page .ws-menu-page-center
190
  {
@@ -262,52 +260,79 @@ div.ws-menu-page .form-table td
262
  font-size : inherit;
263
  line-height : inherit;
264
  }
265
- div.ws-menu-page input:not([type='image']):not([type='button']):not([type='submit']):not([type='radio']):not([type='checkbox']),
266
- div.ws-menu-page input:not([type='image']):not([type='button']):not([type='submit']):not([type='radio']):not([type='checkbox']):focus,
267
  div.ws-menu-page select, div.ws-menu-page select:focus,
268
- div.ws-menu-page textarea, div.ws-menu-page textarea:focus
 
 
269
  {
 
270
  width : 100%;
271
- height : auto;
272
 
273
- margin : 0;
274
- padding : 5px;
275
  line-height : 1em;
276
- box-sizing : border-box;
277
- border : 1px solid rgba(13, 31, 47, 0.5);
278
 
279
- color : #FFFFFF;
280
- background : #73834B;
281
- box-shadow : 0 0 1px 0 rgba(0, 0, 0, 0.5) inset, 0 0 1px 1px rgba(223, 245, 165, 0.5);
 
 
 
 
 
282
  }
283
- div.ws-menu-page input:not([type='image']):not([type='button']):not([type='submit']):not([type='radio']):not([type='checkbox']):focus,
284
- div.ws-menu-page select:focus, div.ws-menu-page textarea:focus
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
285
  {
286
  background : #637041;
287
  }
288
  div.ws-menu-page input::-webkit-input-placeholder
289
  {
290
- color : rgba(255, 255, 255, 0.2);
291
- font-style : italic;
292
  padding-top : 3px;
 
 
293
  }
294
  div.ws-menu-page input::-moz-placeholder
295
  {
296
- color : rgba(255, 255, 255, 0.2);
297
- font-style : italic;
298
  padding-top : 3px;
 
 
299
  }
300
  div.ws-menu-page input:-moz-placeholder
301
  {
302
- color : rgba(255, 255, 255, 0.2);
303
- font-style : italic;
304
  padding-top : 3px;
 
 
305
  }
306
  div.ws-menu-page input:-ms-input-placeholder
307
  {
308
- color : rgba(255, 255, 255, 0.2);
309
- font-style : italic;
310
  padding-top : 3px;
 
 
311
  }
312
  div.ws-menu-page input[disabled],
313
  div.ws-menu-page select[disabled],
@@ -326,7 +351,7 @@ div.ws-menu-page input[type='submit']
326
 
327
  border-radius : 4px;
328
  border : 1px solid rgba(0, 0, 0, 0.5);
329
- box-shadow : 0 1px 1px 0 rgba(0, 0, 0, 0.25), -1px -1px 0 1px rgba(0, 0, 0, 0.2) inset, 1px 1px 0 1px rgba(255, 255, 255, 0.1) inset;
330
 
331
  margin : 0;
332
  box-sizing : border-box;
@@ -382,10 +407,10 @@ div.ws-menu-page .notice,
382
  div.ws-menu-page .warning,
383
  div.ws-menu-page .error
384
  {
 
385
  font-size : 120%;
386
  padding : 10px;
387
  margin : 0 0 25px 0;
388
- border-radius : 5px;
389
  }
390
  div.ws-menu-page .info
391
  {
@@ -425,7 +450,6 @@ div.ws-menu-page .clearfix:after
425
  {
426
  clear : both;
427
  }
428
-
429
  /*
430
  Tools and togglers.
431
  */
@@ -445,7 +469,7 @@ div.ws-menu-page div.ws-menu-page-groups-hide
445
 
446
  border-radius : 4px;
447
  border : 1px solid rgba(0, 0, 0, 0.5);
448
- box-shadow : 0 1px 1px 0 rgba(0, 0, 0, 0.25), -1px -1px 0 1px rgba(0, 0, 0, 0.2) inset, 1px 1px 0 1px rgba(255, 255, 255, 0.1) inset;
449
 
450
  margin : 0;
451
  box-sizing : border-box;
@@ -491,7 +515,6 @@ div.ws-menu-page div.ws-menu-page-toolbox > .links a
491
  margin : 0 10px 0 10px;
492
  text-decoration : none;
493
  }
494
-
495
  /*
496
  Specifically for the main layout table.
497
  These CSS selectors address common layout styles.
@@ -507,8 +530,7 @@ table.ws-menu-page-table .info,
507
  table.ws-menu-page-table .warning,
508
  table.ws-menu-page-table .error
509
  {
510
- font-size : 80%;
511
- padding : 5px;
512
  margin : 1em 0 1em 0;
513
  }
514
  table.ws-menu-page-table ul,
@@ -699,6 +721,10 @@ table.ws-menu-page-table div.ws-menu-page-r-group-header.open:after
699
  table.ws-menu-page-table div.ws-menu-page-group,
700
  table.ws-menu-page-table div.ws-menu-page-r-group
701
  {
 
 
 
 
702
  z-index : 0;
703
  position : relative;
704
  display : none;
@@ -795,7 +821,6 @@ table.ws-menu-page-table div.ws-menu-page-group table.form-table > tbody > tr >
795
  background : #73834B;
796
  box-shadow : 0 0 1px 0 rgba(0, 0, 0, 0.5) inset, 0 0 1px 1px rgba(223, 245, 165, 0.5);
797
  }
798
-
799
  /*
800
  Specifically for info pages with readme files.
801
  These CSS selectors address common layout styles.
@@ -833,7 +858,6 @@ div.ws-menu-page-readme > div.readme > div.section > div.content ol > li
833
  list-style : decimal outside;
834
  margin-bottom : 0;
835
  }
836
-
837
  /*
838
  Specifically for the right sidebar panel.
839
  - Specifically for the updates box.
16
  * @since x.xx
17
  */
18
  @import url('//maxcdn.bootstrapcdn.com/font-awesome/4.1.0/css/font-awesome.min.css');
 
19
  /*
20
  Alter WordPress wrap on s2Member menu pages.
21
  */
23
  {
24
  background : #C7C7C7;
25
  }
 
26
  /*
27
  Align these with menu page.
28
  */
31
  font-size : 120%;
32
  margin : 25px 25px 25px 5px;
33
  }
 
34
  /*
35
  These CSS selectors address common layout styles.
36
  */
46
  box-shadow : 0 0 8px 0 rgba(0, 0, 0, 0.2) !important;
47
  background : #FFFFFF url('<?php echo $i; ?>/trans-bg.png') repeat left top;
48
  }
49
+ div.ws-menu-page p,
50
+ div.ws-menu-page code
51
+ {
52
+ font-size : inherit;
53
+ }
54
  div.ws-menu-page a
55
  {
56
  color : #003E75;
127
  border-radius : 3px;
128
  padding : 1px 5px 1px 5px;
129
  background : rgba(255, 255, 255, 0.25);
130
+ font-family : 'Menlo', 'Monaco', 'Consolas', 'Courier New', monospace;
131
  }
132
  div.ws-menu-page pre.code
133
  {
166
  {
167
  border : 0;
168
  }
169
+ div.ws-menu-page img.ws-menu-page-bordered
170
  {
171
+ border-radius : 4px;
 
 
 
 
 
 
 
172
  padding : 10px;
173
+ background : #FFFFFF;
174
+ border : 1px solid #AFAFAF;
175
+ box-shadow : 0 0 2px 1px #D8D8D8 inset, 0 0 1px 1px rgba(223, 245, 165, 0.5);
176
  }
177
  div.ws-menu-page .ws-menu-page-right
178
  {
 
179
  margin-left : 25px;
180
+ float : right;
181
  }
182
  div.ws-menu-page .ws-menu-page-left
183
  {
 
184
  margin-right : 25px;
185
+ float : left;
186
  }
187
  div.ws-menu-page .ws-menu-page-center
188
  {
260
  font-size : inherit;
261
  line-height : inherit;
262
  }
 
 
263
  div.ws-menu-page select, div.ws-menu-page select:focus,
264
+ div.ws-menu-page textarea, div.ws-menu-page textarea:focus,
265
+ div.ws-menu-page input:not([type='image']):not([type='button']):not([type='submit']):not([type='radio']):not([type='checkbox']),
266
+ div.ws-menu-page input:not([type='image']):not([type='button']):not([type='submit']):not([type='radio']):not([type='checkbox']):focus
267
  {
268
+ margin : 0;
269
  width : 100%;
270
+ height : 2em;
271
 
272
+ font-size : 1em;
 
273
  line-height : 1em;
274
+ font-weight : normal;
 
275
 
276
+ box-sizing : border-box;
277
+ }
278
+ div.ws-menu-page textarea, div.ws-menu-page textarea:focus,
279
+ div.ws-menu-page input:not([type='image']):not([type='button']):not([type='submit']):not([type='radio']):not([type='checkbox']),
280
+ div.ws-menu-page input:not([type='image']):not([type='button']):not([type='submit']):not([type='radio']):not([type='checkbox']):focus
281
+ {
282
+ font-size : 1em; /* Font size again, for CodeMirror too. */
283
+ font-family : 'Menlo', 'Monaco', 'Consolas', 'Courier New', monospace;
284
  }
285
+ div.ws-menu-page textarea, div.ws-menu-page textarea:focus
286
+ {
287
+ height : auto; /* Textareas auto. */
288
+ white-space : pre; /* Preserve whitespace. */
289
+ }
290
+ div.ws-menu-page select, div.ws-menu-page select:focus,
291
+ div.ws-menu-page textarea, div.ws-menu-page textarea:focus,
292
+ div.ws-menu-page input:not([type='image']):not([type='button']):not([type='submit']):not([type='radio']):not([type='checkbox']),
293
+ div.ws-menu-page input:not([type='image']):not([type='button']):not([type='submit']):not([type='radio']):not([type='checkbox']):focus
294
+ {
295
+ border : 0;
296
+ padding : 5px;
297
+ border-radius : 4px;
298
+ box-shadow : 0 0 1px 1px rgba(37, 47, 26, 0.75) inset, 0 0 1px 1px rgba(223, 245, 165, 0.5);
299
+ }
300
+ div.ws-menu-page select,
301
+ div.ws-menu-page textarea,
302
+ div.ws-menu-page input:not([type='image']):not([type='button']):not([type='submit']):not([type='radio']):not([type='checkbox'])
303
+ {
304
+ color : #F7F7F7;
305
+ background : #73834B;
306
+ }
307
+ div.ws-menu-page select:focus,
308
+ div.ws-menu-page textarea:focus,
309
+ div.ws-menu-page input:not([type='image']):not([type='button']):not([type='submit']):not([type='radio']):not([type='checkbox']):focus
310
  {
311
  background : #637041;
312
  }
313
  div.ws-menu-page input::-webkit-input-placeholder
314
  {
 
 
315
  padding-top : 3px;
316
+ font-style : italic;
317
+ color : rgba(255, 255, 255, 0.2);
318
  }
319
  div.ws-menu-page input::-moz-placeholder
320
  {
 
 
321
  padding-top : 3px;
322
+ font-style : italic;
323
+ color : rgba(255, 255, 255, 0.2);
324
  }
325
  div.ws-menu-page input:-moz-placeholder
326
  {
 
 
327
  padding-top : 3px;
328
+ font-style : italic;
329
+ color : rgba(255, 255, 255, 0.2);
330
  }
331
  div.ws-menu-page input:-ms-input-placeholder
332
  {
 
 
333
  padding-top : 3px;
334
+ font-style : italic;
335
+ color : rgba(255, 255, 255, 0.2);
336
  }
337
  div.ws-menu-page input[disabled],
338
  div.ws-menu-page select[disabled],
351
 
352
  border-radius : 4px;
353
  border : 1px solid rgba(0, 0, 0, 0.5);
354
+ box-shadow : 0 1px 1px 0 rgba(0, 0, 0, 0.25), -1px -1px 0 0 rgba(0, 0, 0, 0.2) inset, 1px 1px 0 0 rgba(255, 255, 255, 0.1) inset;
355
 
356
  margin : 0;
357
  box-sizing : border-box;
407
  div.ws-menu-page .warning,
408
  div.ws-menu-page .error
409
  {
410
+ border-radius : 5px;
411
  font-size : 120%;
412
  padding : 10px;
413
  margin : 0 0 25px 0;
 
414
  }
415
  div.ws-menu-page .info
416
  {
450
  {
451
  clear : both;
452
  }
 
453
  /*
454
  Tools and togglers.
455
  */
469
 
470
  border-radius : 4px;
471
  border : 1px solid rgba(0, 0, 0, 0.5);
472
+ box-shadow : 0 1px 1px 0 rgba(0, 0, 0, 0.25), -1px -1px 0 0 rgba(0, 0, 0, 0.2) inset, 1px 1px 0 0 rgba(255, 255, 255, 0.1) inset;
473
 
474
  margin : 0;
475
  box-sizing : border-box;
515
  margin : 0 10px 0 10px;
516
  text-decoration : none;
517
  }
 
518
  /*
519
  Specifically for the main layout table.
520
  These CSS selectors address common layout styles.
530
  table.ws-menu-page-table .warning,
531
  table.ws-menu-page-table .error
532
  {
533
+ font-size : inherit;
 
534
  margin : 1em 0 1em 0;
535
  }
536
  table.ws-menu-page-table ul,
721
  table.ws-menu-page-table div.ws-menu-page-group,
722
  table.ws-menu-page-table div.ws-menu-page-r-group
723
  {
724
+ width : 99%;
725
+ margin : 0 auto 0 auto;
726
+ box-sizing : border-box;
727
+
728
  z-index : 0;
729
  position : relative;
730
  display : none;
821
  background : #73834B;
822
  box-shadow : 0 0 1px 0 rgba(0, 0, 0, 0.5) inset, 0 0 1px 1px rgba(223, 245, 165, 0.5);
823
  }
 
824
  /*
825
  Specifically for info pages with readme files.
826
  These CSS selectors address common layout styles.
858
  list-style : decimal outside;
859
  margin-bottom : 0;
860
  }
 
861
  /*
862
  Specifically for the right sidebar panel.
863
  - Specifically for the updates box.
includes/menu-pages/paypal-buttons.inc.php CHANGED
@@ -96,11 +96,11 @@ if (!class_exists ("c_ws_plugin__s2member_menu_page_paypal_buttons"))
96
  $ws_plugin__s2member_temp_s = preg_replace ("/%%level%%/", c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr ($n)), $ws_plugin__s2member_temp_s);
97
  $ws_plugin__s2member_temp_s = preg_replace ("/%%level_label%%/", c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["level" . $n . "_label"])), $ws_plugin__s2member_temp_s);
98
  $ws_plugin__s2member_temp_s = preg_replace ("/%%custom%%/", c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr ($_SERVER["HTTP_HOST"])), $ws_plugin__s2member_temp_s);
99
- echo '<input type="text" autocomplete="off" id="ws-plugin--s2member-level' . $n . '-shortcode" value="' . format_to_edit ($ws_plugin__s2member_temp_s) . '" onclick="this.select ();" class="monospace" />' . "\n";
100
 
101
  echo '<div' . ((is_multisite () && c_ws_plugin__s2member_utils_conds::is_multisite_farm () && !is_main_site ()) ? ' style="display:none;"' : '') . '><br />' . "\n";
102
  echo '<strong>Resulting PayPal Button Code:</strong> (ultimately, your Shortcode will produce this snippet)<br />' . "\n";
103
- echo '<textarea id="ws-plugin--s2member-level' . $n . '-button" rows="8" wrap="off" onclick="this.select ();" class="monospace">';
104
  $ws_plugin__s2member_temp_s = trim (c_ws_plugin__s2member_utilities::evl (file_get_contents (dirname (dirname (__FILE__)) . "/templates/buttons/paypal-checkout-button.php")));
105
  $ws_plugin__s2member_temp_s = preg_replace ("/%%endpoint%%/", c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr (($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["paypal_sandbox"]) ? "www.sandbox.paypal.com" : "www.paypal.com")), $ws_plugin__s2member_temp_s);
106
  $ws_plugin__s2member_temp_s = preg_replace ("/%%paypal_business%%/", c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["paypal_business"])), $ws_plugin__s2member_temp_s);
@@ -108,11 +108,11 @@ if (!class_exists ("c_ws_plugin__s2member_menu_page_paypal_buttons"))
108
  $ws_plugin__s2member_temp_s = preg_replace ("/%%level%%/", c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr ($n)), $ws_plugin__s2member_temp_s);
109
  $ws_plugin__s2member_temp_s = preg_replace ("/%%level_label%%/", c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["level" . $n . "_label"])), $ws_plugin__s2member_temp_s);
110
  $ws_plugin__s2member_temp_s = preg_replace ("/%%cancel_return%%/", c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr (home_url ("/"))), $ws_plugin__s2member_temp_s);
111
- $ws_plugin__s2member_temp_s = preg_replace ("/%%notify_url%%/", c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr (site_url ("/?s2member_paypal_notify=1"))), $ws_plugin__s2member_temp_s);
112
- $ws_plugin__s2member_temp_s = preg_replace ("/%%return%%/", c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr (site_url ("/?s2member_paypal_return=1"))), $ws_plugin__s2member_temp_s);
113
  $ws_plugin__s2member_temp_s = preg_replace ("/%%custom%%/", c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr ($_SERVER["HTTP_HOST"])), $ws_plugin__s2member_temp_s);
114
  $ws_plugin__s2member_temp_s = preg_replace ("/%%images%%/", c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr ($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["dir_url"] . "/images")), $ws_plugin__s2member_temp_s);
115
- $ws_plugin__s2member_temp_s = preg_replace ("/%%wpurl%%/", c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr (site_url ())), $ws_plugin__s2member_temp_s);
116
  echo format_to_edit ($ws_plugin__s2member_temp_s);
117
  echo '</textarea><br />' . "\n";
118
  echo '&uarr; <em>This <span class="ws-menu-page-hilite">may contain PHP code too</span>; so be careful if you use this.</em>' . "\n";
@@ -198,11 +198,11 @@ if (!class_exists ("c_ws_plugin__s2member_menu_page_paypal_buttons"))
198
  $ws_plugin__s2member_temp_s = preg_replace ("/%%level_label%% /", c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["level1_label"])), $ws_plugin__s2member_temp_s);
199
  $ws_plugin__s2member_temp_s = preg_replace ("/%%custom%%/", c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr ($_SERVER["HTTP_HOST"])), $ws_plugin__s2member_temp_s);
200
  $ws_plugin__s2member_temp_s = preg_replace ("/\/]$/", 'modify="1" /]', $ws_plugin__s2member_temp_s); // Adds modify="1" to the end of the Shortcode.
201
- echo '<input type="text" autocomplete="off" id="ws-plugin--s2member-modification-shortcode" value="' . format_to_edit ($ws_plugin__s2member_temp_s) . '" onclick="this.select ();" class="monospace" />' . "\n";
202
 
203
  echo '<div' . ((is_multisite () && c_ws_plugin__s2member_utils_conds::is_multisite_farm () && !is_main_site ()) ? ' style="display:none;"' : '') . '><br />' . "\n";
204
  echo '<strong>Resulting PayPal Button Code:</strong> (ultimately, your Shortcode will produce this snippet)<br />' . "\n";
205
- echo '<textarea id="ws-plugin--s2member-modification-button" rows="8" wrap="off" onclick="this.select ();" class="monospace">';
206
  $ws_plugin__s2member_temp_s = trim (c_ws_plugin__s2member_utilities::evl (file_get_contents (dirname (dirname (__FILE__)) . "/templates/buttons/paypal-checkout-button.php")));
207
  $ws_plugin__s2member_temp_s = preg_replace ('/name\="modify" value\="(.*?)"/', 'name="modify" value="1"', $ws_plugin__s2member_temp_s);
208
  $ws_plugin__s2member_temp_s = preg_replace ("/%%endpoint%%/", c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr (($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["paypal_sandbox"]) ? "www.sandbox.paypal.com" : "www.paypal.com")), $ws_plugin__s2member_temp_s);
@@ -211,11 +211,11 @@ if (!class_exists ("c_ws_plugin__s2member_menu_page_paypal_buttons"))
211
  $ws_plugin__s2member_temp_s = preg_replace ("/%%level%%/", c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr ("1")), $ws_plugin__s2member_temp_s);
212
  $ws_plugin__s2member_temp_s = preg_replace ("/%%level_label%% /", c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["level1_label"])), $ws_plugin__s2member_temp_s);
213
  $ws_plugin__s2member_temp_s = preg_replace ("/%%cancel_return%%/", c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr (home_url ("/"))), $ws_plugin__s2member_temp_s);
214
- $ws_plugin__s2member_temp_s = preg_replace ("/%%notify_url%%/", c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr (site_url ("/?s2member_paypal_notify=1"))), $ws_plugin__s2member_temp_s);
215
- $ws_plugin__s2member_temp_s = preg_replace ("/%%return%%/", c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr (site_url ("/?s2member_paypal_return=1"))), $ws_plugin__s2member_temp_s);
216
  $ws_plugin__s2member_temp_s = preg_replace ("/%%custom%%/", c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr ($_SERVER["HTTP_HOST"])), $ws_plugin__s2member_temp_s);
217
  $ws_plugin__s2member_temp_s = preg_replace ("/%%images%%/", c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr ($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["dir_url"] . "/images")), $ws_plugin__s2member_temp_s);
218
- $ws_plugin__s2member_temp_s = preg_replace ("/%%wpurl%%/", c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr (site_url ())), $ws_plugin__s2member_temp_s);
219
  echo format_to_edit ($ws_plugin__s2member_temp_s);
220
  echo '</textarea><br />' . "\n";
221
  echo '&uarr; <em>This <span class="ws-menu-page-hilite">may contain PHP code too</span>; so be careful if you use this.</em>' . "\n";
@@ -279,21 +279,21 @@ if (!class_exists ("c_ws_plugin__s2member_menu_page_paypal_buttons"))
279
  echo '<strong>WordPress Shortcode:</strong> (recommended for both the WordPress Visual &amp; HTML Editors)<br />' . "\n";
280
  $ws_plugin__s2member_temp_s = trim (c_ws_plugin__s2member_utilities::evl (file_get_contents (dirname (dirname (__FILE__)) . "/templates/shortcodes/paypal-ccaps-checkout-button-shortcode.php")));
281
  $ws_plugin__s2member_temp_s = preg_replace ("/%%custom%%/", c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr ($_SERVER["HTTP_HOST"])), $ws_plugin__s2member_temp_s);
282
- echo '<input type="text" autocomplete="off" id="ws-plugin--s2member-ccap-shortcode" value="' . format_to_edit ($ws_plugin__s2member_temp_s) . '" onclick="this.select ();" class="monospace" />' . "\n";
283
 
284
  echo '<div' . ((is_multisite () && c_ws_plugin__s2member_utils_conds::is_multisite_farm () && !is_main_site ()) ? ' style="display:none;"' : '') . '><br />' . "\n";
285
  echo '<strong>Resulting PayPal Button Code:</strong> (ultimately, your Shortcode will produce this snippet)<br />' . "\n";
286
- echo '<textarea id="ws-plugin--s2member-ccap-button" rows="8" wrap="off" onclick="this.select ();" class="monospace">';
287
  $ws_plugin__s2member_temp_s = trim (c_ws_plugin__s2member_utilities::evl (file_get_contents (dirname (dirname (__FILE__)) . "/templates/buttons/paypal-ccaps-checkout-button.php")));
288
  $ws_plugin__s2member_temp_s = preg_replace ("/%%endpoint%%/", c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr (($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["paypal_sandbox"]) ? "www.sandbox.paypal.com" : "www.paypal.com")), $ws_plugin__s2member_temp_s);
289
  $ws_plugin__s2member_temp_s = preg_replace ("/%%paypal_business%%/", c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["paypal_business"])), $ws_plugin__s2member_temp_s);
290
  $ws_plugin__s2member_temp_s = preg_replace ("/%%paypal_merchant_id%%/", c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["paypal_merchant_id"])), $ws_plugin__s2member_temp_s);
291
  $ws_plugin__s2member_temp_s = preg_replace ("/%%cancel_return%%/", c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr (home_url ("/"))), $ws_plugin__s2member_temp_s);
292
- $ws_plugin__s2member_temp_s = preg_replace ("/%%notify_url%%/", c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr (site_url ("/?s2member_paypal_notify=1"))), $ws_plugin__s2member_temp_s);
293
- $ws_plugin__s2member_temp_s = preg_replace ("/%%return%%/", c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr (site_url ("/?s2member_paypal_return=1"))), $ws_plugin__s2member_temp_s);
294
  $ws_plugin__s2member_temp_s = preg_replace ("/%%custom%%/", c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr ($_SERVER["HTTP_HOST"])), $ws_plugin__s2member_temp_s);
295
  $ws_plugin__s2member_temp_s = preg_replace ("/%%images%%/", c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr ($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["dir_url"] . "/images")), $ws_plugin__s2member_temp_s);
296
- $ws_plugin__s2member_temp_s = preg_replace ("/%%wpurl%%/", c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr (site_url ())), $ws_plugin__s2member_temp_s);
297
  echo format_to_edit ($ws_plugin__s2member_temp_s);
298
  echo '</textarea><br />' . "\n";
299
  echo '&uarr; <em>This <span class="ws-menu-page-hilite">may contain PHP code too</span>; so be careful if you use this.</em>' . "\n";
@@ -340,7 +340,7 @@ if (!class_exists ("c_ws_plugin__s2member_menu_page_paypal_buttons"))
340
  $ws_plugin__s2member_temp_s = preg_replace ("/%%paypal_business%%/", c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["paypal_business"])), $ws_plugin__s2member_temp_s);
341
  $ws_plugin__s2member_temp_s = preg_replace ("/%%paypal_merchant_id%%/", c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["paypal_merchant_id"])), $ws_plugin__s2member_temp_s);
342
  $ws_plugin__s2member_temp_s = preg_replace ("/%%images%%/", c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr ($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["dir_url"] . "/images")), $ws_plugin__s2member_temp_s);
343
- $ws_plugin__s2member_temp_s = preg_replace ("/%%wpurl%%/", c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr (site_url ())), $ws_plugin__s2member_temp_s);
344
  echo preg_replace ("/\<a/", '<a target="_blank"', $ws_plugin__s2member_temp_s);
345
  echo '</div>' . "\n";
346
  echo '</label>' . "\n";
@@ -360,17 +360,17 @@ if (!class_exists ("c_ws_plugin__s2member_menu_page_paypal_buttons"))
360
  do_action("ws_plugin__s2member_during_paypal_buttons_page_during_left_sections_during_cancellation_buttons_before_shortcode", get_defined_vars ());
361
  echo '<strong>WordPress Shortcode:</strong> (recommended for both the WordPress Visual &amp; HTML Editors)<br />' . "\n";
362
  $ws_plugin__s2member_temp_s = trim (c_ws_plugin__s2member_utilities::evl (file_get_contents (dirname (dirname (__FILE__)) . "/templates/shortcodes/paypal-cancellation-button-shortcode.php")));
363
- echo '<input type="text" autocomplete="off" id="ws-plugin--s2member-cancellation-shortcode" value="' . format_to_edit ($ws_plugin__s2member_temp_s) . '" onclick="this.select ();" class="monospace" />' . "\n";
364
 
365
  echo '<div' . ((is_multisite () && c_ws_plugin__s2member_utils_conds::is_multisite_farm () && !is_main_site ()) ? ' style="display:none;"' : '') . '><br />' . "\n";
366
  echo '<strong>Resulting PayPal Button Code:</strong> (ultimately, your Shortcode will produce this snippet)<br />' . "\n";
367
- echo '<textarea id="ws-plugin--s2member-cancellation-button" rows="8" wrap="off" onclick="this.select ();" class="monospace">';
368
  $ws_plugin__s2member_temp_s = trim (c_ws_plugin__s2member_utilities::evl (file_get_contents (dirname (dirname (__FILE__)) . "/templates/buttons/paypal-cancellation-button.php")));
369
  $ws_plugin__s2member_temp_s = preg_replace ("/%%endpoint%%/", c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr (($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["paypal_sandbox"]) ? "www.sandbox.paypal.com" : "www.paypal.com")), $ws_plugin__s2member_temp_s);
370
  $ws_plugin__s2member_temp_s = preg_replace ("/%%paypal_business%%/", c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["paypal_business"])), $ws_plugin__s2member_temp_s);
371
  $ws_plugin__s2member_temp_s = preg_replace ("/%%paypal_merchant_id%%/", c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["paypal_merchant_id"])), $ws_plugin__s2member_temp_s);
372
  $ws_plugin__s2member_temp_s = preg_replace ("/%%images%%/", c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr ($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["dir_url"] . "/images")), $ws_plugin__s2member_temp_s);
373
- $ws_plugin__s2member_temp_s = preg_replace ("/%%wpurl%%/", c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr (site_url ())), $ws_plugin__s2member_temp_s);
374
  echo format_to_edit ($ws_plugin__s2member_temp_s);
375
  echo '</textarea><br />' . "\n";
376
  echo '&uarr; <em>This <span class="ws-menu-page-hilite">may contain PHP code too</span>; so be careful if you use this.</em>' . "\n";
@@ -414,7 +414,7 @@ if (!class_exists ("c_ws_plugin__s2member_menu_page_paypal_buttons"))
414
  echo '<p>Custom String Value: <input type="text" autocomplete="off" id="ws-plugin--s2member-reg-link-custom" value="' . esc_attr ($_SERVER["HTTP_HOST"]) . '" size="30" /> <a href="#" onclick="alert(\'A Paid Subscription is always associated with a Custom String that is passed through the custom=\\\'\\\'' . c_ws_plugin__s2member_utils_strings::esc_js_sq (esc_attr ($_SERVER["HTTP_HOST"]), 3) . '\\\'\\\' attribute of your Shortcode. This Custom Value, MUST always start with your domain name. However, you can also pipe delimit additional values after your domain, if you need to.\\n\\nFor example:\n' . c_ws_plugin__s2member_utils_strings::esc_js_sq (esc_attr ($_SERVER["HTTP_HOST"]), 3) . '|cv1|cv2|cv3\'); return false;" tabindex="-1">[?]</a> <input type="button" value="Generate Access Link" onclick="ws_plugin__s2member_paypalRegLinkGenerate();" /> <img id="ws-plugin--s2member-reg-link-loading" src="' . esc_attr ($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["dir_url"]) . '/images/ajax-loader.gif" alt="" style="display:none;" /></p>' . "\n";
415
  echo '<p' . ((is_multisite () && c_ws_plugin__s2member_utils_conds::is_multisite_farm () && !is_main_site ()) ? ' style="display:none;"' : '') . '>Custom Capabilities (comma-delimited) <a href="#" onclick="alert(\'Optional. This is VERY advanced.\\nSee: s2Member -› API Scripting -› Custom Capabilities.\'); return false;" tabindex="-1">[?]</a> <input type="text" maxlength="125" autocomplete="off" id="ws-plugin--s2member-reg-link-ccaps" size="40" onkeyup="if(this.value.match(/[^a-z_0-9,]/)) this.value = jQuery.trim (jQuery.trim (this.value).replace (/[ \-]/g, \'_\').replace (/[^a-z_0-9,]/gi, \'\').toLowerCase ());" /></p>' . "\n";
416
  echo '<p>Fixed Term Length (for Buy Now transactions): <input type="text" autocomplete="off" id="ws-plugin--s2member-reg-link-fixed-term" value="" size="10" /> <a href="#" onclick="alert(\'If the Customer purchased Membership through a Buy Now transaction (i.e. there is no Initial/Trial Period and no recurring charges for ongoing access), you may configure a Fixed Term Length in this field. This way the Customer\\\'s Membership Access is automatically revoked by s2Member at the appropriate time. This will be a numeric value, followed by a space, then a single letter.\\n\\nHere are some examples:\\n\\n1 D (this means 1 Day)\\n1 W (this means 1 Week)\\n1 M (this means 1 Month)\\n1 Y (this means 1 Year)\\n1 L (this means 1 Lifetime)\'); return false;">[?]</a></p>' . "\n";
417
- echo '<p id="ws-plugin--s2member-reg-link" class="monospace" style="display:none;"></p>' . "\n";
418
  echo '</form>' . "\n";
419
  echo '</td>' . "\n";
420
 
@@ -490,21 +490,21 @@ if (!class_exists ("c_ws_plugin__s2member_menu_page_paypal_buttons"))
490
  echo '<strong>WordPress Shortcode:</strong> (recommended for both the WordPress Visual &amp; HTML Editors)<br />' . "\n";
491
  $ws_plugin__s2member_temp_s = trim (c_ws_plugin__s2member_utilities::evl (file_get_contents (dirname (dirname (__FILE__)) . "/templates/shortcodes/paypal-sp-checkout-button-shortcode.php")));
492
  $ws_plugin__s2member_temp_s = preg_replace ("/%%custom%%/", c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr ($_SERVER["HTTP_HOST"])), $ws_plugin__s2member_temp_s);
493
- echo '<input type="text" autocomplete="off" id="ws-plugin--s2member-sp-shortcode" value="' . format_to_edit ($ws_plugin__s2member_temp_s) . '" onclick="this.select ();" class="monospace" />' . "\n";
494
 
495
  echo '<div' . ((is_multisite () && c_ws_plugin__s2member_utils_conds::is_multisite_farm () && !is_main_site ()) ? ' style="display:none;"' : '') . '><br />' . "\n";
496
  echo '<strong>Resulting PayPal Button Code:</strong> (ultimately, your Shortcode will produce this snippet)<br />' . "\n";
497
- echo '<textarea id="ws-plugin--s2member-sp-button" rows="8" wrap="off" onclick="this.select ();" class="monospace">';
498
  $ws_plugin__s2member_temp_s = trim (c_ws_plugin__s2member_utilities::evl (file_get_contents (dirname (dirname (__FILE__)) . "/templates/buttons/paypal-sp-checkout-button.php")));
499
  $ws_plugin__s2member_temp_s = preg_replace ("/%%endpoint%%/", c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr (($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["paypal_sandbox"]) ? "www.sandbox.paypal.com" : "www.paypal.com")), $ws_plugin__s2member_temp_s);
500
  $ws_plugin__s2member_temp_s = preg_replace ("/%%paypal_business%%/", c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["paypal_business"])), $ws_plugin__s2member_temp_s);
501
  $ws_plugin__s2member_temp_s = preg_replace ("/%%paypal_merchant_id%%/", c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["paypal_merchant_id"])), $ws_plugin__s2member_temp_s);
502
  $ws_plugin__s2member_temp_s = preg_replace ("/%%cancel_return%%/", c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr (home_url ("/"))), $ws_plugin__s2member_temp_s);
503
- $ws_plugin__s2member_temp_s = preg_replace ("/%%notify_url%%/", c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr (site_url ("/?s2member_paypal_notify=1"))), $ws_plugin__s2member_temp_s);
504
- $ws_plugin__s2member_temp_s = preg_replace ("/%%return%%/", c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr (site_url ("/?s2member_paypal_return=1"))), $ws_plugin__s2member_temp_s);
505
  $ws_plugin__s2member_temp_s = preg_replace ("/%%custom%%/", c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr ($_SERVER["HTTP_HOST"])), $ws_plugin__s2member_temp_s);
506
  $ws_plugin__s2member_temp_s = preg_replace ("/%%images%%/", c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr ($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["dir_url"] . "/images")), $ws_plugin__s2member_temp_s);
507
- $ws_plugin__s2member_temp_s = preg_replace ("/%%wpurl%%/", c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr (site_url ())), $ws_plugin__s2member_temp_s);
508
  echo format_to_edit ($ws_plugin__s2member_temp_s);
509
  echo '</textarea><br />' . "\n";
510
  echo '&uarr; <em>This <span class="ws-menu-page-hilite">may contain PHP code too</span>; so be careful if you use this.</em>' . "\n";
@@ -560,7 +560,7 @@ if (!class_exists ("c_ws_plugin__s2member_menu_page_paypal_buttons"))
560
  echo '</optgroup></select> <a href="#" onclick="alert(\'Hold down your `Ctrl` key to select multiples.\\n\\nOptional. If you include Additional Posts/Pages, Customers will still land on your Leading Post/Page; BUT, they\\\'ll ALSO have access to some Additional Posts/Pages that you\\\'ve protected. This gives you the ability to create Post/Page Packages.\\n\\nIn other words, a Customer is sold a Specific Post/Page (they\\\'ll land on your Leading Post/Page after checkout), which might contain links to some other Posts/Pages that you\\\'ve packaged together under one transaction.\\n\\nBundling Additional Posts/Pages into one Package, authenticates the Customer for access to the Additional Posts/Pages automatically (e.g. only one Access Link is needed, and s2Member generates this automatically). However, you will STILL need to design your Leading Post/Page (which is what a Customer will actually land on), with links pointing to the other Posts/Pages. This way your Customers will have clickable links to everything they\\\'ve paid for.\\n\\n*Quick Summary* s2Member sends Customers to your Leading Post/Page, and also authenticates them for access to any Additional Posts/Pages automatically. You handle it from there.\\n\\n*Tip* If there are no Posts/Pages in this menu, it\\\'s because you\\\'ve not configured s2Member for Specific Post/Page Access yet. See: s2Member -› Restriction Options -› Specific Post/Page Access.\'); return false;" tabindex="-1">[?]</a></p>' . "\n";
561
 
562
  echo '<p><select id="ws-plugin--s2member-sp-link-hours">' . trim (c_ws_plugin__s2member_utilities::evl (file_get_contents (dirname (dirname (__FILE__)) . "/templates/options/paypal-sp-hours.php"))) . '</select> <input type="button" value="Generate Access Link" onclick="ws_plugin__s2member_paypalSpLinkGenerate();" /> <img id="ws-plugin--s2member-sp-link-loading" src="' . esc_attr ($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["dir_url"]) . '/images/ajax-loader.gif" alt="" style="display:none;" /></p>' . "\n";
563
- echo '<p id="ws-plugin--s2member-sp-link" class="monospace" style="display:none;"></p>' . "\n";
564
  echo '</form>' . "\n";
565
  echo '</td>' . "\n";
566
 
96
  $ws_plugin__s2member_temp_s = preg_replace ("/%%level%%/", c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr ($n)), $ws_plugin__s2member_temp_s);
97
  $ws_plugin__s2member_temp_s = preg_replace ("/%%level_label%%/", c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["level" . $n . "_label"])), $ws_plugin__s2member_temp_s);
98
  $ws_plugin__s2member_temp_s = preg_replace ("/%%custom%%/", c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr ($_SERVER["HTTP_HOST"])), $ws_plugin__s2member_temp_s);
99
+ echo '<input type="text" autocomplete="off" id="ws-plugin--s2member-level' . $n . '-shortcode" value="' . format_to_edit ($ws_plugin__s2member_temp_s) . '" onclick="this.select ();" />' . "\n";
100
 
101
  echo '<div' . ((is_multisite () && c_ws_plugin__s2member_utils_conds::is_multisite_farm () && !is_main_site ()) ? ' style="display:none;"' : '') . '><br />' . "\n";
102
  echo '<strong>Resulting PayPal Button Code:</strong> (ultimately, your Shortcode will produce this snippet)<br />' . "\n";
103
+ echo '<textarea id="ws-plugin--s2member-level' . $n . '-button" rows="8" wrap="off" onclick="this.select ();">';
104
  $ws_plugin__s2member_temp_s = trim (c_ws_plugin__s2member_utilities::evl (file_get_contents (dirname (dirname (__FILE__)) . "/templates/buttons/paypal-checkout-button.php")));
105
  $ws_plugin__s2member_temp_s = preg_replace ("/%%endpoint%%/", c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr (($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["paypal_sandbox"]) ? "www.sandbox.paypal.com" : "www.paypal.com")), $ws_plugin__s2member_temp_s);
106
  $ws_plugin__s2member_temp_s = preg_replace ("/%%paypal_business%%/", c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["paypal_business"])), $ws_plugin__s2member_temp_s);
108
  $ws_plugin__s2member_temp_s = preg_replace ("/%%level%%/", c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr ($n)), $ws_plugin__s2member_temp_s);
109
  $ws_plugin__s2member_temp_s = preg_replace ("/%%level_label%%/", c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["level" . $n . "_label"])), $ws_plugin__s2member_temp_s);
110
  $ws_plugin__s2member_temp_s = preg_replace ("/%%cancel_return%%/", c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr (home_url ("/"))), $ws_plugin__s2member_temp_s);
111
+ $ws_plugin__s2member_temp_s = preg_replace ("/%%notify_url%%/", c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr (home_url ("/?s2member_paypal_notify=1"))), $ws_plugin__s2member_temp_s);
112
+ $ws_plugin__s2member_temp_s = preg_replace ("/%%return%%/", c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr (home_url ("/?s2member_paypal_return=1"))), $ws_plugin__s2member_temp_s);
113
  $ws_plugin__s2member_temp_s = preg_replace ("/%%custom%%/", c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr ($_SERVER["HTTP_HOST"])), $ws_plugin__s2member_temp_s);
114
  $ws_plugin__s2member_temp_s = preg_replace ("/%%images%%/", c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr ($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["dir_url"] . "/images")), $ws_plugin__s2member_temp_s);
115
+ $ws_plugin__s2member_temp_s = preg_replace ("/%%wpurl%%/", c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr (home_url ())), $ws_plugin__s2member_temp_s);
116
  echo format_to_edit ($ws_plugin__s2member_temp_s);
117
  echo '</textarea><br />' . "\n";
118
  echo '&uarr; <em>This <span class="ws-menu-page-hilite">may contain PHP code too</span>; so be careful if you use this.</em>' . "\n";
198
  $ws_plugin__s2member_temp_s = preg_replace ("/%%level_label%% /", c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["level1_label"])), $ws_plugin__s2member_temp_s);
199
  $ws_plugin__s2member_temp_s = preg_replace ("/%%custom%%/", c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr ($_SERVER["HTTP_HOST"])), $ws_plugin__s2member_temp_s);
200
  $ws_plugin__s2member_temp_s = preg_replace ("/\/]$/", 'modify="1" /]', $ws_plugin__s2member_temp_s); // Adds modify="1" to the end of the Shortcode.
201
+ echo '<input type="text" autocomplete="off" id="ws-plugin--s2member-modification-shortcode" value="' . format_to_edit ($ws_plugin__s2member_temp_s) . '" onclick="this.select ();" />' . "\n";
202
 
203
  echo '<div' . ((is_multisite () && c_ws_plugin__s2member_utils_conds::is_multisite_farm () && !is_main_site ()) ? ' style="display:none;"' : '') . '><br />' . "\n";
204
  echo '<strong>Resulting PayPal Button Code:</strong> (ultimately, your Shortcode will produce this snippet)<br />' . "\n";
205
+ echo '<textarea id="ws-plugin--s2member-modification-button" rows="8" wrap="off" onclick="this.select ();">';
206
  $ws_plugin__s2member_temp_s = trim (c_ws_plugin__s2member_utilities::evl (file_get_contents (dirname (dirname (__FILE__)) . "/templates/buttons/paypal-checkout-button.php")));
207
  $ws_plugin__s2member_temp_s = preg_replace ('/name\="modify" value\="(.*?)"/', 'name="modify" value="1"', $ws_plugin__s2member_temp_s);
208
  $ws_plugin__s2member_temp_s = preg_replace ("/%%endpoint%%/", c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr (($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["paypal_sandbox"]) ? "www.sandbox.paypal.com" : "www.paypal.com")), $ws_plugin__s2member_temp_s);
211
  $ws_plugin__s2member_temp_s = preg_replace ("/%%level%%/", c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr ("1")), $ws_plugin__s2member_temp_s);
212
  $ws_plugin__s2member_temp_s = preg_replace ("/%%level_label%% /", c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["level1_label"])), $ws_plugin__s2member_temp_s);
213
  $ws_plugin__s2member_temp_s = preg_replace ("/%%cancel_return%%/", c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr (home_url ("/"))), $ws_plugin__s2member_temp_s);
214
+ $ws_plugin__s2member_temp_s = preg_replace ("/%%notify_url%%/", c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr (home_url ("/?s2member_paypal_notify=1"))), $ws_plugin__s2member_temp_s);
215
+ $ws_plugin__s2member_temp_s = preg_replace ("/%%return%%/", c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr (home_url ("/?s2member_paypal_return=1"))), $ws_plugin__s2member_temp_s);
216
  $ws_plugin__s2member_temp_s = preg_replace ("/%%custom%%/", c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr ($_SERVER["HTTP_HOST"])), $ws_plugin__s2member_temp_s);
217
  $ws_plugin__s2member_temp_s = preg_replace ("/%%images%%/", c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr ($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["dir_url"] . "/images")), $ws_plugin__s2member_temp_s);
218
+ $ws_plugin__s2member_temp_s = preg_replace ("/%%wpurl%%/", c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr (home_url ())), $ws_plugin__s2member_temp_s);
219
  echo format_to_edit ($ws_plugin__s2member_temp_s);
220
  echo '</textarea><br />' . "\n";
221
  echo '&uarr; <em>This <span class="ws-menu-page-hilite">may contain PHP code too</span>; so be careful if you use this.</em>' . "\n";
279
  echo '<strong>WordPress Shortcode:</strong> (recommended for both the WordPress Visual &amp; HTML Editors)<br />' . "\n";
280
  $ws_plugin__s2member_temp_s = trim (c_ws_plugin__s2member_utilities::evl (file_get_contents (dirname (dirname (__FILE__)) . "/templates/shortcodes/paypal-ccaps-checkout-button-shortcode.php")));
281
  $ws_plugin__s2member_temp_s = preg_replace ("/%%custom%%/", c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr ($_SERVER["HTTP_HOST"])), $ws_plugin__s2member_temp_s);
282
+ echo '<input type="text" autocomplete="off" id="ws-plugin--s2member-ccap-shortcode" value="' . format_to_edit ($ws_plugin__s2member_temp_s) . '" onclick="this.select ();" />' . "\n";
283
 
284
  echo '<div' . ((is_multisite () && c_ws_plugin__s2member_utils_conds::is_multisite_farm () && !is_main_site ()) ? ' style="display:none;"' : '') . '><br />' . "\n";
285
  echo '<strong>Resulting PayPal Button Code:</strong> (ultimately, your Shortcode will produce this snippet)<br />' . "\n";
286
+ echo '<textarea id="ws-plugin--s2member-ccap-button" rows="8" wrap="off" onclick="this.select ();">';
287
  $ws_plugin__s2member_temp_s = trim (c_ws_plugin__s2member_utilities::evl (file_get_contents (dirname (dirname (__FILE__)) . "/templates/buttons/paypal-ccaps-checkout-button.php")));
288
  $ws_plugin__s2member_temp_s = preg_replace ("/%%endpoint%%/", c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr (($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["paypal_sandbox"]) ? "www.sandbox.paypal.com" : "www.paypal.com")), $ws_plugin__s2member_temp_s);
289
  $ws_plugin__s2member_temp_s = preg_replace ("/%%paypal_business%%/", c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["paypal_business"])), $ws_plugin__s2member_temp_s);
290
  $ws_plugin__s2member_temp_s = preg_replace ("/%%paypal_merchant_id%%/", c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["paypal_merchant_id"])), $ws_plugin__s2member_temp_s);
291
  $ws_plugin__s2member_temp_s = preg_replace ("/%%cancel_return%%/", c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr (home_url ("/"))), $ws_plugin__s2member_temp_s);
292
+ $ws_plugin__s2member_temp_s = preg_replace ("/%%notify_url%%/", c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr (home_url ("/?s2member_paypal_notify=1"))), $ws_plugin__s2member_temp_s);
293
+ $ws_plugin__s2member_temp_s = preg_replace ("/%%return%%/", c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr (home_url ("/?s2member_paypal_return=1"))), $ws_plugin__s2member_temp_s);
294
  $ws_plugin__s2member_temp_s = preg_replace ("/%%custom%%/", c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr ($_SERVER["HTTP_HOST"])), $ws_plugin__s2member_temp_s);
295
  $ws_plugin__s2member_temp_s = preg_replace ("/%%images%%/", c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr ($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["dir_url"] . "/images")), $ws_plugin__s2member_temp_s);
296
+ $ws_plugin__s2member_temp_s = preg_replace ("/%%wpurl%%/", c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr (home_url ())), $ws_plugin__s2member_temp_s);
297
  echo format_to_edit ($ws_plugin__s2member_temp_s);
298
  echo '</textarea><br />' . "\n";
299
  echo '&uarr; <em>This <span class="ws-menu-page-hilite">may contain PHP code too</span>; so be careful if you use this.</em>' . "\n";
340
  $ws_plugin__s2member_temp_s = preg_replace ("/%%paypal_business%%/", c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["paypal_business"])), $ws_plugin__s2member_temp_s);
341
  $ws_plugin__s2member_temp_s = preg_replace ("/%%paypal_merchant_id%%/", c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["paypal_merchant_id"])), $ws_plugin__s2member_temp_s);
342
  $ws_plugin__s2member_temp_s = preg_replace ("/%%images%%/", c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr ($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["dir_url"] . "/images")), $ws_plugin__s2member_temp_s);
343
+ $ws_plugin__s2member_temp_s = preg_replace ("/%%wpurl%%/", c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr (home_url ())), $ws_plugin__s2member_temp_s);
344
  echo preg_replace ("/\<a/", '<a target="_blank"', $ws_plugin__s2member_temp_s);
345
  echo '</div>' . "\n";
346
  echo '</label>' . "\n";
360
  do_action("ws_plugin__s2member_during_paypal_buttons_page_during_left_sections_during_cancellation_buttons_before_shortcode", get_defined_vars ());
361
  echo '<strong>WordPress Shortcode:</strong> (recommended for both the WordPress Visual &amp; HTML Editors)<br />' . "\n";
362
  $ws_plugin__s2member_temp_s = trim (c_ws_plugin__s2member_utilities::evl (file_get_contents (dirname (dirname (__FILE__)) . "/templates/shortcodes/paypal-cancellation-button-shortcode.php")));
363
+ echo '<input type="text" autocomplete="off" id="ws-plugin--s2member-cancellation-shortcode" value="' . format_to_edit ($ws_plugin__s2member_temp_s) . '" onclick="this.select ();" />' . "\n";
364
 
365
  echo '<div' . ((is_multisite () && c_ws_plugin__s2member_utils_conds::is_multisite_farm () && !is_main_site ()) ? ' style="display:none;"' : '') . '><br />' . "\n";
366
  echo '<strong>Resulting PayPal Button Code:</strong> (ultimately, your Shortcode will produce this snippet)<br />' . "\n";
367
+ echo '<textarea id="ws-plugin--s2member-cancellation-button" rows="8" wrap="off" onclick="this.select ();">';
368
  $ws_plugin__s2member_temp_s = trim (c_ws_plugin__s2member_utilities::evl (file_get_contents (dirname (dirname (__FILE__)) . "/templates/buttons/paypal-cancellation-button.php")));
369
  $ws_plugin__s2member_temp_s = preg_replace ("/%%endpoint%%/", c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr (($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["paypal_sandbox"]) ? "www.sandbox.paypal.com" : "www.paypal.com")), $ws_plugin__s2member_temp_s);
370
  $ws_plugin__s2member_temp_s = preg_replace ("/%%paypal_business%%/", c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["paypal_business"])), $ws_plugin__s2member_temp_s);
371
  $ws_plugin__s2member_temp_s = preg_replace ("/%%paypal_merchant_id%%/", c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["paypal_merchant_id"])), $ws_plugin__s2member_temp_s);
372
  $ws_plugin__s2member_temp_s = preg_replace ("/%%images%%/", c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr ($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["dir_url"] . "/images")), $ws_plugin__s2member_temp_s);
373
+ $ws_plugin__s2member_temp_s = preg_replace ("/%%wpurl%%/", c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr (home_url ())), $ws_plugin__s2member_temp_s);
374
  echo format_to_edit ($ws_plugin__s2member_temp_s);
375
  echo '</textarea><br />' . "\n";
376
  echo '&uarr; <em>This <span class="ws-menu-page-hilite">may contain PHP code too</span>; so be careful if you use this.</em>' . "\n";
414
  echo '<p>Custom String Value: <input type="text" autocomplete="off" id="ws-plugin--s2member-reg-link-custom" value="' . esc_attr ($_SERVER["HTTP_HOST"]) . '" size="30" /> <a href="#" onclick="alert(\'A Paid Subscription is always associated with a Custom String that is passed through the custom=\\\'\\\'' . c_ws_plugin__s2member_utils_strings::esc_js_sq (esc_attr ($_SERVER["HTTP_HOST"]), 3) . '\\\'\\\' attribute of your Shortcode. This Custom Value, MUST always start with your domain name. However, you can also pipe delimit additional values after your domain, if you need to.\\n\\nFor example:\n' . c_ws_plugin__s2member_utils_strings::esc_js_sq (esc_attr ($_SERVER["HTTP_HOST"]), 3) . '|cv1|cv2|cv3\'); return false;" tabindex="-1">[?]</a> <input type="button" value="Generate Access Link" onclick="ws_plugin__s2member_paypalRegLinkGenerate();" /> <img id="ws-plugin--s2member-reg-link-loading" src="' . esc_attr ($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["dir_url"]) . '/images/ajax-loader.gif" alt="" style="display:none;" /></p>' . "\n";
415
  echo '<p' . ((is_multisite () && c_ws_plugin__s2member_utils_conds::is_multisite_farm () && !is_main_site ()) ? ' style="display:none;"' : '') . '>Custom Capabilities (comma-delimited) <a href="#" onclick="alert(\'Optional. This is VERY advanced.\\nSee: s2Member -› API Scripting -› Custom Capabilities.\'); return false;" tabindex="-1">[?]</a> <input type="text" maxlength="125" autocomplete="off" id="ws-plugin--s2member-reg-link-ccaps" size="40" onkeyup="if(this.value.match(/[^a-z_0-9,]/)) this.value = jQuery.trim (jQuery.trim (this.value).replace (/[ \-]/g, \'_\').replace (/[^a-z_0-9,]/gi, \'\').toLowerCase ());" /></p>' . "\n";
416
  echo '<p>Fixed Term Length (for Buy Now transactions): <input type="text" autocomplete="off" id="ws-plugin--s2member-reg-link-fixed-term" value="" size="10" /> <a href="#" onclick="alert(\'If the Customer purchased Membership through a Buy Now transaction (i.e. there is no Initial/Trial Period and no recurring charges for ongoing access), you may configure a Fixed Term Length in this field. This way the Customer\\\'s Membership Access is automatically revoked by s2Member at the appropriate time. This will be a numeric value, followed by a space, then a single letter.\\n\\nHere are some examples:\\n\\n1 D (this means 1 Day)\\n1 W (this means 1 Week)\\n1 M (this means 1 Month)\\n1 Y (this means 1 Year)\\n1 L (this means 1 Lifetime)\'); return false;">[?]</a></p>' . "\n";
417
+ echo '<p id="ws-plugin--s2member-reg-link" style="display:none;"></p>' . "\n";
418
  echo '</form>' . "\n";
419
  echo '</td>' . "\n";
420
 
490
  echo '<strong>WordPress Shortcode:</strong> (recommended for both the WordPress Visual &amp; HTML Editors)<br />' . "\n";
491
  $ws_plugin__s2member_temp_s = trim (c_ws_plugin__s2member_utilities::evl (file_get_contents (dirname (dirname (__FILE__)) . "/templates/shortcodes/paypal-sp-checkout-button-shortcode.php")));
492
  $ws_plugin__s2member_temp_s = preg_replace ("/%%custom%%/", c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr ($_SERVER["HTTP_HOST"])), $ws_plugin__s2member_temp_s);
493
+ echo '<input type="text" autocomplete="off" id="ws-plugin--s2member-sp-shortcode" value="' . format_to_edit ($ws_plugin__s2member_temp_s) . '" onclick="this.select ();" />' . "\n";
494
 
495
  echo '<div' . ((is_multisite () && c_ws_plugin__s2member_utils_conds::is_multisite_farm () && !is_main_site ()) ? ' style="display:none;"' : '') . '><br />' . "\n";
496
  echo '<strong>Resulting PayPal Button Code:</strong> (ultimately, your Shortcode will produce this snippet)<br />' . "\n";
497
+ echo '<textarea id="ws-plugin--s2member-sp-button" rows="8" wrap="off" onclick="this.select ();">';
498
  $ws_plugin__s2member_temp_s = trim (c_ws_plugin__s2member_utilities::evl (file_get_contents (dirname (dirname (__FILE__)) . "/templates/buttons/paypal-sp-checkout-button.php")));
499
  $ws_plugin__s2member_temp_s = preg_replace ("/%%endpoint%%/", c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr (($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["paypal_sandbox"]) ? "www.sandbox.paypal.com" : "www.paypal.com")), $ws_plugin__s2member_temp_s);
500
  $ws_plugin__s2member_temp_s = preg_replace ("/%%paypal_business%%/", c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["paypal_business"])), $ws_plugin__s2member_temp_s);
501
  $ws_plugin__s2member_temp_s = preg_replace ("/%%paypal_merchant_id%%/", c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["paypal_merchant_id"])), $ws_plugin__s2member_temp_s);
502
  $ws_plugin__s2member_temp_s = preg_replace ("/%%cancel_return%%/", c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr (home_url ("/"))), $ws_plugin__s2member_temp_s);
503
+ $ws_plugin__s2member_temp_s = preg_replace ("/%%notify_url%%/", c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr (home_url ("/?s2member_paypal_notify=1"))), $ws_plugin__s2member_temp_s);
504
+ $ws_plugin__s2member_temp_s = preg_replace ("/%%return%%/", c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr (home_url ("/?s2member_paypal_return=1"))), $ws_plugin__s2member_temp_s);
505
  $ws_plugin__s2member_temp_s = preg_replace ("/%%custom%%/", c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr ($_SERVER["HTTP_HOST"])), $ws_plugin__s2member_temp_s);
506
  $ws_plugin__s2member_temp_s = preg_replace ("/%%images%%/", c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr ($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["dir_url"] . "/images")), $ws_plugin__s2member_temp_s);
507
+ $ws_plugin__s2member_temp_s = preg_replace ("/%%wpurl%%/", c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr (home_url ())), $ws_plugin__s2member_temp_s);
508
  echo format_to_edit ($ws_plugin__s2member_temp_s);
509
  echo '</textarea><br />' . "\n";
510
  echo '&uarr; <em>This <span class="ws-menu-page-hilite">may contain PHP code too</span>; so be careful if you use this.</em>' . "\n";
560
  echo '</optgroup></select> <a href="#" onclick="alert(\'Hold down your `Ctrl` key to select multiples.\\n\\nOptional. If you include Additional Posts/Pages, Customers will still land on your Leading Post/Page; BUT, they\\\'ll ALSO have access to some Additional Posts/Pages that you\\\'ve protected. This gives you the ability to create Post/Page Packages.\\n\\nIn other words, a Customer is sold a Specific Post/Page (they\\\'ll land on your Leading Post/Page after checkout), which might contain links to some other Posts/Pages that you\\\'ve packaged together under one transaction.\\n\\nBundling Additional Posts/Pages into one Package, authenticates the Customer for access to the Additional Posts/Pages automatically (e.g. only one Access Link is needed, and s2Member generates this automatically). However, you will STILL need to design your Leading Post/Page (which is what a Customer will actually land on), with links pointing to the other Posts/Pages. This way your Customers will have clickable links to everything they\\\'ve paid for.\\n\\n*Quick Summary* s2Member sends Customers to your Leading Post/Page, and also authenticates them for access to any Additional Posts/Pages automatically. You handle it from there.\\n\\n*Tip* If there are no Posts/Pages in this menu, it\\\'s because you\\\'ve not configured s2Member for Specific Post/Page Access yet. See: s2Member -› Restriction Options -› Specific Post/Page Access.\'); return false;" tabindex="-1">[?]</a></p>' . "\n";
561
 
562
  echo '<p><select id="ws-plugin--s2member-sp-link-hours">' . trim (c_ws_plugin__s2member_utilities::evl (file_get_contents (dirname (dirname (__FILE__)) . "/templates/options/paypal-sp-hours.php"))) . '</select> <input type="button" value="Generate Access Link" onclick="ws_plugin__s2member_paypalSpLinkGenerate();" /> <img id="ws-plugin--s2member-sp-link-loading" src="' . esc_attr ($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["dir_url"]) . '/images/ajax-loader.gif" alt="" style="display:none;" /></p>' . "\n";
563
+ echo '<p id="ws-plugin--s2member-sp-link" style="display:none;"></p>' . "\n";
564
  echo '</form>' . "\n";
565
  echo '</td>' . "\n";
566
 
includes/menu-pages/paypal-ops.inc.php CHANGED
@@ -349,7 +349,7 @@ if(!class_exists("c_ws_plugin__s2member_menu_page_paypal_ops"))
349
  echo '<h3>PayPal IPN / Instant Payment Notifications (required, please enable)</h3>'."\n";
350
  echo '<p>Log into your PayPal account and navigate to this section:<br /><code>Account Profile -› Instant Payment Notification Preferences</code></p>'."\n";
351
  echo '<p>Edit your IPN settings &amp; turn IPN Notifications: <strong><code>On</code></strong></p>'."\n";
352
- echo '<p>You\'ll need your IPN URL, which is:<br /><code>'.esc_html(site_url("/?s2member_paypal_notify=1")).'</code></p>'."\n";
353
  do_action("ws_plugin__s2member_during_paypal_ops_page_during_left_sections_during_paypal_ipn", get_defined_vars());
354
 
355
  echo '<h3 style="margin:0;">More Information (<a href="#" onclick="jQuery(\'div#ws-plugin--s2member-paypal-ipn-details\').toggle(); return false;" class="ws-dotted-link">click here</a>)</h3>'."\n";
@@ -364,7 +364,7 @@ if(!class_exists("c_ws_plugin__s2member_menu_page_paypal_ops"))
364
  echo '<h3 style="margin:0;">IPN w/ Proxy Key (<a href="#" onclick="jQuery(\'div#ws-plugin--s2member-paypal-ipn-proxy-details\').toggle(); return false;" class="ws-dotted-link">optional, for 3rd-party integrations</a>)</h3>'."\n";
365
  echo '<div id="ws-plugin--s2member-paypal-ipn-proxy-details" style="display:none;">'."\n";
366
  echo '<p>If you\'re using a 3rd-party application that needs to POST simulated IPN transactions to your s2Member installation, you can use this alternate IPN URL, which includes a Proxy Key. This encrypted Proxy Key verifies incoming data being received by s2Member\'s IPN processor. You can change <em>[proxy-gateway]</em> to whatever you like. The <em>[proxy-gateway]</em> value is required. It will be stored by s2Member as the Customer\'s Paid Subscr. Gateway. Your [proxy-gateway] value will also be reflected in s2Member\'s IPN log.</p>'."\n";
367
- echo '<input type="text" autocomplete="off" value="'.format_to_edit(site_url("/?s2member_paypal_notify=1&s2member_paypal_proxy=[proxy-gateway]&s2member_paypal_proxy_verification=".urlencode(c_ws_plugin__s2member_paypal_utilities::paypal_proxy_key_gen()))).'" style="width:99%;" />'."\n";
368
  echo '<p><em>Any 3rd-party application that is sending IPN transactions to your s2Member installation, must ALWAYS include the <code>custom</code> POST variable, and that variable must always start with your installation domain (i.e. custom=<code>'.esc_html($_SERVER["HTTP_HOST"]).'</code>). In addition, the <code>item_number</code> variable, must always match a format that s2Member looks for. Generally speaking, the <code>item_number</code> should be <code>1, 2, 3, or 4</code>, indicating a specific s2Member Level #. However, s2Member also uses some advanced formats in this field. Just to be sure, we suggest creating a PayPal Button with the s2Member Button Generator, and then taking a look at the Full Button Code to see how s2Member expects <code>item_number</code> to be formatted. Other than the aforementioned exceptions; all other POST variables should follow PayPal standards. Please see: <a href="http://www.s2member.com/paypal-ipn-pdt-vars" target="_blank" rel="external">PayPal\'s IPN/PDT reference guide</a> for full documentation.</em></p>'."\n";
369
  do_action("ws_plugin__s2member_during_paypal_ops_page_during_left_sections_during_paypal_ipn_after_proxy", get_defined_vars());
370
  echo '</div>'."\n";
@@ -385,7 +385,7 @@ if(!class_exists("c_ws_plugin__s2member_menu_page_paypal_ops"))
385
  echo '<h3>PayPal PDT Identity Token (required, please enable)</h3>'."\n";
386
  echo '<p>Log into your PayPal account and navigate to this section:<br /><code>Account Profile -› Website Payment Preferences</code></p>'."\n";
387
  echo '<p>Turn the Auto-Return feature: <strong><code>On</code></strong></p>'."\n";
388
- echo '<p>You\'ll need your <a href="'.esc_attr(site_url("/?s2member_paypal_return=1&s2member_paypal_proxy=paypal&s2member_paypal_proxy_use=x-preview")).'" target="_blank" rel="external">Auto-Return URL</a>, which is:<br /><code>'.esc_html(site_url("/?s2member_paypal_return=1")).'</code></p>'."\n";
389
  echo '<p>You MUST also enable PDT (Payment Data Transfer): <strong><code>On</code></strong><br /><em>You\'ll be issued an Identity Token that you MUST enter below.</em></p>'."\n";
390
  do_action("ws_plugin__s2member_during_paypal_ops_page_during_left_sections_during_paypal_pdt", get_defined_vars());
391
 
@@ -888,7 +888,7 @@ if(!class_exists("c_ws_plugin__s2member_menu_page_paypal_ops"))
888
  echo '<p><em>s2Member will not process an EOT until the User has completely used up the time they paid for. In other words, if a User signs up for a monthly Subscription on Jan 1st, and then cancels their Subscription on Jan 15th; technically, they should still be allowed to access the site for another 15 days, and then on Feb 1st, the time they paid for has completely elapsed. At that time, s2Member will remove their Membership privileges; by either demoting them to a Free Subscriber, or deleting their account from the system (based on your configuration). s2Member also calculates one extra day (24 hours) into its equation, just to make sure access is not removed sooner than a Customer might expect.</em></p>'."\n";
889
  do_action("ws_plugin__s2member_during_paypal_ops_page_during_left_sections_during_eot_behavior", get_defined_vars());
890
 
891
- echo '<p id="ws-plugin--s2member-auto-eot-system-enabled-via-cron"'.(($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["auto_eot_system_enabled"] == 2 && (!function_exists("wp_cron") || !wp_get_schedule("ws_plugin__s2member_auto_eot_system__schedule"))) ? '' : ' style="display:none;"').'>If you\'d like to run s2Member\'s Auto-EOT System through a more traditional Cron Job; instead of through <code>WP-Cron</code>, you will need to configure a Cron Job through your server control panel; provided by your hosting company. Set the Cron Job to run <code>once about every 10 minutes to an hour</code>. You\'ll want to configure an HTTP Cron Job that loads this URL:<br /><code>'.esc_html(site_url("/?s2member_auto_eot_system_via_cron=1")).'</code></p>'."\n";
892
 
893
  echo '<table class="form-table">'."\n";
894
  echo '<tbody>'."\n";
349
  echo '<h3>PayPal IPN / Instant Payment Notifications (required, please enable)</h3>'."\n";
350
  echo '<p>Log into your PayPal account and navigate to this section:<br /><code>Account Profile -› Instant Payment Notification Preferences</code></p>'."\n";
351
  echo '<p>Edit your IPN settings &amp; turn IPN Notifications: <strong><code>On</code></strong></p>'."\n";
352
+ echo '<p>You\'ll need your IPN URL, which is:<br /><code>'.esc_html(home_url("/?s2member_paypal_notify=1")).'</code></p>'."\n";
353
  do_action("ws_plugin__s2member_during_paypal_ops_page_during_left_sections_during_paypal_ipn", get_defined_vars());
354
 
355
  echo '<h3 style="margin:0;">More Information (<a href="#" onclick="jQuery(\'div#ws-plugin--s2member-paypal-ipn-details\').toggle(); return false;" class="ws-dotted-link">click here</a>)</h3>'."\n";
364
  echo '<h3 style="margin:0;">IPN w/ Proxy Key (<a href="#" onclick="jQuery(\'div#ws-plugin--s2member-paypal-ipn-proxy-details\').toggle(); return false;" class="ws-dotted-link">optional, for 3rd-party integrations</a>)</h3>'."\n";
365
  echo '<div id="ws-plugin--s2member-paypal-ipn-proxy-details" style="display:none;">'."\n";
366
  echo '<p>If you\'re using a 3rd-party application that needs to POST simulated IPN transactions to your s2Member installation, you can use this alternate IPN URL, which includes a Proxy Key. This encrypted Proxy Key verifies incoming data being received by s2Member\'s IPN processor. You can change <em>[proxy-gateway]</em> to whatever you like. The <em>[proxy-gateway]</em> value is required. It will be stored by s2Member as the Customer\'s Paid Subscr. Gateway. Your [proxy-gateway] value will also be reflected in s2Member\'s IPN log.</p>'."\n";
367
+ echo '<input type="text" autocomplete="off" value="'.format_to_edit(home_url("/?s2member_paypal_notify=1&s2member_paypal_proxy=[proxy-gateway]&s2member_paypal_proxy_verification=".urlencode(c_ws_plugin__s2member_paypal_utilities::paypal_proxy_key_gen()))).'" style="width:99%;" />'."\n";
368
  echo '<p><em>Any 3rd-party application that is sending IPN transactions to your s2Member installation, must ALWAYS include the <code>custom</code> POST variable, and that variable must always start with your installation domain (i.e. custom=<code>'.esc_html($_SERVER["HTTP_HOST"]).'</code>). In addition, the <code>item_number</code> variable, must always match a format that s2Member looks for. Generally speaking, the <code>item_number</code> should be <code>1, 2, 3, or 4</code>, indicating a specific s2Member Level #. However, s2Member also uses some advanced formats in this field. Just to be sure, we suggest creating a PayPal Button with the s2Member Button Generator, and then taking a look at the Full Button Code to see how s2Member expects <code>item_number</code> to be formatted. Other than the aforementioned exceptions; all other POST variables should follow PayPal standards. Please see: <a href="http://www.s2member.com/paypal-ipn-pdt-vars" target="_blank" rel="external">PayPal\'s IPN/PDT reference guide</a> for full documentation.</em></p>'."\n";
369
  do_action("ws_plugin__s2member_during_paypal_ops_page_during_left_sections_during_paypal_ipn_after_proxy", get_defined_vars());
370
  echo '</div>'."\n";
385
  echo '<h3>PayPal PDT Identity Token (required, please enable)</h3>'."\n";
386
  echo '<p>Log into your PayPal account and navigate to this section:<br /><code>Account Profile -› Website Payment Preferences</code></p>'."\n";
387
  echo '<p>Turn the Auto-Return feature: <strong><code>On</code></strong></p>'."\n";
388
+ echo '<p>You\'ll need your <a href="'.esc_attr(home_url("/?s2member_paypal_return=1&s2member_paypal_proxy=paypal&s2member_paypal_proxy_use=x-preview")).'" target="_blank" rel="external">Auto-Return URL</a>, which is:<br /><code>'.esc_html(home_url("/?s2member_paypal_return=1")).'</code></p>'."\n";
389
  echo '<p>You MUST also enable PDT (Payment Data Transfer): <strong><code>On</code></strong><br /><em>You\'ll be issued an Identity Token that you MUST enter below.</em></p>'."\n";
390
  do_action("ws_plugin__s2member_during_paypal_ops_page_during_left_sections_during_paypal_pdt", get_defined_vars());
391
 
888
  echo '<p><em>s2Member will not process an EOT until the User has completely used up the time they paid for. In other words, if a User signs up for a monthly Subscription on Jan 1st, and then cancels their Subscription on Jan 15th; technically, they should still be allowed to access the site for another 15 days, and then on Feb 1st, the time they paid for has completely elapsed. At that time, s2Member will remove their Membership privileges; by either demoting them to a Free Subscriber, or deleting their account from the system (based on your configuration). s2Member also calculates one extra day (24 hours) into its equation, just to make sure access is not removed sooner than a Customer might expect.</em></p>'."\n";
889
  do_action("ws_plugin__s2member_during_paypal_ops_page_during_left_sections_during_eot_behavior", get_defined_vars());
890
 
891
+ echo '<p id="ws-plugin--s2member-auto-eot-system-enabled-via-cron"'.(($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["auto_eot_system_enabled"] == 2 && (!function_exists("wp_cron") || !wp_get_schedule("ws_plugin__s2member_auto_eot_system__schedule"))) ? '' : ' style="display:none;"').'>If you\'d like to run s2Member\'s Auto-EOT System through a more traditional Cron Job; instead of through <code>WP-Cron</code>, you will need to configure a Cron Job through your server control panel; provided by your hosting company. Set the Cron Job to run <code>once about every 10 minutes to an hour</code>. You\'ll want to configure an HTTP Cron Job that loads this URL:<br /><code>'.esc_html(home_url("/?s2member_auto_eot_system_via_cron=1")).'</code></p>'."\n";
892
 
893
  echo '<table class="form-table">'."\n";
894
  echo '<tbody>'."\n";
includes/menu-pages/scripting.inc.php CHANGED
@@ -497,22 +497,22 @@ if (!class_exists ("c_ws_plugin__s2member_menu_page_scripting"))
497
  echo '<h3>Giving Members The Ability To Modify Their Profile</h3>' . "\n";
498
  echo '<p>s2Member can be configured to redirect Members away from the <a href="' . esc_attr (admin_url ("/profile.php")) . '" target="_blank" rel="external">default Profile Editing Panel</a> that is built into WordPress. When/if a Member attempts to access the default Profile Editing Panel, they\'ll instead, be redirected to the Login Welcome Page that you\'ve configured through s2Member. <strong>Why would I redirect?</strong> Unless you\'ve made some drastic modifications to your WordPress installation, the default Profile Editing Panel that ships with WordPress, is NOT really suited for public access, even by a Member. See: <code>s2Member -› General Options -› Profile Modifications</code>.</p>' . "\n";
499
  echo '<p>So instead of using this default Profile Editing Panel; s2Member creates an added layer of functionality, on top of WordPress. It does this by providing you (as the site owner), with a special Shortcode: <code>[s2Member-Profile /]</code> that you can place into your Login Welcome Page, or any Post/Page for that matter (even into a Text Widget). This Shortcode produces an Inline Profile Editing Form that supports all aspects of s2Member, including Password changes; and any Custom Registration/Profile Fields that you\'ve configured with s2Member.</p>' . "\n";
500
- echo '<p>Alternatively, s2Member also gives you the ability to send your Members to a <a href="' . esc_attr (site_url ("/?s2member_profile=1")) . '" target="_blank" rel="external">special Stand-Alone version</a>. This Stand-Alone version has been designed (with a bare-bones format), intentionally. This makes it possible for you to <a href="#" onclick="if(!window.open(\'' . site_url ("/?s2member_profile=1") . '\', \'_popup\', \'width=600,height=400,left=100,screenX=100,top=100,screenY=100,location=0,menubar=0,toolbar=0,status=0,scrollbars=1,resizable=1\')) alert(\'Please disable popup blockers and try again!\'); return false;" rel="external">open it up in a popup window</a>, or embed it into your Login Welcome Page using an IFRAME. Code samples are provided below.</p>' . "\n";
501
  do_action("ws_plugin__s2member_during_scripting_page_during_left_sections_during_profile_modifications", get_defined_vars ());
502
 
503
  echo '<div class="ws-menu-page-hr"></div>' . "\n";
504
 
505
  echo '<p><strong>Shortcode:</strong> for an Inline Profile Modification Form:<br />' . "\n";
506
- echo '<p><input type="text" autocomplete="off" value="' . format_to_edit ('[s2Member-Profile /]') . '" class="monospace" onclick="this.select ();" /></p>' . "\n";
507
 
508
  echo '<p style="margin-top:20px;"><strong>Stand-Alone / Code Sample</strong> (standard link tag):</p>' . "\n";
509
- echo '<p><input type="text" autocomplete="off" value="' . format_to_edit (preg_replace ("/\<\?php echo S2MEMBER_CURRENT_USER_PROFILE_MODIFICATION_PAGE_URL; \?\>/", c_ws_plugin__s2member_utils_strings::esc_refs (site_url ("/?s2member_profile=1")), file_get_contents (dirname (__FILE__) . "/code-samples/current-user-profile-modification-page-url-1-ops.x-php"))) . '" class="monospace" onclick="this.select ();" /></p>' . "\n";
510
 
511
  echo '<p style="margin-top:20px;"><strong>Stand-Alone / Code Sample</strong> (open the link in a popup window):</p>' . "\n";
512
- echo '<p><input type="text" autocomplete="off" value="' . format_to_edit (preg_replace ("/\<\?php echo S2MEMBER_CURRENT_USER_PROFILE_MODIFICATION_PAGE_URL; \?\>/", c_ws_plugin__s2member_utils_strings::esc_refs (site_url ("/?s2member_profile=1")), file_get_contents (dirname (__FILE__) . "/code-samples/current-user-profile-modification-page-url-2-ops.x-php"))) . '" class="monospace" onclick="this.select ();" /></p>' . "\n";
513
 
514
  echo '<p style="margin-top:20px;"><strong>Stand-Alone / Code Sample</strong> (embed the Form with an IFRAME tag):</p>' . "\n";
515
- echo '<p><input type="text" autocomplete="off" value="' . format_to_edit (preg_replace ("/\<\?php echo S2MEMBER_CURRENT_USER_PROFILE_MODIFICATION_PAGE_URL; \?\>/", c_ws_plugin__s2member_utils_strings::esc_refs (site_url ("/?s2member_profile=1")), file_get_contents (dirname (__FILE__) . "/code-samples/current-user-profile-modification-page-url-3-ops.x-php"))) . '" class="monospace" onclick="this.select ();" /></p>' . "\n";
516
  echo '</div>' . "\n";
517
 
518
  echo '</div>' . "\n";
497
  echo '<h3>Giving Members The Ability To Modify Their Profile</h3>' . "\n";
498
  echo '<p>s2Member can be configured to redirect Members away from the <a href="' . esc_attr (admin_url ("/profile.php")) . '" target="_blank" rel="external">default Profile Editing Panel</a> that is built into WordPress. When/if a Member attempts to access the default Profile Editing Panel, they\'ll instead, be redirected to the Login Welcome Page that you\'ve configured through s2Member. <strong>Why would I redirect?</strong> Unless you\'ve made some drastic modifications to your WordPress installation, the default Profile Editing Panel that ships with WordPress, is NOT really suited for public access, even by a Member. See: <code>s2Member -› General Options -› Profile Modifications</code>.</p>' . "\n";
499
  echo '<p>So instead of using this default Profile Editing Panel; s2Member creates an added layer of functionality, on top of WordPress. It does this by providing you (as the site owner), with a special Shortcode: <code>[s2Member-Profile /]</code> that you can place into your Login Welcome Page, or any Post/Page for that matter (even into a Text Widget). This Shortcode produces an Inline Profile Editing Form that supports all aspects of s2Member, including Password changes; and any Custom Registration/Profile Fields that you\'ve configured with s2Member.</p>' . "\n";
500
+ echo '<p>Alternatively, s2Member also gives you the ability to send your Members to a <a href="' . esc_attr (home_url ("/?s2member_profile=1")) . '" target="_blank" rel="external">special Stand-Alone version</a>. This Stand-Alone version has been designed (with a bare-bones format), intentionally. This makes it possible for you to <a href="#" onclick="if(!window.open(\'' . home_url ("/?s2member_profile=1") . '\', \'_popup\', \'width=600,height=400,left=100,screenX=100,top=100,screenY=100,location=0,menubar=0,toolbar=0,status=0,scrollbars=1,resizable=1\')) alert(\'Please disable popup blockers and try again!\'); return false;" rel="external">open it up in a popup window</a>, or embed it into your Login Welcome Page using an IFRAME. Code samples are provided below.</p>' . "\n";
501
  do_action("ws_plugin__s2member_during_scripting_page_during_left_sections_during_profile_modifications", get_defined_vars ());
502
 
503
  echo '<div class="ws-menu-page-hr"></div>' . "\n";
504
 
505
  echo '<p><strong>Shortcode:</strong> for an Inline Profile Modification Form:<br />' . "\n";
506
+ echo '<p><input type="text" autocomplete="off" value="' . format_to_edit ('[s2Member-Profile /]') . '" onclick="this.select ();" /></p>' . "\n";
507
 
508
  echo '<p style="margin-top:20px;"><strong>Stand-Alone / Code Sample</strong> (standard link tag):</p>' . "\n";
509
+ echo '<p><input type="text" autocomplete="off" value="' . format_to_edit (preg_replace ("/\<\?php echo S2MEMBER_CURRENT_USER_PROFILE_MODIFICATION_PAGE_URL; \?\>/", c_ws_plugin__s2member_utils_strings::esc_refs (home_url ("/?s2member_profile=1")), file_get_contents (dirname (__FILE__) . "/code-samples/current-user-profile-modification-page-url-1-ops.x-php"))) . '" class="monospace" onclick="this.select ();" /></p>' . "\n";
510
 
511
  echo '<p style="margin-top:20px;"><strong>Stand-Alone / Code Sample</strong> (open the link in a popup window):</p>' . "\n";
512
+ echo '<p><input type="text" autocomplete="off" value="' . format_to_edit (preg_replace ("/\<\?php echo S2MEMBER_CURRENT_USER_PROFILE_MODIFICATION_PAGE_URL; \?\>/", c_ws_plugin__s2member_utils_strings::esc_refs (home_url ("/?s2member_profile=1")), file_get_contents (dirname (__FILE__) . "/code-samples/current-user-profile-modification-page-url-2-ops.x-php"))) . '" class="monospace" onclick="this.select ();" /></p>' . "\n";
513
 
514
  echo '<p style="margin-top:20px;"><strong>Stand-Alone / Code Sample</strong> (embed the Form with an IFRAME tag):</p>' . "\n";
515
+ echo '<p><input type="text" autocomplete="off" value="' . format_to_edit (preg_replace ("/\<\?php echo S2MEMBER_CURRENT_USER_PROFILE_MODIFICATION_PAGE_URL; \?\>/", c_ws_plugin__s2member_utils_strings::esc_refs (home_url ("/?s2member_profile=1")), file_get_contents (dirname (__FILE__) . "/code-samples/current-user-profile-modification-page-url-3-ops.x-php"))) . '" class="monospace" onclick="this.select ();" /></p>' . "\n";
516
  echo '</div>' . "\n";
517
 
518
  echo '</div>' . "\n";
includes/menu-pages/trk-ops.inc.php CHANGED
@@ -78,7 +78,7 @@ if (!class_exists ("c_ws_plugin__s2member_menu_page_trk_ops"))
78
  echo '<tr>' . "\n";
79
 
80
  echo '<td>' . "\n";
81
- echo '<textarea name="ws_plugin__s2member_signup_tracking_codes" id="ws-plugin--s2member-signup-tracking-codes" rows="8" wrap="off" spellcheck="false" class="monospace">' . format_to_edit ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["signup_tracking_codes"]) . '</textarea><br />' . "\n";
82
  echo 'Any valid XHTML / JavaScript' . ((is_multisite () && c_ws_plugin__s2member_utils_conds::is_multisite_farm () && !is_main_site ()) ? '' : ' (or even PHP)') . ' code will work just fine here. Just try not to put anything here that would actually be visible to the Customer. Things like 1x1 pixel images that load up silently and/or JavaScript tracking routines will be fine. Google Analytics code works just fine, AdSense performance tracking, as well as Yahoo tracking and other affiliate network codes are all OK here.<br /><br />' . "\n";
83
  echo '<strong>You can also use these special Replacement Codes if you need them:</strong>' . "\n";
84
  echo '<ul class="ws-menu-page-li-margins">' . "\n";
@@ -163,7 +163,7 @@ if (!class_exists ("c_ws_plugin__s2member_menu_page_trk_ops"))
163
  echo '<tr>' . "\n";
164
 
165
  echo '<td>' . "\n";
166
- echo '<textarea name="ws_plugin__s2member_modification_tracking_codes" id="ws-plugin--s2member-modification-tracking-codes" rows="8" wrap="off" spellcheck="false" class="monospace">' . format_to_edit ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["modification_tracking_codes"]) . '</textarea><br />' . "\n";
167
  echo 'Any valid XHTML / JavaScript' . ((is_multisite () && c_ws_plugin__s2member_utils_conds::is_multisite_farm () && !is_main_site ()) ? '' : ' (or even PHP)') . ' code will work just fine here. Just try not to put anything here that would actually be visible to the Customer. Things like 1x1 pixel images that load up silently and/or JavaScript tracking routines will be fine. Google Analytics code works just fine, AdSense performance tracking, as well as Yahoo tracking and other affiliate network codes are all OK here.<br /><br />' . "\n";
168
  echo '<strong>You can also use these special Replacement Codes if you need them:</strong>' . "\n";
169
  echo '<ul class="ws-menu-page-li-margins">' . "\n";
@@ -259,7 +259,7 @@ if (!class_exists ("c_ws_plugin__s2member_menu_page_trk_ops"))
259
  echo '<tr>' . "\n";
260
 
261
  echo '<td>' . "\n";
262
- echo '<textarea name="ws_plugin__s2member_ccap_tracking_codes" id="ws-plugin--s2member-ccap-tracking-codes" rows="8" wrap="off" spellcheck="false" class="monospace">' . format_to_edit ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["ccap_tracking_codes"]) . '</textarea><br />' . "\n";
263
  echo 'Any valid XHTML / JavaScript' . ((is_multisite () && c_ws_plugin__s2member_utils_conds::is_multisite_farm () && !is_main_site ()) ? '' : ' (or even PHP)') . ' code will work just fine here. Just try not to put anything here that would actually be visible to the Customer. Things like 1x1 pixel images that load up silently and/or JavaScript tracking routines will be fine. Google Analytics code works just fine, AdSense performance tracking, as well as Yahoo tracking and other affiliate network codes are all OK here.<br /><br />' . "\n";
264
  echo '<strong>You can also use these special Replacement Codes if you need them:</strong>' . "\n";
265
  echo '<ul class="ws-menu-page-li-margins">' . "\n";
@@ -349,7 +349,7 @@ if (!class_exists ("c_ws_plugin__s2member_menu_page_trk_ops"))
349
  echo '<tr>' . "\n";
350
 
351
  echo '<td>' . "\n";
352
- echo '<textarea name="ws_plugin__s2member_sp_tracking_codes" id="ws-plugin--s2member-sp-tracking-codes" rows="8" wrap="off" spellcheck="false" class="monospace">' . format_to_edit ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["sp_tracking_codes"]) . '</textarea><br />' . "\n";
353
  echo 'Any valid XHTML / JavaScript' . ((is_multisite () && c_ws_plugin__s2member_utils_conds::is_multisite_farm () && !is_main_site ()) ? '' : ' (or even PHP)') . ' code will work just fine here. Just try not to put anything here that would actually be visible to the Customer. Things like 1x1 pixel images that load up silently and/or JavaScript tracking routines will be fine. Google Analytics code works just fine, AdSense performance tracking, as well as Yahoo tracking and other affiliate network codes are all OK here.<br /><br />' . "\n";
354
  echo '<strong>You can also use these special Replacement Codes if you need them:</strong>' . "\n";
355
  echo '<ul class="ws-menu-page-li-margins">' . "\n";
@@ -414,7 +414,7 @@ if (!class_exists ("c_ws_plugin__s2member_menu_page_trk_ops"))
414
 
415
  echo '<div class="ws-menu-page-section ws-plugin--s2member-idev-section">' . "\n";
416
  echo '<h3>Integrating iDevAffiliate (affiliate program management)</h3>' . "\n";
417
- echo '<a href="http://www.s2member.com/idev-affiliate" target="_blank"><img src="' . esc_attr ($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["dir_url"]) . '/images/idev-logo.gif" class="ws-menu-page-right screenshot" style="width:125px; height:125px; border:0;" alt="." /></a>' . "\n";
418
  echo '<p>Adding affiliate tracking software to your site is one of the most effective ways to achieve more sales, more traffic, and more search engine ranking. <a href="http://www.s2member.com/idev-affiliate" target="_blank" rel="external">iDevAffiliate</a> (an affiliate management portal), installs in just minutes, and can be integrated seamlessly with s2Member. We recommend <a href="http://www.s2member.com/idev-affiliate" target="_blank" rel="external">iDevAffiliate Standard</a> ( $99 ) because of its proven track record, and its ability to integrate with s2Member using a variety of techniques. The most popular being a Hidden Image Tag.</p>' . "\n";
419
  echo '<p>If you choose to <a href="http://www.s2member.com/idev-affiliate" target="_blank" rel="external">install iDevAffiliate</a>, you will need to configure your <code>iDevAffiliate -› Shopping Cart Integration</code>. Please choose <code>Generic Tracking Pixel</code>. Then, grab your Hidden Image Tag, and pop the code provided by iDevAffiliate into one of the fields for Tracking Codes <em>(at the top of this page)</em>. You MUST also add Replacement Codes to your Hidden Image Tag. To save you some trouble, we\'ve provided some examples below, one for each of s2Member\'s Tracking Code integrations.</p>' . "\n";
420
  do_action("ws_plugin__s2member_during_trk_ops_page_during_left_sections_during_idev", get_defined_vars ());
@@ -463,7 +463,7 @@ if (!class_exists ("c_ws_plugin__s2member_menu_page_trk_ops"))
463
 
464
  echo '<div class="ws-menu-page-section ws-plugin--s2member-shareasale-section">' . "\n";
465
  echo '<h3>Integrating ShareASale (affiliate program management)</h3>' . "\n";
466
- echo '<a href="http://www.s2member.com/shareasale" target="_blank"><img src="' . esc_attr ($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["dir_url"]) . '/images/sas-logo.png" class="ws-menu-page-right screenshot" style="width:125px; height:125px; border:0;" alt="." /></a>' . "\n";
467
  echo '<p>Established in 2000, <a href="http://www.s2member.com/shareasale" target="_blank" rel="external">ShareASale</a> provides award winning technology and service; which will enable you to connect with a network of established affiliates, as well as recruit new ones. Joining ShareASale, maximizes your ability to reach the greatest number of affiliates, with the least amount of work. At ShareASale, you\'ll have access to an existing affiliate-base. You place your site on the market, and let their existing affiliates promote your products/services.</p>' . "\n";
468
  echo '<p>If you <a href="http://www.s2member.com/shareasale" target="_blank" rel="external">become a Merchant at ShareASale</a>, you will need to configure your <code>ShareASale -› Sale Tracking</code>. Grab your Hidden Image Tag, and pop the code provided by ShareASale into one of the fields for Tracking Codes <em>(at the top of this page)</em>. You MUST also add Replacement Codes to your Hidden Image Tag. To save you some trouble, we\'ve provided some examples below, one for each of s2Member\'s Tracking Code integrations.</p>' . "\n";
469
  do_action("ws_plugin__s2member_during_trk_ops_page_during_left_sections_during_shareasale", get_defined_vars ());
78
  echo '<tr>' . "\n";
79
 
80
  echo '<td>' . "\n";
81
+ echo '<textarea name="ws_plugin__s2member_signup_tracking_codes" id="ws-plugin--s2member-signup-tracking-codes" rows="8" wrap="off" spellcheck="false">' . format_to_edit ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["signup_tracking_codes"]) . '</textarea><br />' . "\n";
82
  echo 'Any valid XHTML / JavaScript' . ((is_multisite () && c_ws_plugin__s2member_utils_conds::is_multisite_farm () && !is_main_site ()) ? '' : ' (or even PHP)') . ' code will work just fine here. Just try not to put anything here that would actually be visible to the Customer. Things like 1x1 pixel images that load up silently and/or JavaScript tracking routines will be fine. Google Analytics code works just fine, AdSense performance tracking, as well as Yahoo tracking and other affiliate network codes are all OK here.<br /><br />' . "\n";
83
  echo '<strong>You can also use these special Replacement Codes if you need them:</strong>' . "\n";
84
  echo '<ul class="ws-menu-page-li-margins">' . "\n";
163
  echo '<tr>' . "\n";
164
 
165
  echo '<td>' . "\n";
166
+ echo '<textarea name="ws_plugin__s2member_modification_tracking_codes" id="ws-plugin--s2member-modification-tracking-codes" rows="8" wrap="off" spellcheck="false">' . format_to_edit ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["modification_tracking_codes"]) . '</textarea><br />' . "\n";
167
  echo 'Any valid XHTML / JavaScript' . ((is_multisite () && c_ws_plugin__s2member_utils_conds::is_multisite_farm () && !is_main_site ()) ? '' : ' (or even PHP)') . ' code will work just fine here. Just try not to put anything here that would actually be visible to the Customer. Things like 1x1 pixel images that load up silently and/or JavaScript tracking routines will be fine. Google Analytics code works just fine, AdSense performance tracking, as well as Yahoo tracking and other affiliate network codes are all OK here.<br /><br />' . "\n";
168
  echo '<strong>You can also use these special Replacement Codes if you need them:</strong>' . "\n";
169
  echo '<ul class="ws-menu-page-li-margins">' . "\n";
259
  echo '<tr>' . "\n";
260
 
261
  echo '<td>' . "\n";
262
+ echo '<textarea name="ws_plugin__s2member_ccap_tracking_codes" id="ws-plugin--s2member-ccap-tracking-codes" rows="8" wrap="off" spellcheck="false">' . format_to_edit ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["ccap_tracking_codes"]) . '</textarea><br />' . "\n";
263
  echo 'Any valid XHTML / JavaScript' . ((is_multisite () && c_ws_plugin__s2member_utils_conds::is_multisite_farm () && !is_main_site ()) ? '' : ' (or even PHP)') . ' code will work just fine here. Just try not to put anything here that would actually be visible to the Customer. Things like 1x1 pixel images that load up silently and/or JavaScript tracking routines will be fine. Google Analytics code works just fine, AdSense performance tracking, as well as Yahoo tracking and other affiliate network codes are all OK here.<br /><br />' . "\n";
264
  echo '<strong>You can also use these special Replacement Codes if you need them:</strong>' . "\n";
265
  echo '<ul class="ws-menu-page-li-margins">' . "\n";
349
  echo '<tr>' . "\n";
350
 
351
  echo '<td>' . "\n";
352
+ echo '<textarea name="ws_plugin__s2member_sp_tracking_codes" id="ws-plugin--s2member-sp-tracking-codes" rows="8" wrap="off" spellcheck="false">' . format_to_edit ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["sp_tracking_codes"]) . '</textarea><br />' . "\n";
353
  echo 'Any valid XHTML / JavaScript' . ((is_multisite () && c_ws_plugin__s2member_utils_conds::is_multisite_farm () && !is_main_site ()) ? '' : ' (or even PHP)') . ' code will work just fine here. Just try not to put anything here that would actually be visible to the Customer. Things like 1x1 pixel images that load up silently and/or JavaScript tracking routines will be fine. Google Analytics code works just fine, AdSense performance tracking, as well as Yahoo tracking and other affiliate network codes are all OK here.<br /><br />' . "\n";
354
  echo '<strong>You can also use these special Replacement Codes if you need them:</strong>' . "\n";
355
  echo '<ul class="ws-menu-page-li-margins">' . "\n";
414
 
415
  echo '<div class="ws-menu-page-section ws-plugin--s2member-idev-section">' . "\n";
416
  echo '<h3>Integrating iDevAffiliate (affiliate program management)</h3>' . "\n";
417
+ echo '<a href="http://www.s2member.com/idev-affiliate" target="_blank"><img src="' . esc_attr ($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["dir_url"]) . '/images/idev-logo.gif" class="ws-menu-page-right ws-menu-page-bordered" style="width:125px; height:125px; border:0;" alt="." /></a>' . "\n";
418
  echo '<p>Adding affiliate tracking software to your site is one of the most effective ways to achieve more sales, more traffic, and more search engine ranking. <a href="http://www.s2member.com/idev-affiliate" target="_blank" rel="external">iDevAffiliate</a> (an affiliate management portal), installs in just minutes, and can be integrated seamlessly with s2Member. We recommend <a href="http://www.s2member.com/idev-affiliate" target="_blank" rel="external">iDevAffiliate Standard</a> ( $99 ) because of its proven track record, and its ability to integrate with s2Member using a variety of techniques. The most popular being a Hidden Image Tag.</p>' . "\n";
419
  echo '<p>If you choose to <a href="http://www.s2member.com/idev-affiliate" target="_blank" rel="external">install iDevAffiliate</a>, you will need to configure your <code>iDevAffiliate -› Shopping Cart Integration</code>. Please choose <code>Generic Tracking Pixel</code>. Then, grab your Hidden Image Tag, and pop the code provided by iDevAffiliate into one of the fields for Tracking Codes <em>(at the top of this page)</em>. You MUST also add Replacement Codes to your Hidden Image Tag. To save you some trouble, we\'ve provided some examples below, one for each of s2Member\'s Tracking Code integrations.</p>' . "\n";
420
  do_action("ws_plugin__s2member_during_trk_ops_page_during_left_sections_during_idev", get_defined_vars ());
463
 
464
  echo '<div class="ws-menu-page-section ws-plugin--s2member-shareasale-section">' . "\n";
465
  echo '<h3>Integrating ShareASale (affiliate program management)</h3>' . "\n";
466
+ echo '<a href="http://www.s2member.com/shareasale" target="_blank"><img src="' . esc_attr ($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["dir_url"]) . '/images/sas-logo.png" class="ws-menu-page-right ws-menu-page-bordered" style="width:125px; height:125px; border:0;" alt="." /></a>' . "\n";
467
  echo '<p>Established in 2000, <a href="http://www.s2member.com/shareasale" target="_blank" rel="external">ShareASale</a> provides award winning technology and service; which will enable you to connect with a network of established affiliates, as well as recruit new ones. Joining ShareASale, maximizes your ability to reach the greatest number of affiliates, with the least amount of work. At ShareASale, you\'ll have access to an existing affiliate-base. You place your site on the market, and let their existing affiliates promote your products/services.</p>' . "\n";
468
  echo '<p>If you <a href="http://www.s2member.com/shareasale" target="_blank" rel="external">become a Merchant at ShareASale</a>, you will need to configure your <code>ShareASale -› Sale Tracking</code>. Grab your Hidden Image Tag, and pop the code provided by ShareASale into one of the fields for Tracking Codes <em>(at the top of this page)</em>. You MUST also add Replacement Codes to your Hidden Image Tag. To save you some trouble, we\'ve provided some examples below, one for each of s2Member\'s Tracking Code integrations.</p>' . "\n";
469
  do_action("ws_plugin__s2member_during_trk_ops_page_during_left_sections_during_shareasale", get_defined_vars ());
includes/translations/s2member.pot CHANGED
@@ -2,9 +2,9 @@
2
  # This file is distributed under the same license as the package.
3
  msgid ""
4
  msgstr ""
5
- "Project-Id-Version: 140816\n"
6
  "Report-Msgid-Bugs-To: http://wordpress.org/tag/s2member\n"
7
- "POT-Creation-Date: 2014-08-14 18:40:57+00:00\n"
8
  "MIME-Version: 1.0\n"
9
  "Content-Type: text/plain; charset=UTF-8\n"
10
  "Content-Transfer-Encoding: 8bit\n"
2
  # This file is distributed under the same license as the package.
3
  msgid ""
4
  msgstr ""
5
+ "Project-Id-Version: 140909\n"
6
  "Report-Msgid-Bugs-To: http://wordpress.org/tag/s2member\n"
7
+ "POT-Creation-Date: 2014-09-09 20:33:14+00:00\n"
8
  "MIME-Version: 1.0\n"
9
  "Content-Type: text/plain; charset=UTF-8\n"
10
  "Content-Transfer-Encoding: 8bit\n"
readme.txt CHANGED
@@ -1,7 +1,7 @@
1
  === s2Member Framework (Member Roles, Capabilities, Membership, PayPal Members) ===
2
 
3
- Version: 140816
4
- Stable tag: 140816
5
 
6
  SSL Compatible: yes
7
  bbPress® Compatible: yes
@@ -159,12 +159,26 @@ Released under the terms of the [GNU General Public License](http://www.gnu.org/
159
 
160
  == Upgrade Notice ==
161
 
162
- = v140816 =
163
 
164
  (Maintenance Release) Upgrade immediately.
165
 
166
  == Changelog ==
167
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
168
  = v140816 =
169
 
170
  * (s2Member/s2Member Pro) **bbPress Forum Compatibility** Woohoo! This release of s2Member improves s2Member's compatibility with bbPress Forums/Topics/Replies. It is now possible to protect a Forum with s2Member, and have all Topics within that Forum protected automatically. No changes necessary to enable this feature. If you protect a bbPress Forum, this is how s2Member will behave automatically. It's a parent/child relationship that s2Member is now compatible with.
1
  === s2Member Framework (Member Roles, Capabilities, Membership, PayPal Members) ===
2
 
3
+ Version: 140909
4
+ Stable tag: 140909
5
 
6
  SSL Compatible: yes
7
  bbPress® Compatible: yes
159
 
160
  == Upgrade Notice ==
161
 
162
+ = v140909 =
163
 
164
  (Maintenance Release) Upgrade immediately.
165
 
166
  == Changelog ==
167
 
168
+ = v140909 =
169
+
170
+ - (s2Member/s2Member Pro) **Compatibility:** Several instances of `site_url()` (a WordPress core function) have been converted to `home_url()` instead. This provides better compatibility with WordPress installations running from a sub-directory. Please see [this GitHub issue](https://github.com/websharks/s2member/issues/293) if you'd like further details.
171
+ - (s2Member Pro) **Bug Fix:** Ampersands; i.e. `&` symbols in a ClickBank button `desc=""` attribute are now converted to the word `and` automatically. The symbol itself causes issues in ClickBank's IPN processing. Fixed in this release. Please see [this GitHub issue](https://github.com/websharks/s2member/issues/253) if you'd like further details.
172
+ - (s2Member) **Bug Fix:** Improving compatibility with Mozilla/Firefox for the default `wp-login.php?action=register` handler. This release corrects an issue where `<select>` fields contained text with too large a font-size for Mozilla browsers to deal with. Please see [this GitHub issue](https://github.com/websharks/s2member/issues/244) if you'd like further details.
173
+ - (s2Member) **WP v4.0 / bbPress Compat.** A conflict between WordPress v4.0, bbPress v2.5.4 and the previous release of s2Member has been resolved. A symptom of this issue was to see the leading topic post missing from your bbPress forum threads.
174
+
175
+ This was a complex issue related to changes in the most recent copy of WordPress where `WP_Query::$is_search` is flagged as `TRUE` when the `s` key `isset()` instead of `!empty()`. s2Member has implemented a workaround so that the conflict will no longer cause this problem for site owners running s2Member/bbPress.
176
+
177
+ However, please note that some other 3rd-party plugins may still conflict in this way; when running the latest version of bbPress under WordPress v4.0. We are working to notify bbPress and other plugin authors about this issue; just to help others avoid the problem. While unconfirmed, some site owners reported that the Relevanssi search plugin may have some trouble with this also.
178
+ For further details, please see <http://bbpress.org/?p=151839>. See also: [this GitHub issue](https://github.com/websharks/s2member/issues/321) if you'd like all of the details regarding this workaround in the s2Member software.
179
+ - (s2Member) **WP v4.0 Compat.** Updating s2Member's use of the now-deprecated `get_all_category_ids()`. Using `get_terms()` instead. Please see [this GitHub issue](https://github.com/websharks/s2member/issues/322) if you'd like further details.
180
+ - (s2Member Pro) **Stripe Bug Fix:** This release corrects an issue with Stripe Pro Forms and a `$0` trial period. A symptom of this bug was to find a customer's Stripe token value missing from their Customer object in the Stripe Dashboard. This issue impacted Pro Forms whenever a 100% free trial was offered (i.e. with a `$0` sale amount). Resolved by this release. Please see [this GitHub issue](https://github.com/websharks/s2member/issues/326) if you'd like the details.
181
+
182
  = v140816 =
183
 
184
  * (s2Member/s2Member Pro) **bbPress Forum Compatibility** Woohoo! This release of s2Member improves s2Member's compatibility with bbPress Forums/Topics/Replies. It is now possible to protect a Forum with s2Member, and have all Topics within that Forum protected automatically. No changes necessary to enable this feature. If you protect a bbPress Forum, this is how s2Member will behave automatically. It's a parent/child relationship that s2Member is now compatible with.
s2member-o.php CHANGED
@@ -1,51 +1,50 @@
1
  <?php
2
  /**
3
- * WordPress with s2Member only.
4
- *
5
- * Copyright: © 2009-2011
6
- * {@link http://www.websharks-inc.com/ WebSharks, Inc.}
7
- * (coded in the USA)
8
- *
9
- * Released under the terms of the GNU General Public License.
10
- * You should have received a copy of the GNU General Public License,
11
- * along with this software. In the main directory, see: /licensing/
12
- * If not, see: {@link http://www.gnu.org/licenses/}.
13
- *
14
- * @package s2Member
15
- * @since 110912
16
- */
17
- include_once dirname (__FILE__) . "/includes/classes/utils-s2o.inc.php";
18
 
19
- if (($ws_plugin__s2member_o["wp_dir"] = c_ws_plugin__s2member_utils_s2o::wp_dir (dirname (__FILE__), dirname ($_SERVER["SCRIPT_FILENAME"]))))
 
 
20
  {
21
- if (($ws_plugin__s2member_o["wp_settings_as"] = c_ws_plugin__s2member_utils_s2o::wp_settings_as ($ws_plugin__s2member_o["wp_dir"], __FILE__)))
22
- {
23
- /**
24
- * Short initialization mode for WordPress.
25
- *
26
- * @package s2Member
27
- * @since 110912
28
- *
29
- * @var bool
30
- */
31
- define ("SHORTINIT", true);
32
- /**
33
- * Flag indicating only s2Member is being loaded.
34
- *
35
- * @package s2Member
36
- * @since 110912
37
- *
38
- * @var bool
39
- */
40
- define ("WS_PLUGIN__S2MEMBER_ONLY", true);
41
- /*
42
- Load WordPress.
43
- */
44
- require($ws_plugin__s2member_o["wp_dir"] . "/wp-load.php");
45
- eval ("?>" . /* Settings after ``SHORTINIT``. */ $ws_plugin__s2member_o["wp_settings_as"]);
46
- }
47
- else // Else fallback on full WordPress.
48
- require($ws_plugin__s2member_o["wp_dir"] . "/wp-load.php");
49
  }
50
- unset($ws_plugin__s2member_o);
51
- ?>
 
 
1
  <?php
2
  /**
3
+ * WordPress with s2Member only.
4
+ *
5
+ * Copyright: © 2009-2011
6
+ * {@link http://www.websharks-inc.com/ WebSharks, Inc.}
7
+ * (coded in the USA)
8
+ *
9
+ * Released under the terms of the GNU General Public License.
10
+ * You should have received a copy of the GNU General Public License,
11
+ * along with this software. In the main directory, see: /licensing/
12
+ * If not, see: {@link http://www.gnu.org/licenses/}.
13
+ *
14
+ * @package s2Member
15
+ * @since 110912
16
+ */
17
+ include_once dirname(__FILE__).'/includes/classes/utils-s2o.inc.php';
18
 
19
+ if(($ws_plugin__s2member_o['wp_dir'] = c_ws_plugin__s2member_utils_s2o::wp_dir(dirname(__FILE__), dirname($_SERVER['SCRIPT_FILENAME']))))
20
+ {
21
+ if(($ws_plugin__s2member_o['wp_settings_as'] = c_ws_plugin__s2member_utils_s2o::wp_settings_as($ws_plugin__s2member_o['wp_dir'], __FILE__)))
22
  {
23
+ /**
24
+ * Short initialization mode for WordPress.
25
+ *
26
+ * @package s2Member
27
+ * @since 110912
28
+ *
29
+ * @var bool
30
+ */
31
+ define ('SHORTINIT', TRUE);
32
+ /**
33
+ * Flag indicating only s2Member is being loaded.
34
+ *
35
+ * @package s2Member
36
+ * @since 110912
37
+ *
38
+ * @var bool
39
+ */
40
+ define ('WS_PLUGIN__S2MEMBER_ONLY', TRUE);
41
+ /*
42
+ Load WordPress.
43
+ */
44
+ require($ws_plugin__s2member_o['wp_dir'].'/wp-load.php');
45
+ eval ('?>'.$ws_plugin__s2member_o['wp_settings_as']); // Settings after ``SHORTINIT``.
 
 
 
 
 
46
  }
47
+ else // Else fallback on full WordPress.
48
+ require($ws_plugin__s2member_o['wp_dir'].'/wp-load.php');
49
+ }
50
+ unset($ws_plugin__s2member_o);
s2member.php CHANGED
@@ -1,26 +1,26 @@
1
  <?php
2
  /**
3
- * The main plugin file.
4
- *
5
- * This file loads the plugin after checking
6
- * PHP, WordPress and other compatibility requirements.
7
- *
8
- * Copyright: © 2009-2011
9
- * {@link http://www.websharks-inc.com/ WebSharks, Inc.}
10
- * (coded in the USA)
11
- *
12
- * Released under the terms of the GNU General Public License.
13
- * You should have received a copy of the GNU General Public License,
14
- * along with this software. In the main directory, see: /licensing/
15
- * If not, see: {@link http://www.gnu.org/licenses/}.
16
- *
17
- * @package s2Member
18
- * @since 1.0
19
- */
20
  /* -- This section for WordPress parsing. ------------------------------------------------------------------------------
21
 
22
- Version: 140816
23
- Stable tag: 140816
24
 
25
  SSL Compatible: yes
26
  bbPress Compatible: yes
@@ -64,114 +64,113 @@ Description: s2Member, a powerful (free) membership plugin for WordPress. Protec
64
  Tags: s2, s2member, s2 member, membership, users, user, members, member, subscribers, subscriber, members only, roles, capabilities, capability, register, signup, paypal, paypal pro, pay pal, authorize, authorize.net, google wallet, clickbank, click bank, buddypress, buddy press, bbpress, bb press, shopping cart, cart, checkout, ecommerce
65
 
66
  -- end section for WordPress parsing. ------------------------------------------------------------------------------- */
67
- if(realpath(__FILE__) === realpath($_SERVER["SCRIPT_FILENAME"]))
68
- exit("Do not access this file directly.");
69
  /**
70
- * The installed version of s2Member.
71
- *
72
- * @package s2Member
73
- * @since 3.0
74
- *
75
- * @var string
76
- */
77
- if(!defined("WS_PLUGIN__S2MEMBER_VERSION"))
78
- define("WS_PLUGIN__S2MEMBER_VERSION", "140816" /* !#distro-version#! */);
79
  /**
80
- * Minimum PHP version required to run s2Member.
81
- *
82
- * @package s2Member
83
- * @since 3.0
84
- *
85
- * @var string
86
- */
87
- if(!defined("WS_PLUGIN__S2MEMBER_MIN_PHP_VERSION"))
88
- define("WS_PLUGIN__S2MEMBER_MIN_PHP_VERSION", "5.2" /* !#php-requires-at-least-version#! */);
89
  /**
90
- * Minimum WordPress version required to run s2Member.
91
- *
92
- * @package s2Member
93
- * @since 3.0
94
- *
95
- * @var string
96
- */
97
- if(!defined("WS_PLUGIN__S2MEMBER_MIN_WP_VERSION"))
98
- define("WS_PLUGIN__S2MEMBER_MIN_WP_VERSION", "3.3" /* !#wp-requires-at-least-version#! */);
99
  /**
100
- * Minimum Pro version required by the Framework.
101
- *
102
- * @package s2Member
103
- * @since 3.0
104
- *
105
- * @var string
106
- */
107
- if(!defined("WS_PLUGIN__S2MEMBER_MIN_PRO_VERSION"))
108
- define("WS_PLUGIN__S2MEMBER_MIN_PRO_VERSION", "140816" /* !#distro-version#! */);
109
  /*
110
  Several compatibility checks.
111
  If all pass, load the s2Member plugin.
112
  */
113
- if(version_compare(PHP_VERSION, WS_PLUGIN__S2MEMBER_MIN_PHP_VERSION, ">=") && version_compare(get_bloginfo("version"), WS_PLUGIN__S2MEMBER_MIN_WP_VERSION, ">=") && !isset($GLOBALS["WS_PLUGIN__"]["s2member"]))
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
114
  {
115
- $GLOBALS["WS_PLUGIN__"]["s2member"]["l"] = __FILE__;
116
- /*
117
- Hook before loaded.
118
- */
119
- do_action("ws_plugin__s2member_before_loaded");
120
- /*
121
- System configuraton.
122
- */
123
- include_once dirname(__FILE__)."/includes/syscon.inc.php";
124
- /*
125
- Hooks and Filters.
126
- */
127
- include_once dirname(__FILE__)."/includes/hooks.inc.php";
128
- /*
129
- Hook after system config & Hooks are loaded.
130
- */
131
- do_action("ws_plugin__s2member_config_hooks_loaded");
132
- /*
133
- Load a possible Pro module, if/when available.
134
- */
135
- if(apply_filters("ws_plugin__s2member_load_pro", true) && file_exists(dirname(__FILE__)."-pro/pro-module.php"))
136
- {
137
- include_once dirname(__FILE__)."-pro/pro-module.php";
138
- if(is_dir(WP_PLUGIN_DIR."/codestyling-localization") && !is_dir(dirname(__FILE__)."/s2member-pro") && function_exists("symlink"))
139
- {
140
- // Removing this for now. It causes problems during upgrades.
141
- //@symlink(dirname(__FILE__)."-pro", dirname(__FILE__)."/s2member-pro"); // For CS localization compatibility.
142
- //@chmod(dirname(__FILE__)."/s2member-pro", 0755);
143
- }
144
- }
145
- /*
146
- Configure options and their defaults.
147
- */
148
- ws_plugin__s2member_configure_options_and_their_defaults();
149
- /*
150
- Function includes.
151
- */
152
- include_once dirname(__FILE__)."/includes/funcs.inc.php";
153
- /*
154
- Include Shortcodes.
155
- */
156
- include_once dirname(__FILE__)."/includes/codes.inc.php";
157
- /*
158
- Hooks after loaded.
159
- */
160
- do_action("ws_plugin__s2member_loaded");
161
- do_action("ws_plugin__s2member_after_loaded");
162
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
163
  /*
164
  Else NOT compatible. Do we need admin compatibility errors now?
165
  */
166
  else if(is_admin()) // Admin compatibility errors.
 
 
 
 
 
 
167
  {
168
- if(!version_compare(PHP_VERSION, WS_PLUGIN__S2MEMBER_MIN_PHP_VERSION, ">="))
169
- {
170
- add_action("all_admin_notices", create_function('', 'echo \'<div class="error fade"><p>You need PHP v\' . WS_PLUGIN__S2MEMBER_MIN_PHP_VERSION . \'+ to use the s2Member plugin.</p></div>\';'));
171
- }
172
- else if(!version_compare(get_bloginfo("version"), WS_PLUGIN__S2MEMBER_MIN_WP_VERSION, ">="))
173
- {
174
- add_action("all_admin_notices", create_function('', 'echo \'<div class="error fade"><p>You need WordPress v\' . WS_PLUGIN__S2MEMBER_MIN_WP_VERSION . \'+ to use the s2Member plugin.</p></div>\';'));
175
- }
176
  }
177
- ?>
1
  <?php
2
  /**
3
+ * The main plugin file.
4
+ *
5
+ * This file loads the plugin after checking
6
+ * PHP, WordPress and other compatibility requirements.
7
+ *
8
+ * Copyright: © 2009-2011
9
+ * {@link http://www.websharks-inc.com/ WebSharks, Inc.}
10
+ * (coded in the USA)
11
+ *
12
+ * Released under the terms of the GNU General Public License.
13
+ * You should have received a copy of the GNU General Public License,
14
+ * along with this software. In the main directory, see: /licensing/
15
+ * If not, see: {@link http://www.gnu.org/licenses/}.
16
+ *
17
+ * @package s2Member
18
+ * @since 1.0
19
+ */
20
  /* -- This section for WordPress parsing. ------------------------------------------------------------------------------
21
 
22
+ Version: 140909
23
+ Stable tag: 140909
24
 
25
  SSL Compatible: yes
26
  bbPress Compatible: yes
64
  Tags: s2, s2member, s2 member, membership, users, user, members, member, subscribers, subscriber, members only, roles, capabilities, capability, register, signup, paypal, paypal pro, pay pal, authorize, authorize.net, google wallet, clickbank, click bank, buddypress, buddy press, bbpress, bb press, shopping cart, cart, checkout, ecommerce
65
 
66
  -- end section for WordPress parsing. ------------------------------------------------------------------------------- */
67
+ if(realpath(__FILE__) === realpath($_SERVER['SCRIPT_FILENAME']))
68
+ exit('Do not access this file directly.');
69
  /**
70
+ * The installed version of s2Member.
71
+ *
72
+ * @package s2Member
73
+ * @since 3.0
74
+ *
75
+ * @var string
76
+ */
77
+ if(!defined('WS_PLUGIN__S2MEMBER_VERSION'))
78
+ define('WS_PLUGIN__S2MEMBER_VERSION', '140909' /* !#distro-version#! */);
79
  /**
80
+ * Minimum PHP version required to run s2Member.
81
+ *
82
+ * @package s2Member
83
+ * @since 3.0
84
+ *
85
+ * @var string
86
+ */
87
+ if(!defined('WS_PLUGIN__S2MEMBER_MIN_PHP_VERSION'))
88
+ define('WS_PLUGIN__S2MEMBER_MIN_PHP_VERSION', '5.2' /* !#php-requires-at-least-version#! */);
89
  /**
90
+ * Minimum WordPress version required to run s2Member.
91
+ *
92
+ * @package s2Member
93
+ * @since 3.0
94
+ *
95
+ * @var string
96
+ */
97
+ if(!defined('WS_PLUGIN__S2MEMBER_MIN_WP_VERSION'))
98
+ define('WS_PLUGIN__S2MEMBER_MIN_WP_VERSION', '3.3' /* !#wp-requires-at-least-version#! */);
99
  /**
100
+ * Minimum Pro version required by the Framework.
101
+ *
102
+ * @package s2Member
103
+ * @since 3.0
104
+ *
105
+ * @var string
106
+ */
107
+ if(!defined('WS_PLUGIN__S2MEMBER_MIN_PRO_VERSION'))
108
+ define('WS_PLUGIN__S2MEMBER_MIN_PRO_VERSION', '140909' /* !#distro-version#! */);
109
  /*
110
  Several compatibility checks.
111
  If all pass, load the s2Member plugin.
112
  */
113
+ if(version_compare(PHP_VERSION, WS_PLUGIN__S2MEMBER_MIN_PHP_VERSION, '>=') && version_compare(get_bloginfo('version'), WS_PLUGIN__S2MEMBER_MIN_WP_VERSION, '>=') && !isset($GLOBALS['WS_PLUGIN__']['s2member']))
114
+ {
115
+ $GLOBALS['WS_PLUGIN__']['s2member']['l'] = __FILE__;
116
+ /*
117
+ Hook before loaded.
118
+ */
119
+ do_action('ws_plugin__s2member_before_loaded');
120
+ /*
121
+ System configuraton.
122
+ */
123
+ include_once dirname(__FILE__).'/includes/syscon.inc.php';
124
+ /*
125
+ Hooks and Filters.
126
+ */
127
+ include_once dirname(__FILE__).'/includes/hooks.inc.php';
128
+ /*
129
+ Hook after system config & Hooks are loaded.
130
+ */
131
+ do_action('ws_plugin__s2member_config_hooks_loaded');
132
+ /*
133
+ Load a possible Pro module, if/when available.
134
+ */
135
+ if(apply_filters('ws_plugin__s2member_load_pro', TRUE) && file_exists(dirname(__FILE__).'-pro/pro-module.php'))
136
  {
137
+ include_once dirname(__FILE__).'-pro/pro-module.php';
138
+ if(is_dir(WP_PLUGIN_DIR.'/codestyling-localization') && !is_dir(dirname(__FILE__).'/s2member-pro') && function_exists('symlink'))
139
+ {
140
+ // Removing this for now. It causes problems during upgrades.
141
+ //@symlink(dirname(__FILE__).'-pro', dirname(__FILE__).'/s2member-pro'); // For CS localization compatibility.
142
+ //@chmod(dirname(__FILE__).'/s2member-pro', 0755);
143
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
144
  }
145
+ /*
146
+ Configure options and their defaults.
147
+ */
148
+ ws_plugin__s2member_configure_options_and_their_defaults();
149
+ /*
150
+ Function includes.
151
+ */
152
+ include_once dirname(__FILE__).'/includes/funcs.inc.php';
153
+ /*
154
+ Include Shortcodes.
155
+ */
156
+ include_once dirname(__FILE__).'/includes/codes.inc.php';
157
+ /*
158
+ Hooks after loaded.
159
+ */
160
+ do_action('ws_plugin__s2member_loaded');
161
+ do_action('ws_plugin__s2member_after_loaded');
162
+ }
163
  /*
164
  Else NOT compatible. Do we need admin compatibility errors now?
165
  */
166
  else if(is_admin()) // Admin compatibility errors.
167
+ {
168
+ if(!version_compare(PHP_VERSION, WS_PLUGIN__S2MEMBER_MIN_PHP_VERSION, '>='))
169
+ {
170
+ add_action('all_admin_notices', create_function('', 'echo \'<div class="error fade"><p>You need PHP v\' . WS_PLUGIN__S2MEMBER_MIN_PHP_VERSION . \'+ to use the s2Member plugin.</p></div>\';'));
171
+ }
172
+ else if(!version_compare(get_bloginfo('version'), WS_PLUGIN__S2MEMBER_MIN_WP_VERSION, '>='))
173
  {
174
+ add_action('all_admin_notices', create_function('', 'echo \'<div class="error fade"><p>You need WordPress v\' . WS_PLUGIN__S2MEMBER_MIN_WP_VERSION . \'+ to use the s2Member plugin.</p></div>\';'));
 
 
 
 
 
 
 
175
  }
176
+ }