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

Version Description

Download this release

Release Info

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

Code changes from version 110812 to 110815

Files changed (63) hide show
  1. images/trans-1px.png +0 -0
  2. includes/classes/admin-lockouts.inc.php +30 -16
  3. includes/classes/css-js-in.inc.php +53 -58
  4. includes/classes/custom-reg-fields.inc.php +4 -4
  5. includes/classes/files-in.inc.php +33 -33
  6. includes/classes/list-servers.inc.php +8 -4
  7. includes/classes/menu-pages.inc.php +2 -2
  8. includes/classes/meta-box-security.inc.php +2 -2
  9. includes/classes/paypal-notify-in-subscr-modify-w-level.inc.php +46 -14
  10. includes/classes/paypal-notify-in-subscr-or-wa-w-level.inc.php +51 -19
  11. includes/classes/paypal-notify-in-wa-ccaps-wo-level.inc.php +292 -0
  12. includes/classes/paypal-notify-in-web-accept-sp.inc.php +4 -4
  13. includes/classes/paypal-notify-in.inc.php +5 -1
  14. includes/classes/paypal-return-in-subscr-modify-w-level.inc.php +51 -15
  15. includes/classes/paypal-return-in-subscr-or-wa-w-level.inc.php +46 -10
  16. includes/classes/paypal-return-in-wa-ccaps-wo-level.inc.php +205 -0
  17. includes/classes/paypal-return-in-web-accept-sp.inc.php +1 -1
  18. includes/classes/paypal-return-in.inc.php +5 -1
  19. includes/classes/paypal-utilities.inc.php +2 -1
  20. includes/classes/profile-in.inc.php +3 -3
  21. includes/classes/register-in.inc.php +4 -4
  22. includes/classes/registrations.inc.php +24 -24
  23. includes/classes/sc-paypal-button-in.inc.php +65 -9
  24. includes/classes/sc-profile-in.inc.php +3 -3
  25. includes/classes/sp-access.inc.php +5 -5
  26. includes/classes/tracking-codes.inc.php +118 -11
  27. includes/classes/tracking-cookies-in.inc.php +17 -11
  28. includes/classes/tracking-cookies.inc.php +5 -5
  29. includes/classes/user-new-in.inc.php +3 -3
  30. includes/classes/user-securities.inc.php +14 -11
  31. includes/classes/users-list-in.inc.php +5 -4
  32. includes/classes/utilities.inc.php +19 -0
  33. includes/classes/utils-captchas.inc.php +3 -2
  34. includes/classes/utils-logs.inc.php +2 -2
  35. includes/classes/utils-strings.inc.php +4 -4
  36. includes/functions/api-functions.inc.php +30 -12
  37. includes/hooks.inc.php +8 -2
  38. includes/menu-pages/api-ops.inc.php +45 -24
  39. includes/menu-pages/code-samples/idev-ccap-tracking-code.php +3 -0
  40. includes/menu-pages/code-samples/idev-modification-tracking-code.php +3 -0
  41. includes/menu-pages/code-samples/sas-ccap-tracking-code.php +3 -0
  42. includes/menu-pages/code-samples/sas-modification-tracking-code.php +3 -0
  43. includes/menu-pages/gen-ops.inc.php +4 -4
  44. includes/menu-pages/menu-pages-min.js +1 -1
  45. includes/menu-pages/menu-pages-s-min.js +1 -1
  46. includes/menu-pages/menu-pages-s.js +81 -9
  47. includes/menu-pages/menu-pages.css +102 -201
  48. includes/menu-pages/menu-pages.js +45 -48
  49. includes/menu-pages/mms-ops.inc.php +1 -1
  50. includes/menu-pages/paypal-buttons.inc.php +92 -11
  51. includes/menu-pages/paypal-ops.inc.php +4 -3
  52. includes/menu-pages/scripting.inc.php +3 -2
  53. includes/menu-pages/start.inc.php +3 -2
  54. includes/menu-pages/trk-ops.inc.php +220 -11
  55. includes/menu-pages/ws-mlist.inc.php +11 -7
  56. includes/mime-types.ini +0 -1
  57. includes/syscon.inc.php +11 -13
  58. includes/templates/buttons/paypal-ccaps-checkout-button.html +30 -0
  59. includes/templates/options/paypal-membership-ccap-terms.html +3 -0
  60. includes/templates/shortcodes/paypal-ccaps-checkout-button-shortcode.html +1 -0
  61. ms.txt +3 -3
  62. readme.txt +22 -62
  63. s2member.php +8 -8
images/trans-1px.png ADDED
Binary file
includes/classes/admin-lockouts.inc.php CHANGED
@@ -15,7 +15,7 @@
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_admin_lockouts"))
21
  {
@@ -47,10 +47,10 @@ if (!class_exists ("c_ws_plugin__s2member_admin_lockouts"))
47
  if (apply_filters ("ws_plugin__s2member_admin_lockout", true, get_defined_vars ())) /* Give Filters a chance too. */
48
  {
49
  if ($special_redirection_url = c_ws_plugin__s2member_login_redirects::login_redirection_url ())
50
- wp_redirect ($special_redirection_url); /* Special Redirection. */
51
  /**/
52
  else /* Else we use the Login Welcome Page configured for s2Member. */
53
- wp_redirect (get_page_link ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["login_welcome_page"]));
54
  /**/
55
  exit (); /* Clean exit. */
56
  }
@@ -80,28 +80,42 @@ if (!class_exists ("c_ws_plugin__s2member_admin_lockouts"))
80
  if (apply_filters ("ws_plugin__s2member_admin_lockout", true, get_defined_vars ())) /* Give Filters a chance too. */
81
  {
82
  if ($special_redirection_url = c_ws_plugin__s2member_login_redirects::login_redirection_url ())
83
- $lwp = $special_redirection_url; /* Use Special Redirection URL. */
84
  /**/
85
  else /* Else we use the Login Welcome Page configured for s2Member. */
86
  $lwp = get_page_link ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["login_welcome_page"]);
87
  /**/
88
- if (isset ($wp_admin_bar->menu->{"my-account-with-avatar"}["href"]) && isset ($wp_admin_bar->menu->{"my-account-with-avatar"}["children"]->{"edit-my-profile"}["href"]))
89
  {
90
- $wp_admin_bar->menu->{"my-account-with-avatar"}["href"] = $lwp;
91
- $wp_admin_bar->menu->{"my-account-with-avatar"}["children"]->{"edit-my-profile"}["href"] = $lwp;
92
- unset ($wp_admin_bar->menu->{"my-account-with-avatar"}["children"]->{"dashboard"});
 
 
 
 
 
 
 
 
 
 
93
  }
94
  /**/
95
- if (isset ($wp_admin_bar->menu->{"my-blogs"}["href"]) && isset ($wp_admin_bar->menu->{"my-blogs"}["children"]) && is_object ($wp_admin_bar->menu->{"my-blogs"}["children"]))
 
 
 
96
  {
97
- $wp_admin_bar->menu->{"my-blogs"}["href"] = "#"; /* Void this link by converting to #. */
98
  /**/
99
- foreach ($wp_admin_bar->menu->{"my-blogs"}["children"] as &$blog)
100
- if (is_array ($blog) && isset ($blog["href"]) && isset ($blog["children"]) && is_object ($blog["children"]))
101
- {
102
- $blog["href"] = preg_replace ("/\/wp-admin/", "", $blog["href"]);
103
- unset ($blog["children"]); /* Cause all we need is the link. */
104
- }
 
105
  }
106
  }
107
  /**/
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_admin_lockouts"))
21
  {
47
  if (apply_filters ("ws_plugin__s2member_admin_lockout", true, get_defined_vars ())) /* Give Filters a chance too. */
48
  {
49
  if ($special_redirection_url = c_ws_plugin__s2member_login_redirects::login_redirection_url ())
50
+ wp_redirect($special_redirection_url); /* Special Redirection. */
51
  /**/
52
  else /* Else we use the Login Welcome Page configured for s2Member. */
53
+ wp_redirect(get_page_link ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["login_welcome_page"]));
54
  /**/
55
  exit (); /* Clean exit. */
56
  }
80
  if (apply_filters ("ws_plugin__s2member_admin_lockout", true, get_defined_vars ())) /* Give Filters a chance too. */
81
  {
82
  if ($special_redirection_url = c_ws_plugin__s2member_login_redirects::login_redirection_url ())
83
+ $lwp = $special_redirection_url;
84
  /**/
85
  else /* Else we use the Login Welcome Page configured for s2Member. */
86
  $lwp = get_page_link ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["login_welcome_page"]);
87
  /**/
88
+ if (isset ($wp_admin_bar->menu->{"my-account-with-avatar"})) /* Profile. */
89
  {
90
+ if (isset ($wp_admin_bar->menu->{"my-account-with-avatar"}["href"]))
91
+ $wp_admin_bar->menu->{"my-account-with-avatar"}["href"] = $lwp;
92
+ /**/
93
+ if (isset ($wp_admin_bar->menu->{"my-account-with-avatar"}["children"]->{"edit-profile"}["href"]))
94
+ $wp_admin_bar->menu->{"my-account-with-avatar"}["children"]->{"edit-profile"}["href"] = $lwp;
95
+ /*
96
+ Backward compatibility ( {"edit-my-profile"} ), prior to WordPress® 3.2. */
97
+ if (isset ($wp_admin_bar->menu->{"my-account-with-avatar"}["children"]->{"edit-my-profile"}["href"]))
98
+ $wp_admin_bar->menu->{"my-account-with-avatar"}["children"]->{"edit-my-profile"}["href"] = $lwp;
99
+ /*
100
+ Backward compatibility ( ["children"]->{"dashboard"} ), prior to WordPress® 3.2. */
101
+ if (isset ($wp_admin_bar->menu->{"my-account-with-avatar"}["children"]->{"dashboard"}))
102
+ unset($wp_admin_bar->menu->{"my-account-with-avatar"}["children"]->{"dashboard"});
103
  }
104
  /**/
105
+ if (isset ($wp_admin_bar->menu->{"dashboard"})) /* Dashboard menu, we don't need this. */
106
+ unset($wp_admin_bar->menu->{"dashboard"}); /* Removes this entire menu from the bar. */
107
+ /**/
108
+ if (isset ($wp_admin_bar->menu->{"my-blogs"}["href"])) /* Deals with multiple Blog drop-down. */
109
  {
110
+ $wp_admin_bar->menu->{"my-blogs"}["href"] = "#"; /* Void this link out by converting to `#`. */
111
  /**/
112
+ if (isset ($wp_admin_bar->menu->{"my-blogs"}["children"]) && is_object ($wp_admin_bar->menu->{"my-blogs"}["children"]))
113
+ foreach ($wp_admin_bar->menu->{"my-blogs"}["children"] as &$blog) /* Modify other Blog links in drop-down. */
114
+ if (is_array ($blog) && isset ($blog["href"], $blog["children"]) && is_object ($blog["children"]))
115
+ {
116
+ $blog["href"] = preg_replace ("/\/wp-admin/", "", $blog["href"]);
117
+ unset($blog["children"]); /* Cause all we need is the link. */
118
+ }
119
  }
120
  }
121
  /**/
includes/classes/css-js-in.inc.php CHANGED
@@ -87,102 +87,97 @@ if (!class_exists ("c_ws_plugin__s2member_css_js_in"))
87
  header("Cache-Control: max-age=604800");
88
  header("Pragma: public");
89
  /**/
90
- $g = "var S2MEMBER_VERSION = '" . c_ws_plugin__s2member_utils_strings::esc_sq (S2MEMBER_VERSION) . "',";
91
  /**/
92
- $g .= "S2MEMBER_CURRENT_USER_LOGIN_COUNTER = " . S2MEMBER_CURRENT_USER_LOGIN_COUNTER . ",";
93
  /**/
94
- $g .= "S2MEMBER_CURRENT_USER_IS_LOGGED_IN = " . ((S2MEMBER_CURRENT_USER_IS_LOGGED_IN) ? "true" : "false") . ",";
95
- $g .= "S2MEMBER_CURRENT_USER_IS_LOGGED_IN_AS_MEMBER = " . ((S2MEMBER_CURRENT_USER_IS_LOGGED_IN_AS_MEMBER) ? "true" : "false") . ",";
96
  /**/
97
- $g .= "S2MEMBER_CURRENT_USER_ACCESS_LEVEL = " . S2MEMBER_CURRENT_USER_ACCESS_LEVEL . ",";
98
- $g .= "S2MEMBER_CURRENT_USER_ACCESS_LABEL = '" . c_ws_plugin__s2member_utils_strings::esc_sq (S2MEMBER_CURRENT_USER_ACCESS_LABEL) . "',";
99
  /**/
100
- $g .= "S2MEMBER_CURRENT_USER_SUBSCR_ID = '" . c_ws_plugin__s2member_utils_strings::esc_sq (S2MEMBER_CURRENT_USER_SUBSCR_ID) . "',";
101
- $g .= "S2MEMBER_CURRENT_USER_SUBSCR_OR_WP_ID = '" . c_ws_plugin__s2member_utils_strings::esc_sq (S2MEMBER_CURRENT_USER_SUBSCR_OR_WP_ID) . "',";
102
- $g .= "S2MEMBER_CURRENT_USER_SUBSCR_GATEWAY = '" . c_ws_plugin__s2member_utils_strings::esc_sq (S2MEMBER_CURRENT_USER_SUBSCR_GATEWAY) . "',";
103
- $g .= "S2MEMBER_CURRENT_USER_CUSTOM = '" . c_ws_plugin__s2member_utils_strings::esc_sq (S2MEMBER_CURRENT_USER_CUSTOM) . "',";
104
  /**/
105
- $g .= "S2MEMBER_CURRENT_USER_REGISTRATION_TIME = " . S2MEMBER_CURRENT_USER_REGISTRATION_TIME . ",";
106
- $g .= "S2MEMBER_CURRENT_USER_PAID_REGISTRATION_TIME = " . S2MEMBER_CURRENT_USER_PAID_REGISTRATION_TIME . ",";
107
  /**/
108
- $g .= "S2MEMBER_CURRENT_USER_PAID_REGISTRATION_DAYS = " . S2MEMBER_CURRENT_USER_PAID_REGISTRATION_DAYS . ",";
109
- $g .= "S2MEMBER_CURRENT_USER_REGISTRATION_DAYS = " . S2MEMBER_CURRENT_USER_REGISTRATION_DAYS . ",";
110
  /**/
111
- $g .= "S2MEMBER_CURRENT_USER_DISPLAY_NAME = '" . c_ws_plugin__s2member_utils_strings::esc_sq (S2MEMBER_CURRENT_USER_DISPLAY_NAME) . "',";
112
- $g .= "S2MEMBER_CURRENT_USER_FIRST_NAME = '" . c_ws_plugin__s2member_utils_strings::esc_sq (S2MEMBER_CURRENT_USER_FIRST_NAME) . "',";
113
- $g .= "S2MEMBER_CURRENT_USER_LAST_NAME = '" . c_ws_plugin__s2member_utils_strings::esc_sq (S2MEMBER_CURRENT_USER_LAST_NAME) . "',";
114
  /**/
115
- $g .= "S2MEMBER_CURRENT_USER_LOGIN = '" . c_ws_plugin__s2member_utils_strings::esc_sq (S2MEMBER_CURRENT_USER_LOGIN) . "',";
116
- $g .= "S2MEMBER_CURRENT_USER_EMAIL = '" . c_ws_plugin__s2member_utils_strings::esc_sq (S2MEMBER_CURRENT_USER_EMAIL) . "',";
117
- $g .= "S2MEMBER_CURRENT_USER_IP = '" . c_ws_plugin__s2member_utils_strings::esc_sq (S2MEMBER_CURRENT_USER_IP) . "',";
118
- $g .= "S2MEMBER_CURRENT_USER_REGISTRATION_IP = '" . c_ws_plugin__s2member_utils_strings::esc_sq (S2MEMBER_CURRENT_USER_REGISTRATION_IP) . "',";
119
  /**/
120
- $g .= "S2MEMBER_CURRENT_USER_ID = " . S2MEMBER_CURRENT_USER_ID . ",";
121
- $g .= "S2MEMBER_CURRENT_USER_FIELDS = " . S2MEMBER_CURRENT_USER_FIELDS . ",";
122
  /**/
123
- $g .= "S2MEMBER_CURRENT_USER_DOWNLOADS_ALLOWED = " . S2MEMBER_CURRENT_USER_DOWNLOADS_ALLOWED . ",";
124
- $g .= "S2MEMBER_CURRENT_USER_DOWNLOADS_ALLOWED_IS_UNLIMITED = " . ((S2MEMBER_CURRENT_USER_DOWNLOADS_ALLOWED_IS_UNLIMITED) ? "true" : "false") . ",";
125
- $g .= "S2MEMBER_CURRENT_USER_DOWNLOADS_CURRENTLY = " . S2MEMBER_CURRENT_USER_DOWNLOADS_CURRENTLY . ",";
126
- $g .= "S2MEMBER_CURRENT_USER_DOWNLOADS_ALLOWED_DAYS = " . S2MEMBER_CURRENT_USER_DOWNLOADS_ALLOWED_DAYS . ",";
127
  /**/
128
- $g .= "S2MEMBER_FILE_DOWNLOAD_LIMIT_EXCEEDED_PAGE_ID = " . S2MEMBER_FILE_DOWNLOAD_LIMIT_EXCEEDED_PAGE_ID . ",";
129
- $g .= "S2MEMBER_MEMBERSHIP_OPTIONS_PAGE_ID = " . S2MEMBER_MEMBERSHIP_OPTIONS_PAGE_ID . ",";
130
- $g .= "S2MEMBER_LOGIN_WELCOME_PAGE_ID = " . S2MEMBER_LOGIN_WELCOME_PAGE_ID . ",";
131
  /**/
132
- $g .= "S2MEMBER_CURRENT_USER_PROFILE_MODIFICATION_PAGE_URL = '" . c_ws_plugin__s2member_utils_strings::esc_sq (S2MEMBER_CURRENT_USER_PROFILE_MODIFICATION_PAGE_URL) . "',";
133
- $g .= "S2MEMBER_FILE_DOWNLOAD_LIMIT_EXCEEDED_PAGE_URL = '" . c_ws_plugin__s2member_utils_strings::esc_sq (S2MEMBER_FILE_DOWNLOAD_LIMIT_EXCEEDED_PAGE_URL) . "',";
134
- $g .= "S2MEMBER_MEMBERSHIP_OPTIONS_PAGE_URL = '" . c_ws_plugin__s2member_utils_strings::esc_sq (S2MEMBER_MEMBERSHIP_OPTIONS_PAGE_URL) . "',";
135
- $g .= "S2MEMBER_LOGIN_WELCOME_PAGE_URL = '" . c_ws_plugin__s2member_utils_strings::esc_sq (S2MEMBER_LOGIN_WELCOME_PAGE_URL) . "',";
136
- $g .= "S2MEMBER_LOGOUT_PAGE_URL = '" . c_ws_plugin__s2member_utils_strings::esc_sq (S2MEMBER_LOGOUT_PAGE_URL) . "',";
137
- $g .= "S2MEMBER_LOGIN_PAGE_URL = '" . c_ws_plugin__s2member_utils_strings::esc_sq (S2MEMBER_LOGIN_PAGE_URL) . "',";
138
  /**/
139
  for ($n = 0; $n <= $GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["levels"]; $n++)
140
  {
141
  if (defined (($S2MEMBER_LEVELn_LABEL = "S2MEMBER_LEVEL" . $n . "_LABEL")))
142
- $g .= $S2MEMBER_LEVELn_LABEL . " = '" . c_ws_plugin__s2member_utils_strings::esc_sq (constant ($S2MEMBER_LEVELn_LABEL)) . "',";
143
  }
144
  /**/
145
  for ($n = 0; $n <= $GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["levels"]; $n++)
146
  {
147
  if (defined (($S2MEMBER_LEVELn_FILE_DOWNLOADS_ALLOWED = "S2MEMBER_LEVEL" . $n . "_FILE_DOWNLOADS_ALLOWED")))
148
- $g .= $S2MEMBER_LEVELn_FILE_DOWNLOADS_ALLOWED . " = " . constant ($S2MEMBER_LEVELn_FILE_DOWNLOADS_ALLOWED) . ",";
149
  }
150
  /**/
151
  for ($n = 0; $n <= $GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["levels"]; $n++)
152
  {
153
  if (defined (($S2MEMBER_LEVELn_FILE_DOWNLOADS_ALLOWED_DAYS = "S2MEMBER_LEVEL" . $n . "_FILE_DOWNLOADS_ALLOWED_DAYS")))
154
- $g .= $S2MEMBER_LEVELn_FILE_DOWNLOADS_ALLOWED_DAYS . " = " . constant ($S2MEMBER_LEVELn_FILE_DOWNLOADS_ALLOWED_DAYS) . ",";
155
  }
156
  /**/
157
- $g .= "S2MEMBER_FILE_DOWNLOAD_INLINE_EXTENSIONS = '" . c_ws_plugin__s2member_utils_strings::esc_sq (S2MEMBER_FILE_DOWNLOAD_INLINE_EXTENSIONS) . "',";
158
  /**/
159
- $g .= "S2MEMBER_REG_EMAIL_FROM_NAME = '" . c_ws_plugin__s2member_utils_strings::esc_sq (S2MEMBER_REG_EMAIL_FROM_NAME) . "',";
160
- $g .= "S2MEMBER_REG_EMAIL_FROM_EMAIL = '" . c_ws_plugin__s2member_utils_strings::esc_sq (S2MEMBER_REG_EMAIL_FROM_EMAIL) . "',";
161
  /**/
162
- $g .= "S2MEMBER_PAYPAL_NOTIFY_URL = '" . c_ws_plugin__s2member_utils_strings::esc_sq (S2MEMBER_PAYPAL_NOTIFY_URL) . "',";
163
- $g .= "S2MEMBER_PAYPAL_RETURN_URL = '" . c_ws_plugin__s2member_utils_strings::esc_sq (S2MEMBER_PAYPAL_RETURN_URL) . "',";
164
  /**/
165
- $g .= "S2MEMBER_PAYPAL_BUSINESS = '" . c_ws_plugin__s2member_utils_strings::esc_sq (S2MEMBER_PAYPAL_BUSINESS) . "',";
166
- $g .= "S2MEMBER_PAYPAL_ENDPOINT = '" . c_ws_plugin__s2member_utils_strings::esc_sq (S2MEMBER_PAYPAL_ENDPOINT) . "',";
167
- $g .= "S2MEMBER_PAYPAL_API_ENDPOINT = '" . c_ws_plugin__s2member_utils_strings::esc_sq (S2MEMBER_PAYPAL_API_ENDPOINT) . "',";
168
  /**/
169
- $g .= "S2MEMBER_VALUE_FOR_PP_INV = Math.round (new Date ().getTime ()) + '~" . c_ws_plugin__s2member_utils_strings::esc_sq (S2MEMBER_CURRENT_USER_IP) . "',";
170
- $g .= "S2MEMBER_VALUE_FOR_PP_INV_GEN = function(){ var invoice = '', formatSeed = function(seed, reqWidth) { seed = parseInt(seed, 10).toString (16); if (reqWidth < seed.length) return seed.slice (seed.length - reqWidth); else if (reqWidth > seed.length) return Array(1 + (reqWidth - seed.length)).join ('0') + seed; return seed; }; if (typeof S2MEMBER_VALUE_FOR_PP_INV_GEN_UNIQUE_SEED === 'undefined') S2MEMBER_VALUE_FOR_PP_INV_GEN_UNIQUE_SEED = Math.floor (Math.random () * 0x75bcd15); S2MEMBER_VALUE_FOR_PP_INV_GEN_UNIQUE_SEED++; invoice = formatSeed(parseInt(new Date ().getTime () / 1000, 10), 8); invoice += formatSeed(S2MEMBER_VALUE_FOR_PP_INV_GEN_UNIQUE_SEED, 5); invoice += '~' + S2MEMBER_CURRENT_USER_IP; return invoice; },";
171
  /**/
172
- $g .= "S2MEMBER_CURRENT_USER_VALUE_FOR_PP_ON0 = '" . c_ws_plugin__s2member_utils_strings::esc_sq (S2MEMBER_CURRENT_USER_VALUE_FOR_PP_ON0) . "',";
173
- $g .= "S2MEMBER_CURRENT_USER_VALUE_FOR_PP_OS0 = '" . c_ws_plugin__s2member_utils_strings::esc_sq (S2MEMBER_CURRENT_USER_VALUE_FOR_PP_OS0) . "',";
174
  /**/
175
- $g .= "S2MEMBER_CURRENT_USER_VALUE_FOR_PP_ON1 = '" . c_ws_plugin__s2member_utils_strings::esc_sq (S2MEMBER_CURRENT_USER_VALUE_FOR_PP_ON1) . "',";
176
- $g .= "S2MEMBER_CURRENT_USER_VALUE_FOR_PP_OS1 = '" . c_ws_plugin__s2member_utils_strings::esc_sq (S2MEMBER_CURRENT_USER_VALUE_FOR_PP_OS1) . "',";
177
- /**/
178
- $g = trim ($g, " ,") . ";"; /* Trim & add semicolon. */
179
  /**/
180
  $u = $GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["dir_url"];
181
  $i = $GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["dir_url"] . "/images";
182
  /**/
183
- echo $g . "\n"; /* Add a line break. */
184
- unset($g); /* Now unset this variable. */
185
- /**/
186
  include_once dirname (dirname (__FILE__)) . "/s2member-min.js";
187
  /**/
188
  do_action ("ws_plugin__s2member_during_js_w_globals", get_defined_vars ());
87
  header("Cache-Control: max-age=604800");
88
  header("Pragma: public");
89
  /**/
90
+ echo "var S2MEMBER_VERSION = '" . c_ws_plugin__s2member_utils_strings::esc_sq (S2MEMBER_VERSION) . "',";
91
  /**/
92
+ echo "S2MEMBER_CURRENT_USER_LOGIN_COUNTER = " . S2MEMBER_CURRENT_USER_LOGIN_COUNTER . ",";
93
  /**/
94
+ echo "S2MEMBER_CURRENT_USER_IS_LOGGED_IN = " . ((S2MEMBER_CURRENT_USER_IS_LOGGED_IN) ? "true" : "false") . ",";
95
+ echo "S2MEMBER_CURRENT_USER_IS_LOGGED_IN_AS_MEMBER = " . ((S2MEMBER_CURRENT_USER_IS_LOGGED_IN_AS_MEMBER) ? "true" : "false") . ",";
96
  /**/
97
+ echo "S2MEMBER_CURRENT_USER_ACCESS_LEVEL = " . S2MEMBER_CURRENT_USER_ACCESS_LEVEL . ",";
98
+ echo "S2MEMBER_CURRENT_USER_ACCESS_LABEL = '" . c_ws_plugin__s2member_utils_strings::esc_sq (S2MEMBER_CURRENT_USER_ACCESS_LABEL) . "',";
99
  /**/
100
+ echo "S2MEMBER_CURRENT_USER_SUBSCR_ID = '" . c_ws_plugin__s2member_utils_strings::esc_sq (S2MEMBER_CURRENT_USER_SUBSCR_ID) . "',";
101
+ echo "S2MEMBER_CURRENT_USER_SUBSCR_OR_WP_ID = '" . c_ws_plugin__s2member_utils_strings::esc_sq (S2MEMBER_CURRENT_USER_SUBSCR_OR_WP_ID) . "',";
102
+ echo "S2MEMBER_CURRENT_USER_SUBSCR_GATEWAY = '" . c_ws_plugin__s2member_utils_strings::esc_sq (S2MEMBER_CURRENT_USER_SUBSCR_GATEWAY) . "',";
103
+ echo "S2MEMBER_CURRENT_USER_CUSTOM = '" . c_ws_plugin__s2member_utils_strings::esc_sq (S2MEMBER_CURRENT_USER_CUSTOM) . "',";
104
  /**/
105
+ echo "S2MEMBER_CURRENT_USER_REGISTRATION_TIME = " . S2MEMBER_CURRENT_USER_REGISTRATION_TIME . ",";
106
+ echo "S2MEMBER_CURRENT_USER_PAID_REGISTRATION_TIME = " . S2MEMBER_CURRENT_USER_PAID_REGISTRATION_TIME . ",";
107
  /**/
108
+ echo "S2MEMBER_CURRENT_USER_PAID_REGISTRATION_DAYS = " . S2MEMBER_CURRENT_USER_PAID_REGISTRATION_DAYS . ",";
109
+ echo "S2MEMBER_CURRENT_USER_REGISTRATION_DAYS = " . S2MEMBER_CURRENT_USER_REGISTRATION_DAYS . ",";
110
  /**/
111
+ echo "S2MEMBER_CURRENT_USER_DISPLAY_NAME = '" . c_ws_plugin__s2member_utils_strings::esc_sq (S2MEMBER_CURRENT_USER_DISPLAY_NAME) . "',";
112
+ echo "S2MEMBER_CURRENT_USER_FIRST_NAME = '" . c_ws_plugin__s2member_utils_strings::esc_sq (S2MEMBER_CURRENT_USER_FIRST_NAME) . "',";
113
+ echo "S2MEMBER_CURRENT_USER_LAST_NAME = '" . c_ws_plugin__s2member_utils_strings::esc_sq (S2MEMBER_CURRENT_USER_LAST_NAME) . "',";
114
  /**/
115
+ echo "S2MEMBER_CURRENT_USER_LOGIN = '" . c_ws_plugin__s2member_utils_strings::esc_sq (S2MEMBER_CURRENT_USER_LOGIN) . "',";
116
+ echo "S2MEMBER_CURRENT_USER_EMAIL = '" . c_ws_plugin__s2member_utils_strings::esc_sq (S2MEMBER_CURRENT_USER_EMAIL) . "',";
117
+ echo "S2MEMBER_CURRENT_USER_IP = '" . c_ws_plugin__s2member_utils_strings::esc_sq (S2MEMBER_CURRENT_USER_IP) . "',";
118
+ echo "S2MEMBER_CURRENT_USER_REGISTRATION_IP = '" . c_ws_plugin__s2member_utils_strings::esc_sq (S2MEMBER_CURRENT_USER_REGISTRATION_IP) . "',";
119
  /**/
120
+ echo "S2MEMBER_CURRENT_USER_ID = " . S2MEMBER_CURRENT_USER_ID . ",";
121
+ echo "S2MEMBER_CURRENT_USER_FIELDS = " . S2MEMBER_CURRENT_USER_FIELDS . ",";
122
  /**/
123
+ echo "S2MEMBER_CURRENT_USER_DOWNLOADS_ALLOWED = " . S2MEMBER_CURRENT_USER_DOWNLOADS_ALLOWED . ",";
124
+ echo "S2MEMBER_CURRENT_USER_DOWNLOADS_ALLOWED_IS_UNLIMITED = " . ((S2MEMBER_CURRENT_USER_DOWNLOADS_ALLOWED_IS_UNLIMITED) ? "true" : "false") . ",";
125
+ echo "S2MEMBER_CURRENT_USER_DOWNLOADS_CURRENTLY = " . S2MEMBER_CURRENT_USER_DOWNLOADS_CURRENTLY . ",";
126
+ echo "S2MEMBER_CURRENT_USER_DOWNLOADS_ALLOWED_DAYS = " . S2MEMBER_CURRENT_USER_DOWNLOADS_ALLOWED_DAYS . ",";
127
  /**/
128
+ echo "S2MEMBER_FILE_DOWNLOAD_LIMIT_EXCEEDED_PAGE_ID = " . S2MEMBER_FILE_DOWNLOAD_LIMIT_EXCEEDED_PAGE_ID . ",";
129
+ echo "S2MEMBER_MEMBERSHIP_OPTIONS_PAGE_ID = " . S2MEMBER_MEMBERSHIP_OPTIONS_PAGE_ID . ",";
130
+ echo "S2MEMBER_LOGIN_WELCOME_PAGE_ID = " . S2MEMBER_LOGIN_WELCOME_PAGE_ID . ",";
131
  /**/
132
+ echo "S2MEMBER_CURRENT_USER_PROFILE_MODIFICATION_PAGE_URL = '" . c_ws_plugin__s2member_utils_strings::esc_sq (S2MEMBER_CURRENT_USER_PROFILE_MODIFICATION_PAGE_URL) . "',";
133
+ echo "S2MEMBER_FILE_DOWNLOAD_LIMIT_EXCEEDED_PAGE_URL = '" . c_ws_plugin__s2member_utils_strings::esc_sq (S2MEMBER_FILE_DOWNLOAD_LIMIT_EXCEEDED_PAGE_URL) . "',";
134
+ echo "S2MEMBER_MEMBERSHIP_OPTIONS_PAGE_URL = '" . c_ws_plugin__s2member_utils_strings::esc_sq (S2MEMBER_MEMBERSHIP_OPTIONS_PAGE_URL) . "',";
135
+ echo "S2MEMBER_LOGIN_WELCOME_PAGE_URL = '" . c_ws_plugin__s2member_utils_strings::esc_sq (S2MEMBER_LOGIN_WELCOME_PAGE_URL) . "',";
136
+ echo "S2MEMBER_LOGOUT_PAGE_URL = '" . c_ws_plugin__s2member_utils_strings::esc_sq (S2MEMBER_LOGOUT_PAGE_URL) . "',";
137
+ echo "S2MEMBER_LOGIN_PAGE_URL = '" . c_ws_plugin__s2member_utils_strings::esc_sq (S2MEMBER_LOGIN_PAGE_URL) . "',";
138
  /**/
139
  for ($n = 0; $n <= $GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["levels"]; $n++)
140
  {
141
  if (defined (($S2MEMBER_LEVELn_LABEL = "S2MEMBER_LEVEL" . $n . "_LABEL")))
142
+ echo $S2MEMBER_LEVELn_LABEL . " = '" . c_ws_plugin__s2member_utils_strings::esc_sq (constant ($S2MEMBER_LEVELn_LABEL)) . "',";
143
  }
144
  /**/
145
  for ($n = 0; $n <= $GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["levels"]; $n++)
146
  {
147
  if (defined (($S2MEMBER_LEVELn_FILE_DOWNLOADS_ALLOWED = "S2MEMBER_LEVEL" . $n . "_FILE_DOWNLOADS_ALLOWED")))
148
+ echo $S2MEMBER_LEVELn_FILE_DOWNLOADS_ALLOWED . " = " . constant ($S2MEMBER_LEVELn_FILE_DOWNLOADS_ALLOWED) . ",";
149
  }
150
  /**/
151
  for ($n = 0; $n <= $GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["levels"]; $n++)
152
  {
153
  if (defined (($S2MEMBER_LEVELn_FILE_DOWNLOADS_ALLOWED_DAYS = "S2MEMBER_LEVEL" . $n . "_FILE_DOWNLOADS_ALLOWED_DAYS")))
154
+ echo $S2MEMBER_LEVELn_FILE_DOWNLOADS_ALLOWED_DAYS . " = " . constant ($S2MEMBER_LEVELn_FILE_DOWNLOADS_ALLOWED_DAYS) . ",";
155
  }
156
  /**/
157
+ echo "S2MEMBER_FILE_DOWNLOAD_INLINE_EXTENSIONS = '" . c_ws_plugin__s2member_utils_strings::esc_sq (S2MEMBER_FILE_DOWNLOAD_INLINE_EXTENSIONS) . "',";
158
  /**/
159
+ echo "S2MEMBER_REG_EMAIL_FROM_NAME = '" . c_ws_plugin__s2member_utils_strings::esc_sq (S2MEMBER_REG_EMAIL_FROM_NAME) . "',";
160
+ echo "S2MEMBER_REG_EMAIL_FROM_EMAIL = '" . c_ws_plugin__s2member_utils_strings::esc_sq (S2MEMBER_REG_EMAIL_FROM_EMAIL) . "',";
161
  /**/
162
+ echo "S2MEMBER_PAYPAL_NOTIFY_URL = '" . c_ws_plugin__s2member_utils_strings::esc_sq (S2MEMBER_PAYPAL_NOTIFY_URL) . "',";
163
+ echo "S2MEMBER_PAYPAL_RETURN_URL = '" . c_ws_plugin__s2member_utils_strings::esc_sq (S2MEMBER_PAYPAL_RETURN_URL) . "',";
164
  /**/
165
+ echo "S2MEMBER_PAYPAL_BUSINESS = '" . c_ws_plugin__s2member_utils_strings::esc_sq (S2MEMBER_PAYPAL_BUSINESS) . "',";
166
+ echo "S2MEMBER_PAYPAL_ENDPOINT = '" . c_ws_plugin__s2member_utils_strings::esc_sq (S2MEMBER_PAYPAL_ENDPOINT) . "',";
167
+ echo "S2MEMBER_PAYPAL_API_ENDPOINT = '" . c_ws_plugin__s2member_utils_strings::esc_sq (S2MEMBER_PAYPAL_API_ENDPOINT) . "',";
168
  /**/
169
+ echo "S2MEMBER_VALUE_FOR_PP_INV = Math.round (new Date ().getTime ()) + '~" . c_ws_plugin__s2member_utils_strings::esc_sq (S2MEMBER_CURRENT_USER_IP) . "',";
170
+ echo "S2MEMBER_VALUE_FOR_PP_INV_GEN = function(){ var invoice = '', formatSeed = function(seed, reqWidth) { seed = parseInt(seed, 10).toString (16); if (reqWidth < seed.length) return seed.slice (seed.length - reqWidth); else if (reqWidth > seed.length) return Array(1 + (reqWidth - seed.length)).join ('0') + seed; return seed; }; if (typeof S2MEMBER_VALUE_FOR_PP_INV_GEN_UNIQUE_SEED === 'undefined') S2MEMBER_VALUE_FOR_PP_INV_GEN_UNIQUE_SEED = Math.floor (Math.random () * 0x75bcd15); S2MEMBER_VALUE_FOR_PP_INV_GEN_UNIQUE_SEED++; invoice = formatSeed(parseInt(new Date ().getTime () / 1000, 10), 8); invoice += formatSeed(S2MEMBER_VALUE_FOR_PP_INV_GEN_UNIQUE_SEED, 5); invoice += '~' + S2MEMBER_CURRENT_USER_IP; return invoice; },";
171
  /**/
172
+ echo "S2MEMBER_CURRENT_USER_VALUE_FOR_PP_ON0 = '" . c_ws_plugin__s2member_utils_strings::esc_sq (S2MEMBER_CURRENT_USER_VALUE_FOR_PP_ON0) . "',";
173
+ echo "S2MEMBER_CURRENT_USER_VALUE_FOR_PP_OS0 = '" . c_ws_plugin__s2member_utils_strings::esc_sq (S2MEMBER_CURRENT_USER_VALUE_FOR_PP_OS0) . "',";
174
  /**/
175
+ echo "S2MEMBER_CURRENT_USER_VALUE_FOR_PP_ON1 = '" . c_ws_plugin__s2member_utils_strings::esc_sq (S2MEMBER_CURRENT_USER_VALUE_FOR_PP_ON1) . "',";
176
+ echo "S2MEMBER_CURRENT_USER_VALUE_FOR_PP_OS1 = '" . c_ws_plugin__s2member_utils_strings::esc_sq (S2MEMBER_CURRENT_USER_VALUE_FOR_PP_OS1) . "';";
 
 
177
  /**/
178
  $u = $GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["dir_url"];
179
  $i = $GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["dir_url"] . "/images";
180
  /**/
 
 
 
181
  include_once dirname (dirname (__FILE__)) . "/s2member-min.js";
182
  /**/
183
  do_action ("ws_plugin__s2member_during_js_w_globals", get_defined_vars ());
includes/classes/custom-reg-fields.inc.php CHANGED
@@ -335,7 +335,7 @@ if (!class_exists ("c_ws_plugin__s2member_custom_reg_fields"))
335
  unset ($__refs, $__v); /* Unset defined __refs, __v. */
336
  /**/
337
  echo '<label for="ws-plugin--s2member-custom-reg-field-first-name">First Name *</label>' . "\n";
338
- echo '<input aria-required="true" type="text" maxlength="100" name="ws_plugin__s2member_custom_reg_field_first_name" id="ws-plugin--s2member-custom-reg-field-first-name" class="ws-plugin--s2member-custom-reg-field" value="' . format_to_edit ($_p["ws_plugin__s2member_custom_reg_field_first_name"]) . '" />' . "\n";
339
  echo '<br />' . "\n";
340
  /**/
341
  eval('foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;');
@@ -347,7 +347,7 @@ if (!class_exists ("c_ws_plugin__s2member_custom_reg_fields"))
347
  unset ($__refs, $__v); /* Unset defined __refs, __v. */
348
  /**/
349
  echo '<label for="ws-plugin--s2member-custom-reg-field-last-name">Last Name *</label>' . "\n";
350
- echo '<input aria-required="true" type="text" maxlength="100" name="ws_plugin__s2member_custom_reg_field_last_name" id="ws-plugin--s2member-custom-reg-field-last-name" class="ws-plugin--s2member-custom-reg-field" value="' . format_to_edit ($_p["ws_plugin__s2member_custom_reg_field_last_name"]) . '" />' . "\n";
351
  echo '<br />' . "\n";
352
  /**/
353
  eval('foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;');
@@ -477,7 +477,7 @@ if (!class_exists ("c_ws_plugin__s2member_custom_reg_fields"))
477
  echo '<p>' . "\n";
478
  echo '<label for="ws-plugin--s2member-custom-reg-field-first-name">' . "\n";
479
  echo '<span>First Name *</span><br />' . "\n";
480
- echo '<input aria-required="true" type="text" maxlength="100" name="ws_plugin__s2member_custom_reg_field_first_name" id="ws-plugin--s2member-custom-reg-field-first-name" class="ws-plugin--s2member-custom-reg-field" value="' . format_to_edit ($_p["ws_plugin__s2member_custom_reg_field_first_name"]) . '" tabindex="' . esc_attr (($tabindex = $tabindex + 10)) . '" />' . "\n";
481
  echo '</label>' . "\n";
482
  echo '</p>' . "\n";
483
  /**/
@@ -492,7 +492,7 @@ if (!class_exists ("c_ws_plugin__s2member_custom_reg_fields"))
492
  echo '<p>' . "\n";
493
  echo '<label for="ws-plugin--s2member-custom-reg-field-last-name">' . "\n";
494
  echo '<span>Last Name *</span><br />' . "\n";
495
- echo '<input aria-required="true" type="text" maxlength="100" name="ws_plugin__s2member_custom_reg_field_last_name" id="ws-plugin--s2member-custom-reg-field-last-name" class="ws-plugin--s2member-custom-reg-field" value="' . format_to_edit ($_p["ws_plugin__s2member_custom_reg_field_last_name"]) . '" tabindex="' . esc_attr (($tabindex = $tabindex + 10)) . '" />' . "\n";
496
  echo '</label>' . "\n";
497
  echo '</p>' . "\n";
498
  /**/
335
  unset ($__refs, $__v); /* Unset defined __refs, __v. */
336
  /**/
337
  echo '<label for="ws-plugin--s2member-custom-reg-field-first-name">First Name *</label>' . "\n";
338
+ echo '<input aria-required="true" type="text" maxlength="100" name="ws_plugin__s2member_custom_reg_field_first_name" id="ws-plugin--s2member-custom-reg-field-first-name" class="ws-plugin--s2member-custom-reg-field" value="' . esc_attr ($_p["ws_plugin__s2member_custom_reg_field_first_name"]) . '" />' . "\n";
339
  echo '<br />' . "\n";
340
  /**/
341
  eval('foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;');
347
  unset ($__refs, $__v); /* Unset defined __refs, __v. */
348
  /**/
349
  echo '<label for="ws-plugin--s2member-custom-reg-field-last-name">Last Name *</label>' . "\n";
350
+ echo '<input aria-required="true" type="text" maxlength="100" name="ws_plugin__s2member_custom_reg_field_last_name" id="ws-plugin--s2member-custom-reg-field-last-name" class="ws-plugin--s2member-custom-reg-field" value="' . esc_attr ($_p["ws_plugin__s2member_custom_reg_field_last_name"]) . '" />' . "\n";
351
  echo '<br />' . "\n";
352
  /**/
353
  eval('foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;');
477
  echo '<p>' . "\n";
478
  echo '<label for="ws-plugin--s2member-custom-reg-field-first-name">' . "\n";
479
  echo '<span>First Name *</span><br />' . "\n";
480
+ echo '<input aria-required="true" type="text" maxlength="100" name="ws_plugin__s2member_custom_reg_field_first_name" id="ws-plugin--s2member-custom-reg-field-first-name" class="ws-plugin--s2member-custom-reg-field" value="' . esc_attr ($_p["ws_plugin__s2member_custom_reg_field_first_name"]) . '" tabindex="' . esc_attr (($tabindex = $tabindex + 10)) . '" />' . "\n";
481
  echo '</label>' . "\n";
482
  echo '</p>' . "\n";
483
  /**/
492
  echo '<p>' . "\n";
493
  echo '<label for="ws-plugin--s2member-custom-reg-field-last-name">' . "\n";
494
  echo '<span>Last Name *</span><br />' . "\n";
495
+ echo '<input aria-required="true" type="text" maxlength="100" name="ws_plugin__s2member_custom_reg_field_last_name" id="ws-plugin--s2member-custom-reg-field-last-name" class="ws-plugin--s2member-custom-reg-field" value="' . esc_attr ($_p["ws_plugin__s2member_custom_reg_field_last_name"]) . '" tabindex="' . esc_attr (($tabindex = $tabindex + 10)) . '" />' . "\n";
496
  echo '</label>' . "\n";
497
  echo '</p>' . "\n";
498
  /**/
includes/classes/files-in.inc.php CHANGED
@@ -15,7 +15,7 @@
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_files_in"))
21
  {
@@ -54,14 +54,14 @@ if (!class_exists ("c_ws_plugin__s2member_files_in"))
54
  /**/
55
  if (!$using_amazon_s3_storage && !file_exists ($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["files_dir"] . "/" . $_GET["s2member_file_download"]))
56
  {
57
- header("HTTP/1.0 404 Not Found"); /* The file does NOT even exist. */
58
- exit("404: Sorry, file not found. Please contact Support for assistance.");
59
  }
60
  /**/
61
  else if (!empty ($_GET["s2member_file_download_key"]) && !$file_download_key_is_valid) /* Invalid Key? */
62
  {
63
- header("HTTP/1.0 503 Service Temporarily Unavailable"); /* Invalid Download Keys are handled separately. */
64
- exit("503 ( Invalid Key ): Sorry, your access to this file has expired. Please contact Support for assistance.");
65
  }
66
  /**/
67
  else if ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["membership_options_page"]) /* Is a Membership Options Page configured? */
@@ -72,8 +72,8 @@ if (!class_exists ("c_ws_plugin__s2member_files_in"))
72
  /**/
73
  if (($file_download_access_is_allowed = $min_level_4_downloads = c_ws_plugin__s2member_files::min_level_4_downloads ()) === false)
74
  {
75
- header("HTTP/1.0 503 Service Temporarily Unavailable"); /* File downloads are NOT yet configured? */
76
- exit("503: Sorry, File Downloads are NOT enabled yet. Please contact Support for assistance. If you are the site owner, please configure: `s2Member -> Download Options -> Basic Download Restrictions`.");
77
  }
78
  /**/
79
  else if (!is_object ($user = apply_filters ("ws_plugin__s2member_check_file_download_access_user", ((is_user_logged_in ()) ? wp_get_current_user () : false), get_defined_vars ())) || !($user_id = $user->ID))
@@ -124,7 +124,7 @@ if (!class_exists ("c_ws_plugin__s2member_files_in"))
124
  {
125
  if (strtotime ($file_download_access_log_entry["date"]) < strtotime ("-" . $max_days_logged . " days"))
126
  {
127
- unset($file_download_access_log[$file_download_access_log_entry_key]);
128
  $file_download_access_arc[] = $file_download_access_log_entry;
129
  }
130
  else if (strtotime ($file_download_access_log_entry["date"]) >= strtotime ("-" . $file_downloads["allowed_days"] . " days"))
@@ -152,8 +152,8 @@ if (!class_exists ("c_ws_plugin__s2member_files_in"))
152
  /**/
153
  if (!$using_amazon_s3_storage && !file_exists ($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["files_dir"] . "/" . $_GET["s2member_file_download"]))
154
  {
155
- header("HTTP/1.0 404 Not Found"); /* The file does NOT even exist. */
156
- exit("404: Sorry, file not found. Please contact Support for assistance.");
157
  }
158
  }
159
  /*
@@ -171,7 +171,7 @@ if (!class_exists ("c_ws_plugin__s2member_files_in"))
171
  $pathinfo = (!$using_amazon_s3_storage) ? pathinfo (($file = $GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["files_dir"] . "/" . $_GET["s2member_file_download"])) : array ();
172
  $length = (!$using_amazon_s3_storage && $file) ? filesize ($file) : -1; /* The overall file size, in bytes. */
173
  /**/
174
- eval('foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;');
175
  do_action ("ws_plugin__s2member_during_file_download_access", get_defined_vars ());
176
  unset ($__refs, $__v); /* Unset defined __refs, __v. */
177
  /**/
@@ -191,50 +191,50 @@ if (!class_exists ("c_ws_plugin__s2member_files_in"))
191
  $amazon_s3_redirection_url .= "&Expires=" . urlencode ($amazon_s3_file_expires);
192
  $amazon_s3_redirection_url .= "&Signature=" . urlencode ($amazon_s3_signature);
193
  /**/
194
- wp_redirect($amazon_s3_redirection_url); /* 302 redirection. */
195
  /**/
196
  exit (); /* Clean exit. */
197
  }
198
  /**/
199
  else /* Else, using localized storage ( default ). */
200
  {
201
- @set_time_limit(0); /* Unlimited. */
202
  @ini_set ("zlib.output_compression", 0);
203
  /**/
204
- header("Accept-Ranges: none");
205
- header("Content-Encoding: none");
206
- header("Content-Type: " . $mimetype);
207
- header("Expires: " . gmdate ("D, d M Y H:i:s", strtotime ("-1 week")) . " GMT");
208
- header("Last-Modified: " . gmdate ("D, d M Y H:i:s") . " GMT");
209
- header("Cache-Control: no-cache, must-revalidate, max-age=0");
210
  header ("Cache-Control: post-check=0, pre-check=0", false);
211
- header("Pragma: no-cache");
212
  /**/
213
- header('Content-Disposition: ' . (($inline) ? "inline" : "attachment") . '; filename="' . $basename . '"');
214
  /**/
215
  if ($length && apply_filters ("ws_plugin__s2member_stream_file_downloads", true, get_defined_vars ()) && ($stream = fopen ($file, "rb")))
216
  {
217
  $_stream_w_content_length = (preg_match ("/^win/i", PHP_OS)) ? false : true; /* Windows® IIS does not jive here. */
218
  /* Windows® IIS doesn't seem to like it when both `Content-Length` and `Transfer-Encoding: chunked` are sent together. */
219
  if (apply_filters ("ws_plugin__s2member_stream_file_downloads_w_content_length", $_stream_w_content_length, get_defined_vars ()))
220
- header("Content-Length: " . $length);
221
  /**/
222
- header("Transfer-Encoding: chunked"); /* Uses `Transfer-Encoding: chunked` for simulated streaming. */
223
  /**/
224
- eval('while (@ob_end_clean ());'); /* End/clean all output buffers that may or may not exist. */
225
  /**/
226
  while (!feof ($stream) && ($chunk_size = strlen ($data = fread ($stream, 2097152))))
227
- eval('echo dechex ($chunk_size) . "\r\n". $data . "\r\n"; @flush ();');
228
  /**/
229
- fclose($stream);
230
  /**/
231
- exit("0\r\n\r\n");
232
  }
233
  else if ($length) /* Else `file_get_contents()`. */
234
  {
235
- header("Content-Length: " . $length);
236
  /**/
237
- exit(file_get_contents ($file));
238
  }
239
  else
240
  exit (); /* Empty file. */
@@ -271,7 +271,7 @@ if (!class_exists ("c_ws_plugin__s2member_files_in"))
271
  */
272
  public static function _file_remote_authorization ($user = FALSE)
273
  {
274
- eval('foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;');
275
  do_action ("_ws_plugin__s2member_before_file_remote_authorization", get_defined_vars ());
276
  unset ($__refs, $__v); /* Unset defined __refs, __v. */
277
  /**/
@@ -281,9 +281,9 @@ if (!class_exists ("c_ws_plugin__s2member_files_in"))
281
  /**/
282
  if (empty ($_SERVER["PHP_AUTH_USER"]) || empty ($_SERVER["PHP_AUTH_PW"]) || !user_pass_ok ($_SERVER["PHP_AUTH_USER"], $_SERVER["PHP_AUTH_PW"]))
283
  {
284
- header('WWW-Authenticate: Basic realm="Members Only"');
285
- header("HTTP/1.0 401 Unauthorized");
286
- exit("Access Denied");
287
  }
288
  else if (is_object ($_user = new WP_User ($_SERVER["PHP_AUTH_USER"])) && $_user->ID)
289
  {
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_files_in"))
21
  {
54
  /**/
55
  if (!$using_amazon_s3_storage && !file_exists ($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["files_dir"] . "/" . $_GET["s2member_file_download"]))
56
  {
57
+ header ("HTTP/1.0 404 Not Found"); /* The file does NOT even exist. */
58
+ exit ("404: Sorry, file not found. Please contact Support for assistance.");
59
  }
60
  /**/
61
  else if (!empty ($_GET["s2member_file_download_key"]) && !$file_download_key_is_valid) /* Invalid Key? */
62
  {
63
+ header ("HTTP/1.0 503 Service Temporarily Unavailable"); /* Invalid Download Keys are handled separately. */
64
+ exit ("503 ( Invalid Key ): Sorry, your access to this file has expired. Please contact Support for assistance.");
65
  }
66
  /**/
67
  else if ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["membership_options_page"]) /* Is a Membership Options Page configured? */
72
  /**/
73
  if (($file_download_access_is_allowed = $min_level_4_downloads = c_ws_plugin__s2member_files::min_level_4_downloads ()) === false)
74
  {
75
+ header ("HTTP/1.0 503 Service Temporarily Unavailable"); /* File downloads are NOT yet configured? */
76
+ exit ("503: Sorry, File Downloads are NOT enabled yet. Please contact Support for assistance. If you are the site owner, please configure: `s2Member -> Download Options -> Basic Download Restrictions`.");
77
  }
78
  /**/
79
  else if (!is_object ($user = apply_filters ("ws_plugin__s2member_check_file_download_access_user", ((is_user_logged_in ()) ? wp_get_current_user () : false), get_defined_vars ())) || !($user_id = $user->ID))
124
  {
125
  if (strtotime ($file_download_access_log_entry["date"]) < strtotime ("-" . $max_days_logged . " days"))
126
  {
127
+ unset ($file_download_access_log[$file_download_access_log_entry_key]);
128
  $file_download_access_arc[] = $file_download_access_log_entry;
129
  }
130
  else if (strtotime ($file_download_access_log_entry["date"]) >= strtotime ("-" . $file_downloads["allowed_days"] . " days"))
152
  /**/
153
  if (!$using_amazon_s3_storage && !file_exists ($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["files_dir"] . "/" . $_GET["s2member_file_download"]))
154
  {
155
+ header ("HTTP/1.0 404 Not Found"); /* The file does NOT even exist. */
156
+ exit ("404: Sorry, file not found. Please contact Support for assistance.");
157
  }
158
  }
159
  /*
171
  $pathinfo = (!$using_amazon_s3_storage) ? pathinfo (($file = $GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["files_dir"] . "/" . $_GET["s2member_file_download"])) : array ();
172
  $length = (!$using_amazon_s3_storage && $file) ? filesize ($file) : -1; /* The overall file size, in bytes. */
173
  /**/
174
+ eval ('foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;');
175
  do_action ("ws_plugin__s2member_during_file_download_access", get_defined_vars ());
176
  unset ($__refs, $__v); /* Unset defined __refs, __v. */
177
  /**/
191
  $amazon_s3_redirection_url .= "&Expires=" . urlencode ($amazon_s3_file_expires);
192
  $amazon_s3_redirection_url .= "&Signature=" . urlencode ($amazon_s3_signature);
193
  /**/
194
+ wp_redirect ($amazon_s3_redirection_url); /* 302 redirection. */
195
  /**/
196
  exit (); /* Clean exit. */
197
  }
198
  /**/
199
  else /* Else, using localized storage ( default ). */
200
  {
201
+ @set_time_limit (0); /* Unlimited. */
202
  @ini_set ("zlib.output_compression", 0);
203
  /**/
204
+ header ("Accept-Ranges: none");
205
+ header ("Content-Encoding: none");
206
+ header ("Content-Type: " . $mimetype);
207
+ header ("Expires: " . gmdate ("D, d M Y H:i:s", strtotime ("-1 week")) . " GMT");
208
+ header ("Last-Modified: " . gmdate ("D, d M Y H:i:s") . " GMT");
209
+ header ("Cache-Control: no-cache, must-revalidate, max-age=0");
210
  header ("Cache-Control: post-check=0, pre-check=0", false);
211
+ header ("Pragma: no-cache");
212
  /**/
213
+ header ('Content-Disposition: ' . (($inline) ? "inline" : "attachment") . '; filename="' . $basename . '"');
214
  /**/
215
  if ($length && apply_filters ("ws_plugin__s2member_stream_file_downloads", true, get_defined_vars ()) && ($stream = fopen ($file, "rb")))
216
  {
217
  $_stream_w_content_length = (preg_match ("/^win/i", PHP_OS)) ? false : true; /* Windows® IIS does not jive here. */
218
  /* Windows® IIS doesn't seem to like it when both `Content-Length` and `Transfer-Encoding: chunked` are sent together. */
219
  if (apply_filters ("ws_plugin__s2member_stream_file_downloads_w_content_length", $_stream_w_content_length, get_defined_vars ()))
220
+ header ("Content-Length: " . $length);
221
  /**/
222
+ header ("Transfer-Encoding: chunked"); /* Uses `Transfer-Encoding: chunked` for simulated streaming. */
223
  /**/
224
+ eval ('while (@ob_end_clean ());'); /* End/clean all output buffers that may or may not exist. */
225
  /**/
226
  while (!feof ($stream) && ($chunk_size = strlen ($data = fread ($stream, 2097152))))
227
+ eval ('echo dechex ($chunk_size) . "\r\n". $data . "\r\n"; @flush ();');
228
  /**/
229
+ fclose ($stream);
230
  /**/
231
+ exit ("0\r\n\r\n");
232
  }
233
  else if ($length) /* Else `file_get_contents()`. */
234
  {
235
+ header ("Content-Length: " . $length);
236
  /**/
237
+ exit (file_get_contents ($file));
238
  }
239
  else
240
  exit (); /* Empty file. */
271
  */
272
  public static function _file_remote_authorization ($user = FALSE)
273
  {
274
+ eval ('foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;');
275
  do_action ("_ws_plugin__s2member_before_file_remote_authorization", get_defined_vars ());
276
  unset ($__refs, $__v); /* Unset defined __refs, __v. */
277
  /**/
281
  /**/
282
  if (empty ($_SERVER["PHP_AUTH_USER"]) || empty ($_SERVER["PHP_AUTH_PW"]) || !user_pass_ok ($_SERVER["PHP_AUTH_USER"], $_SERVER["PHP_AUTH_PW"]))
283
  {
284
+ header ('WWW-Authenticate: Basic realm="Members Only"');
285
+ header ("HTTP/1.0 401 Unauthorized");
286
+ exit ("Access Denied");
287
  }
288
  else if (is_object ($_user = new WP_User ($_SERVER["PHP_AUTH_USER"])) && $_user->ID)
289
  {
includes/classes/list-servers.inc.php CHANGED
@@ -126,6 +126,7 @@ if (!class_exists ("c_ws_plugin__s2member_list_servers"))
126
  $mailchimp["api_properties"] = $mcapi; /* Include API instance too; as it contains some additional information after each method is processed ( need this in the logs ). */
127
  /**/
128
  $logv = c_ws_plugin__s2member_utilities::ver_details ();
 
129
  $log4 = $_SERVER["HTTP_HOST"] . $_SERVER["REQUEST_URI"] . "\nUser-Agent: " . $_SERVER["HTTP_USER_AGENT"];
130
  $log4 = (is_multisite () && !is_main_site ()) ? ($_log4 = $current_blog->domain . $current_blog->path) . "\n" . $log4 : $log4;
131
  $log2 = (is_multisite () && !is_main_site ()) ? "mailchimp-api-4-" . trim (preg_replace ("/[^a-z0-9]/i", "-", $_log4), "-") . ".log" : "mailchimp-api.log";
@@ -133,7 +134,7 @@ if (!class_exists ("c_ws_plugin__s2member_list_servers"))
133
  if ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["gateway_debug_logs"])
134
  if (is_dir ($logs_dir = $GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["logs_dir"]))
135
  if (is_writable ($logs_dir) && c_ws_plugin__s2member_utils_logs::archive_oversize_log_files ())
136
- file_put_contents ($logs_dir . "/" . $log2, $logv . "\n" . $log4 . "\n" . var_export ($mailchimp, true) . "\n\n", FILE_APPEND);
137
  }
138
  }
139
  }
@@ -156,6 +157,7 @@ if (!class_exists ("c_ws_plugin__s2member_list_servers"))
156
  $aweber["wp_mail_success"] = $success = true; /* Flag indicating that we DO have a successful processing of a new List; affects the function's overall return value. */
157
  /**/
158
  $logv = c_ws_plugin__s2member_utilities::ver_details ();
 
159
  $log4 = $_SERVER["HTTP_HOST"] . $_SERVER["REQUEST_URI"] . "\nUser-Agent: " . $_SERVER["HTTP_USER_AGENT"];
160
  $log4 = (is_multisite () && !is_main_site ()) ? ($_log4 = $current_blog->domain . $current_blog->path) . "\n" . $log4 : $log4;
161
  $log2 = (is_multisite () && !is_main_site ()) ? "aweber-api-4-" . trim (preg_replace ("/[^a-z0-9]/i", "-", $_log4), "-") . ".log" : "aweber-api.log";
@@ -163,7 +165,7 @@ if (!class_exists ("c_ws_plugin__s2member_list_servers"))
163
  if ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["gateway_debug_logs"])
164
  if (is_dir ($logs_dir = $GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["logs_dir"]))
165
  if (is_writable ($logs_dir) && c_ws_plugin__s2member_utils_logs::archive_oversize_log_files ())
166
- file_put_contents ($logs_dir . "/" . $log2, $logv . "\n" . $log4 . "\n" . var_export ($aweber, true) . "\n\n", FILE_APPEND);
167
  }
168
  }
169
  }
@@ -238,6 +240,7 @@ if (!class_exists ("c_ws_plugin__s2member_list_servers"))
238
  $mailchimp["api_removal_properties"] = $mcapi; /* Include API instance too; as it contains some additional information after each method is processed ( need this in the logs ). */
239
  /**/
240
  $logv = c_ws_plugin__s2member_utilities::ver_details ();
 
241
  $log4 = $_SERVER["HTTP_HOST"] . $_SERVER["REQUEST_URI"] . "\nUser-Agent: " . $_SERVER["HTTP_USER_AGENT"];
242
  $log4 = (is_multisite () && !is_main_site ()) ? ($_log4 = $current_blog->domain . $current_blog->path) . "\n" . $log4 : $log4;
243
  $log2 = (is_multisite () && !is_main_site ()) ? "mailchimp-api-4-" . trim (preg_replace ("/[^a-z0-9]/i", "-", $_log4), "-") . ".log" : "mailchimp-api.log";
@@ -245,7 +248,7 @@ if (!class_exists ("c_ws_plugin__s2member_list_servers"))
245
  if ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["gateway_debug_logs"])
246
  if (is_dir ($logs_dir = $GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["logs_dir"]))
247
  if (is_writable ($logs_dir) && c_ws_plugin__s2member_utils_logs::archive_oversize_log_files ())
248
- file_put_contents ($logs_dir . "/" . $log2, $logv . "\n" . $log4 . "\n" . var_export ($mailchimp, true) . "\n\n", FILE_APPEND);
249
  }
250
  }
251
  }
@@ -266,6 +269,7 @@ if (!class_exists ("c_ws_plugin__s2member_list_servers"))
266
  $aweber["wp_mail_removal_success"] = $removal_success = true; /* Flag indicating that we DO have a successful removal; affects the function's overall return value. */
267
  /**/
268
  $logv = c_ws_plugin__s2member_utilities::ver_details ();
 
269
  $log4 = $_SERVER["HTTP_HOST"] . $_SERVER["REQUEST_URI"] . "\nUser-Agent: " . $_SERVER["HTTP_USER_AGENT"];
270
  $log4 = (is_multisite () && !is_main_site ()) ? ($_log4 = $current_blog->domain . $current_blog->path) . "\n" . $log4 : $log4;
271
  $log2 = (is_multisite () && !is_main_site ()) ? "aweber-api-4-" . trim (preg_replace ("/[^a-z0-9]/i", "-", $_log4), "-") . ".log" : "aweber-api.log";
@@ -273,7 +277,7 @@ if (!class_exists ("c_ws_plugin__s2member_list_servers"))
273
  if ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["gateway_debug_logs"])
274
  if (is_dir ($logs_dir = $GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["logs_dir"]))
275
  if (is_writable ($logs_dir) && c_ws_plugin__s2member_utils_logs::archive_oversize_log_files ())
276
- file_put_contents ($logs_dir . "/" . $log2, $logv . "\n" . $log4 . "\n" . var_export ($aweber, true) . "\n\n", FILE_APPEND);
277
  }
278
  }
279
  }
126
  $mailchimp["api_properties"] = $mcapi; /* Include API instance too; as it contains some additional information after each method is processed ( need this in the logs ). */
127
  /**/
128
  $logv = c_ws_plugin__s2member_utilities::ver_details ();
129
+ $logm = c_ws_plugin__s2member_utilities::mem_details ();
130
  $log4 = $_SERVER["HTTP_HOST"] . $_SERVER["REQUEST_URI"] . "\nUser-Agent: " . $_SERVER["HTTP_USER_AGENT"];
131
  $log4 = (is_multisite () && !is_main_site ()) ? ($_log4 = $current_blog->domain . $current_blog->path) . "\n" . $log4 : $log4;
132
  $log2 = (is_multisite () && !is_main_site ()) ? "mailchimp-api-4-" . trim (preg_replace ("/[^a-z0-9]/i", "-", $_log4), "-") . ".log" : "mailchimp-api.log";
134
  if ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["gateway_debug_logs"])
135
  if (is_dir ($logs_dir = $GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["logs_dir"]))
136
  if (is_writable ($logs_dir) && c_ws_plugin__s2member_utils_logs::archive_oversize_log_files ())
137
+ file_put_contents ($logs_dir . "/" . $log2, $logv . "\n" . $logm . "\n" . $log4 . "\n" . var_export ($mailchimp, true) . "\n\n", FILE_APPEND);
138
  }
139
  }
140
  }
157
  $aweber["wp_mail_success"] = $success = true; /* Flag indicating that we DO have a successful processing of a new List; affects the function's overall return value. */
158
  /**/
159
  $logv = c_ws_plugin__s2member_utilities::ver_details ();
160
+ $logm = c_ws_plugin__s2member_utilities::mem_details ();
161
  $log4 = $_SERVER["HTTP_HOST"] . $_SERVER["REQUEST_URI"] . "\nUser-Agent: " . $_SERVER["HTTP_USER_AGENT"];
162
  $log4 = (is_multisite () && !is_main_site ()) ? ($_log4 = $current_blog->domain . $current_blog->path) . "\n" . $log4 : $log4;
163
  $log2 = (is_multisite () && !is_main_site ()) ? "aweber-api-4-" . trim (preg_replace ("/[^a-z0-9]/i", "-", $_log4), "-") . ".log" : "aweber-api.log";
165
  if ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["gateway_debug_logs"])
166
  if (is_dir ($logs_dir = $GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["logs_dir"]))
167
  if (is_writable ($logs_dir) && c_ws_plugin__s2member_utils_logs::archive_oversize_log_files ())
168
+ file_put_contents ($logs_dir . "/" . $log2, $logv . "\n" . $logm . "\n" . $log4 . "\n" . var_export ($aweber, true) . "\n\n", FILE_APPEND);
169
  }
170
  }
171
  }
240
  $mailchimp["api_removal_properties"] = $mcapi; /* Include API instance too; as it contains some additional information after each method is processed ( need this in the logs ). */
241
  /**/
242
  $logv = c_ws_plugin__s2member_utilities::ver_details ();
243
+ $logm = c_ws_plugin__s2member_utilities::mem_details ();
244
  $log4 = $_SERVER["HTTP_HOST"] . $_SERVER["REQUEST_URI"] . "\nUser-Agent: " . $_SERVER["HTTP_USER_AGENT"];
245
  $log4 = (is_multisite () && !is_main_site ()) ? ($_log4 = $current_blog->domain . $current_blog->path) . "\n" . $log4 : $log4;
246
  $log2 = (is_multisite () && !is_main_site ()) ? "mailchimp-api-4-" . trim (preg_replace ("/[^a-z0-9]/i", "-", $_log4), "-") . ".log" : "mailchimp-api.log";
248
  if ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["gateway_debug_logs"])
249
  if (is_dir ($logs_dir = $GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["logs_dir"]))
250
  if (is_writable ($logs_dir) && c_ws_plugin__s2member_utils_logs::archive_oversize_log_files ())
251
+ file_put_contents ($logs_dir . "/" . $log2, $logv . "\n" . $logm . "\n" . $log4 . "\n" . var_export ($mailchimp, true) . "\n\n", FILE_APPEND);
252
  }
253
  }
254
  }
269
  $aweber["wp_mail_removal_success"] = $removal_success = true; /* Flag indicating that we DO have a successful removal; affects the function's overall return value. */
270
  /**/
271
  $logv = c_ws_plugin__s2member_utilities::ver_details ();
272
+ $logm = c_ws_plugin__s2member_utilities::mem_details ();
273
  $log4 = $_SERVER["HTTP_HOST"] . $_SERVER["REQUEST_URI"] . "\nUser-Agent: " . $_SERVER["HTTP_USER_AGENT"];
274
  $log4 = (is_multisite () && !is_main_site ()) ? ($_log4 = $current_blog->domain . $current_blog->path) . "\n" . $log4 : $log4;
275
  $log2 = (is_multisite () && !is_main_site ()) ? "aweber-api-4-" . trim (preg_replace ("/[^a-z0-9]/i", "-", $_log4), "-") . ".log" : "aweber-api.log";
277
  if ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["gateway_debug_logs"])
278
  if (is_dir ($logs_dir = $GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["logs_dir"]))
279
  if (is_writable ($logs_dir) && c_ws_plugin__s2member_utils_logs::archive_oversize_log_files ())
280
+ file_put_contents ($logs_dir . "/" . $log2, $logv . "\n" . $logm . "\n" . $log4 . "\n" . var_export ($aweber, true) . "\n\n", FILE_APPEND);
281
  }
282
  }
283
  }
includes/classes/menu-pages.inc.php CHANGED
@@ -50,8 +50,8 @@ if (!class_exists ("c_ws_plugin__s2member_menu_pages"))
50
  if ($verified || (!empty ($_POST["ws_plugin__s2member_options_save"]) && ($nonce = $_POST["ws_plugin__s2member_options_save"]) && wp_verify_nonce ($nonce, "ws-plugin--s2member-options-save")))
51
  {
52
  $options = $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]; /* Here we get all of the existing options. */
53
- $new_options = (is_array ($new_options)) ? $new_options : ((!empty ($_POST)) ? $_POST : array ());
54
- $new_options = c_ws_plugin__s2member_utils_strings::trim_deep (stripslashes_deep ($new_options));
55
  /**/
56
  foreach ((array)$new_options as $key => $value) /* Looking for relevant keys. */
57
  if (preg_match ("/^" . preg_quote ("ws_plugin__s2member_", "/") . "/", $key))
50
  if ($verified || (!empty ($_POST["ws_plugin__s2member_options_save"]) && ($nonce = $_POST["ws_plugin__s2member_options_save"]) && wp_verify_nonce ($nonce, "ws-plugin--s2member-options-save")))
51
  {
52
  $options = $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]; /* Here we get all of the existing options. */
53
+ $new_options = (is_array ($new_options)) ? $new_options : ((!empty ($_POST)) ? stripslashes_deep ($_POST) : array ());
54
+ $new_options = c_ws_plugin__s2member_utils_strings::trim_deep ($new_options);
55
  /**/
56
  foreach ((array)$new_options as $key => $value) /* Looking for relevant keys. */
57
  if (preg_match ("/^" . preg_quote ("ws_plugin__s2member_", "/") . "/", $key))
includes/classes/meta-box-security.inc.php CHANGED
@@ -69,7 +69,7 @@ if (!class_exists ("c_ws_plugin__s2member_meta_box_security"))
69
  {
70
  echo '<p style="margin-top:15px; margin-left:2px;"><strong>Require Custom Capabilities?</strong></p>' . "\n";
71
  echo '<label class="screen-reader-text" for="ws-plugin--s2member-security-meta-box-ccaps">Custom Capabilities?</label>' . "\n";
72
- echo '<input type="text" name="ws_plugin__s2member_security_meta_box_ccaps" id="ws-plugin--s2member-security-meta-box-ccaps" value="' . format_to_edit (trim (implode (",", (array)get_post_meta ($page_id, "s2member_ccaps_req", true)))) . '" 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 ());" style="width:99%;" />' . "\n";
73
  echo '<br /><small>* see: <code>API Scripting -> Custom Capabilities</code></small>' . "\n";
74
  }
75
  }
@@ -111,7 +111,7 @@ if (!class_exists ("c_ws_plugin__s2member_meta_box_security"))
111
  {
112
  echo '<p style="margin-top:15px; margin-left:2px;"><strong>Require Custom Capabilities?</strong></p>' . "\n";
113
  echo '<label class="screen-reader-text" for="ws-plugin--s2member-security-meta-box-ccaps">Custom Capabilities?</label>' . "\n";
114
- echo '<input type="text" name="ws_plugin__s2member_security_meta_box_ccaps" id="ws-plugin--s2member-security-meta-box-ccaps" value="' . format_to_edit (trim (implode (",", (array)get_post_meta ($post_id, "s2member_ccaps_req", true)))) . '" 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 ());" style="width:99%;" />' . "\n";
115
  echo '<br /><small>* see: <code>API Scripting -> Custom Capabilities</code></small>' . "\n";
116
  }
117
  }
69
  {
70
  echo '<p style="margin-top:15px; margin-left:2px;"><strong>Require Custom Capabilities?</strong></p>' . "\n";
71
  echo '<label class="screen-reader-text" for="ws-plugin--s2member-security-meta-box-ccaps">Custom Capabilities?</label>' . "\n";
72
+ echo '<input type="text" name="ws_plugin__s2member_security_meta_box_ccaps" id="ws-plugin--s2member-security-meta-box-ccaps" value="' . format_to_edit (trim (implode (",", (array)get_post_meta ($page_id, "s2member_ccaps_req", true)))) . '" 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 ());" style="width:99%;" />' . "\n";
73
  echo '<br /><small>* see: <code>API Scripting -> Custom Capabilities</code></small>' . "\n";
74
  }
75
  }
111
  {
112
  echo '<p style="margin-top:15px; margin-left:2px;"><strong>Require Custom Capabilities?</strong></p>' . "\n";
113
  echo '<label class="screen-reader-text" for="ws-plugin--s2member-security-meta-box-ccaps">Custom Capabilities?</label>' . "\n";
114
+ echo '<input type="text" name="ws_plugin__s2member_security_meta_box_ccaps" id="ws-plugin--s2member-security-meta-box-ccaps" value="' . format_to_edit (trim (implode (",", (array)get_post_meta ($post_id, "s2member_ccaps_req", true)))) . '" 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 ());" style="width:99%;" />' . "\n";
115
  echo '<br /><small>* see: <code>API Scripting -> Custom Capabilities</code></small>' . "\n";
116
  }
117
  }
includes/classes/paypal-notify-in-subscr-modify-w-level.inc.php CHANGED
@@ -15,7 +15,7 @@
15
  * @since 110720
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_paypal_notify_in_subscr_modify_w_level"))
21
  {
@@ -40,13 +40,13 @@ if (!class_exists ("c_ws_plugin__s2member_paypal_notify_in_subscr_modify_w_level
40
  */
41
  public static function cp ($vars = array ()) /* Conditional phase for ``c_ws_plugin__s2member_paypal_notify_in::paypal_notify()``. */
42
  {
43
- extract($vars); /* Extract all vars passed in from: ``c_ws_plugin__s2member_paypal_notify_in::paypal_notify()``. */
44
  /**/
45
  if (/**/(!empty ($paypal["txn_type"]) && preg_match ("/^subscr_modify$/i", $paypal["txn_type"]))/**/
46
  && (!empty ($paypal["item_number"]) && preg_match ($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["membership_item_number_w_level_regex"], $paypal["item_number"]))/**/
47
  && (!empty ($paypal["subscr_id"])) && (!empty ($paypal["payer_email"]))/**/)
48
  {
49
- eval('foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;');
50
  do_action ("ws_plugin__s2member_during_paypal_notify_before_subscr_modify", get_defined_vars ());
51
  unset ($__refs, $__v); /* Unset defined __refs, __v. */
52
  /**/
@@ -54,7 +54,7 @@ if (!class_exists ("c_ws_plugin__s2member_paypal_notify_in_subscr_modify_w_level
54
  {
55
  $paypal["s2member_log"][] = "s2Member `txn_type` identified as ( `subscr_modify` ).";
56
  /**/
57
- list ($paypal["level"], $paypal["ccaps"]) = preg_split ("/\:/", $paypal["item_number"], 2);
58
  /**/
59
  $paypal["ip"] = (preg_match ("/ip address/i", $paypal["option_name2"]) && $paypal["option_selection2"]) ? $paypal["option_selection2"] : "";
60
  $paypal["ip"] = (!$paypal["ip"] && preg_match ("/^[a-z0-9]+~[0-9\.]+$/i", $paypal["invoice"])) ? preg_replace ("/^[a-z0-9]+~/i", "", $paypal["invoice"]) : $paypal["ip"];
@@ -68,7 +68,7 @@ if (!class_exists ("c_ws_plugin__s2member_paypal_notify_in_subscr_modify_w_level
68
  $paypal["regular_term"] = $paypal["period3"]; /* This is just set to keep a standard; this way both initial_term & regular_term are available. */
69
  $paypal["recurring"] = ($paypal["recurring"]) ? $paypal["mc_amount3"] : "0"; /* If non-recurring, this should be zero, otherwise Regular. */
70
  /**/
71
- eval('$ipn_signup_vars = $paypal; unset($ipn_signup_vars["s2member_log"]);'); /* Create array of IPN signup vars w/o s2member_log. */
72
  /**/
73
  if (($user_id = c_ws_plugin__s2member_utils_users::get_user_id_with ($paypal["subscr_id"])) && is_object ($user = new WP_User ($user_id)) && $user->ID)
74
  {
@@ -76,7 +76,7 @@ if (!class_exists ("c_ws_plugin__s2member_paypal_notify_in_subscr_modify_w_level
76
  {
77
  $processing = $modifying = $during = true; /* Yes, we ARE processing this. */
78
  /**/
79
- eval('foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;');
80
  do_action ("ws_plugin__s2member_during_paypal_notify_during_before_subscr_modify", get_defined_vars ());
81
  do_action ("ws_plugin__s2member_during_collective_mods", $user_id, get_defined_vars (), "ipn-upgrade-downgrade", "modification", "s2member_level" . $paypal["level"]);
82
  unset ($__refs, $__v); /* Unset defined __refs, __v. */
@@ -85,9 +85,9 @@ if (!class_exists ("c_ws_plugin__s2member_paypal_notify_in_subscr_modify_w_level
85
  $user_reg_ip = get_user_option ("s2member_registration_ip", $user_id); /* Original IP during Registration. */
86
  $user_reg_ip = $paypal["ip"] = ($user_reg_ip) ? $user_reg_ip : $paypal["ip"]; /* Now merge conditionally. */
87
  /**/
88
- if (is_multisite () && !is_user_member_of_blog ($user_id))
89
  {
90
- add_existing_user_to_blog(array ("user_id" => $user_id, "role" => "s2member_level" . $paypal["level"]));
91
  $user = new WP_User ($user_id);
92
  }
93
  /**/
@@ -96,14 +96,15 @@ if (!class_exists ("c_ws_plugin__s2member_paypal_notify_in_subscr_modify_w_level
96
  if ($current_role !== "s2member_level" . $paypal["level"]) /* Only if we need to. */
97
  $user->set_role ("s2member_level" . $paypal["level"]); /* (upgrade/downgrade) */
98
  /**/
99
- if (!preg_match ("/^\+/", $paypal["ccaps"]))
100
  foreach ($user->allcaps as $cap => $cap_enabled)
101
  if (preg_match ("/^access_s2member_ccap_/", $cap))
102
  $user->remove_cap ($ccap = $cap);
103
  /**/
104
- foreach (preg_split ("/[\r\n\t\s;,]+/", ltrim ($paypal["ccaps"], "+")) as $ccap)
105
- if (strlen ($ccap)) /* Don't add empty Custom Capabilities. */
106
- $user->add_cap ("access_s2member_ccap_" . trim (strtolower ($ccap)));
 
107
  /**/
108
  update_user_option ($user_id, "s2member_subscr_gateway", $paypal["subscr_gateway"]);
109
  update_user_option ($user_id, "s2member_subscr_id", $paypal["subscr_id"]);
@@ -232,7 +233,38 @@ if (!class_exists ("c_ws_plugin__s2member_paypal_notify_in_subscr_modify_w_level
232
  $paypal["s2member_log"][] = "Modification Notification Emails have been processed.";
233
  }
234
  /**/
235
- eval('foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
236
  do_action ("ws_plugin__s2member_during_paypal_notify_during_subscr_modify", get_defined_vars ());
237
  unset ($__refs, $__v); /* Unset defined __refs, __v. */
238
  }
@@ -249,7 +281,7 @@ if (!class_exists ("c_ws_plugin__s2member_paypal_notify_in_subscr_modify_w_level
249
  $paypal["s2member_log"][] = "Duplicate IPN. Already processed. This IPN will be ignored.";
250
  }
251
  /**/
252
- eval('foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;');
253
  do_action ("ws_plugin__s2member_during_paypal_notify_after_subscr_modify", get_defined_vars ());
254
  unset ($__refs, $__v); /* Unset defined __refs, __v. */
255
  /**/
15
  * @since 110720
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_paypal_notify_in_subscr_modify_w_level"))
21
  {
40
  */
41
  public static function cp ($vars = array ()) /* Conditional phase for ``c_ws_plugin__s2member_paypal_notify_in::paypal_notify()``. */
42
  {
43
+ extract ($vars); /* Extract all vars passed in from: ``c_ws_plugin__s2member_paypal_notify_in::paypal_notify()``. */
44
  /**/
45
  if (/**/(!empty ($paypal["txn_type"]) && preg_match ("/^subscr_modify$/i", $paypal["txn_type"]))/**/
46
  && (!empty ($paypal["item_number"]) && preg_match ($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["membership_item_number_w_level_regex"], $paypal["item_number"]))/**/
47
  && (!empty ($paypal["subscr_id"])) && (!empty ($paypal["payer_email"]))/**/)
48
  {
49
+ eval ('foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;');
50
  do_action ("ws_plugin__s2member_during_paypal_notify_before_subscr_modify", get_defined_vars ());
51
  unset ($__refs, $__v); /* Unset defined __refs, __v. */
52
  /**/
54
  {
55
  $paypal["s2member_log"][] = "s2Member `txn_type` identified as ( `subscr_modify` ).";
56
  /**/
57
+ list ($paypal["level"], $paypal["ccaps"]/*, $paypal["eotper"] */) = preg_split ("/\:/", $paypal["item_number"], 2);
58
  /**/
59
  $paypal["ip"] = (preg_match ("/ip address/i", $paypal["option_name2"]) && $paypal["option_selection2"]) ? $paypal["option_selection2"] : "";
60
  $paypal["ip"] = (!$paypal["ip"] && preg_match ("/^[a-z0-9]+~[0-9\.]+$/i", $paypal["invoice"])) ? preg_replace ("/^[a-z0-9]+~/i", "", $paypal["invoice"]) : $paypal["ip"];
68
  $paypal["regular_term"] = $paypal["period3"]; /* This is just set to keep a standard; this way both initial_term & regular_term are available. */
69
  $paypal["recurring"] = ($paypal["recurring"]) ? $paypal["mc_amount3"] : "0"; /* If non-recurring, this should be zero, otherwise Regular. */
70
  /**/
71
+ eval ('$ipn_signup_vars = $paypal; unset($ipn_signup_vars["s2member_log"]);'); /* Create array of IPN signup vars w/o s2member_log. */
72
  /**/
73
  if (($user_id = c_ws_plugin__s2member_utils_users::get_user_id_with ($paypal["subscr_id"])) && is_object ($user = new WP_User ($user_id)) && $user->ID)
74
  {
76
  {
77
  $processing = $modifying = $during = true; /* Yes, we ARE processing this. */
78
  /**/
79
+ eval ('foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;');
80
  do_action ("ws_plugin__s2member_during_paypal_notify_during_before_subscr_modify", get_defined_vars ());
81
  do_action ("ws_plugin__s2member_during_collective_mods", $user_id, get_defined_vars (), "ipn-upgrade-downgrade", "modification", "s2member_level" . $paypal["level"]);
82
  unset ($__refs, $__v); /* Unset defined __refs, __v. */
85
  $user_reg_ip = get_user_option ("s2member_registration_ip", $user_id); /* Original IP during Registration. */
86
  $user_reg_ip = $paypal["ip"] = ($user_reg_ip) ? $user_reg_ip : $paypal["ip"]; /* Now merge conditionally. */
87
  /**/
88
+ if (is_multisite () && !is_user_member_of_blog ($user_id)) /* Must have a Role on this Blog. */
89
  {
90
+ add_existing_user_to_blog (array ("user_id" => $user_id, "role" => "s2member_level" . $paypal["level"]));
91
  $user = new WP_User ($user_id);
92
  }
93
  /**/
96
  if ($current_role !== "s2member_level" . $paypal["level"]) /* Only if we need to. */
97
  $user->set_role ("s2member_level" . $paypal["level"]); /* (upgrade/downgrade) */
98
  /**/
99
+ if ($paypal["ccaps"] && preg_match ("/^-all/", str_replace ("+", "", $paypal["ccaps"])))
100
  foreach ($user->allcaps as $cap => $cap_enabled)
101
  if (preg_match ("/^access_s2member_ccap_/", $cap))
102
  $user->remove_cap ($ccap = $cap);
103
  /**/
104
+ if ($paypal["ccaps"] && preg_replace ("/^-all[\r\n\t\s;,]*/", "", str_replace ("+", "", $paypal["ccaps"])))
105
+ foreach (preg_split ("/[\r\n\t\s;,]+/", preg_replace ("/^-all[\r\n\t\s;,]*/", "", str_replace ("+", "", $paypal["ccaps"]))) as $ccap)
106
+ if (strlen ($ccap = trim (strtolower (preg_replace ("/[^a-z_0-9]/i", "", $ccap)))))
107
+ $user->add_cap ("access_s2member_ccap_" . $ccap);
108
  /**/
109
  update_user_option ($user_id, "s2member_subscr_gateway", $paypal["subscr_gateway"]);
110
  update_user_option ($user_id, "s2member_subscr_id", $paypal["subscr_id"]);
233
  $paypal["s2member_log"][] = "Modification Notification Emails have been processed.";
234
  }
235
  /**/
236
+ if ($processing && ($code = $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["modification_tracking_codes"]) && is_array ($cv = preg_split ("/\|/", $paypal["custom"])))
237
+ {
238
+ if (($code = preg_replace ("/%%cv([0-9]+)%%/ei", 'trim($cv[$1])', $code)) && ($code = preg_replace ("/%%subscr_id%%/i", c_ws_plugin__s2member_utils_strings::esc_ds ($paypal["subscr_id"]), $code)))
239
+ if (($code = preg_replace ("/%%initial%%/i", c_ws_plugin__s2member_utils_strings::esc_ds ($paypal["initial"]), $code)) && ($code = preg_replace ("/%%regular%%/i", c_ws_plugin__s2member_utils_strings::esc_ds ($paypal["regular"]), $code)) && ($code = preg_replace ("/%%recurring%%/i", c_ws_plugin__s2member_utils_strings::esc_ds ($paypal["recurring"]), $code)))
240
+ if (($code = preg_replace ("/%%initial_term%%/i", c_ws_plugin__s2member_utils_strings::esc_ds ($paypal["initial_term"]), $code)) && ($code = preg_replace ("/%%regular_term%%/i", c_ws_plugin__s2member_utils_strings::esc_ds ($paypal["regular_term"]), $code)))
241
+ if (($code = preg_replace ("/%%item_number%%/i", c_ws_plugin__s2member_utils_strings::esc_ds ($paypal["item_number"]), $code)) && ($code = preg_replace ("/%%item_name%%/i", c_ws_plugin__s2member_utils_strings::esc_ds ($paypal["item_name"]), $code)))
242
+ if (($code = preg_replace ("/%%first_name%%/i", c_ws_plugin__s2member_utils_strings::esc_ds ($paypal["first_name"]), $code)) && ($code = preg_replace ("/%%last_name%%/i", c_ws_plugin__s2member_utils_strings::esc_ds ($paypal["last_name"]), $code)))
243
+ if (($code = preg_replace ("/%%full_name%%/i", c_ws_plugin__s2member_utils_strings::esc_ds (trim ($paypal["first_name"] . " " . $paypal["last_name"])), $code)))
244
+ if (($code = preg_replace ("/%%payer_email%%/i", c_ws_plugin__s2member_utils_strings::esc_ds ($paypal["payer_email"]), $code)))
245
+ {
246
+ if (($code = preg_replace ("/%%user_first_name%%/i", c_ws_plugin__s2member_utils_strings::esc_ds ($user->first_name), $code)) && ($code = preg_replace ("/%%user_last_name%%/i", c_ws_plugin__s2member_utils_strings::esc_ds ($user->last_name), $code)))
247
+ if (($code = preg_replace ("/%%user_full_name%%/i", c_ws_plugin__s2member_utils_strings::esc_ds (trim ($user->first_name . " " . $user->last_name)), $code)))
248
+ if (($code = preg_replace ("/%%user_email%%/i", c_ws_plugin__s2member_utils_strings::esc_ds ($user->user_email), $code)))
249
+ if (($code = preg_replace ("/%%user_login%%/i", c_ws_plugin__s2member_utils_strings::esc_ds ($user->user_login), $code)))
250
+ if (($code = preg_replace ("/%%user_ip%%/i", c_ws_plugin__s2member_utils_strings::esc_ds ($user_reg_ip), $code)))
251
+ if (($code = preg_replace ("/%%user_id%%/i", c_ws_plugin__s2member_utils_strings::esc_ds ($user_id), $code)))
252
+ {
253
+ if (is_array ($fields) && !empty ($fields))
254
+ foreach ($fields as $var => $val) /* Custom Registration Fields. */
255
+ if (!($code = preg_replace ("/%%" . preg_quote ($var, "/") . "%%/i", c_ws_plugin__s2member_utils_strings::esc_ds (maybe_serialize ($val)), $code)))
256
+ break;
257
+ /**/
258
+ if (($code = trim (preg_replace ("/%%(.+?)%%/i", "", $code)))) /* This gets stored into a Transient Queue. */
259
+ {
260
+ $paypal["s2member_log"][] = "Storing Modification Tracking Codes into a Transient Queue. These will be processed on-site.";
261
+ set_transient ("s2m_" . md5 ("s2member_transient_modification_tracking_codes_" . $paypal["subscr_id"]), $code, 43200);
262
+ }
263
+ }
264
+ }
265
+ }
266
+ /**/
267
+ eval ('foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;');
268
  do_action ("ws_plugin__s2member_during_paypal_notify_during_subscr_modify", get_defined_vars ());
269
  unset ($__refs, $__v); /* Unset defined __refs, __v. */
270
  }
281
  $paypal["s2member_log"][] = "Duplicate IPN. Already processed. This IPN will be ignored.";
282
  }
283
  /**/
284
+ eval ('foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;');
285
  do_action ("ws_plugin__s2member_during_paypal_notify_after_subscr_modify", get_defined_vars ());
286
  unset ($__refs, $__v); /* Unset defined __refs, __v. */
287
  /**/
includes/classes/paypal-notify-in-subscr-or-wa-w-level.inc.php CHANGED
@@ -15,7 +15,7 @@
15
  * @since 110720
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_paypal_notify_in_subscr_or_wa_w_level"))
21
  {
@@ -40,7 +40,7 @@ if (!class_exists ("c_ws_plugin__s2member_paypal_notify_in_subscr_or_wa_w_level"
40
  */
41
  public static function cp ($vars = array ()) /* Conditional phase for ``c_ws_plugin__s2member_paypal_notify_in::paypal_notify()``. */
42
  {
43
- extract ($vars); /* Extract all vars passed in from: ``c_ws_plugin__s2member_paypal_notify_in::paypal_notify()``. */
44
  /**/
45
  if (/**/(!empty ($paypal["txn_type"]) && preg_match ("/^(web_accept|subscr_signup)$/i", $paypal["txn_type"]))/**/
46
  && (!empty ($paypal["item_number"]) && preg_match ($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["membership_item_number_w_level_regex"], $paypal["item_number"]))/**/
@@ -48,7 +48,7 @@ if (!class_exists ("c_ws_plugin__s2member_paypal_notify_in_subscr_or_wa_w_level"
48
  && (empty ($paypal["payment_status"]) || empty ($payment_status_issues) || !preg_match ($payment_status_issues, $paypal["payment_status"]))/**/
49
  && (!empty ($paypal["payer_email"]))/**/)
50
  {
51
- eval ('foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;');
52
  do_action ("ws_plugin__s2member_during_paypal_notify_before_subscr_signup", get_defined_vars ());
53
  unset ($__refs, $__v); /* Unset defined __refs, __v. */
54
  /**/
@@ -76,7 +76,7 @@ if (!class_exists ("c_ws_plugin__s2member_paypal_notify_in_subscr_or_wa_w_level"
76
  $paypal["regular_term"] = $paypal["period3"]; /* This is just set to keep a standard; this way both initial_term & regular_term are available. */
77
  $paypal["recurring"] = ($paypal["recurring"]) ? $paypal["mc_amount3"] : "0"; /* If non-recurring, this should be zero, otherwise Regular. */
78
  /**/
79
- eval ('$ipn_signup_vars = $paypal; unset($ipn_signup_vars["s2member_log"]);'); /* Create array of IPN signup vars w/o s2member_log. */
80
  /*
81
  New Subscription with advanced update vars ( option_name1, option_selection1 )? These variables are used in Subscr. Modifications.
82
  */
@@ -84,7 +84,7 @@ if (!class_exists ("c_ws_plugin__s2member_paypal_notify_in_subscr_or_wa_w_level"
84
  /* This advanced method is required whenever a Subscription that is already completed, or was never setup to recur in the first place needs to be modified.
85
  PayPal® will not allow the `modify=1|2` parameter to be used in those scenarios, because technically there is no billing to update; only the account. */
86
  {
87
- eval ('foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;');
88
  do_action ("ws_plugin__s2member_during_paypal_notify_before_subscr_signup_w_update_vars", get_defined_vars ());
89
  unset ($__refs, $__v); /* Unset defined __refs, __v. */
90
  /**/
@@ -97,7 +97,7 @@ if (!class_exists ("c_ws_plugin__s2member_paypal_notify_in_subscr_or_wa_w_level"
97
  {
98
  $processing = $modifying = $during = true; /* Yes, we ARE processing this. */
99
  /**/
100
- eval ('foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;');
101
  do_action ("ws_plugin__s2member_during_paypal_notify_during_before_subscr_signup_w_update_vars", get_defined_vars ());
102
  do_action ("ws_plugin__s2member_during_collective_mods", $user_id, get_defined_vars (), "ipn-upgrade-downgrade", "modification", "s2member_level" . $paypal["level"]);
103
  unset ($__refs, $__v); /* Unset defined __refs, __v. */
@@ -106,9 +106,9 @@ if (!class_exists ("c_ws_plugin__s2member_paypal_notify_in_subscr_or_wa_w_level"
106
  $user_reg_ip = get_user_option ("s2member_registration_ip", $user_id); /* Original IP during Registration. */
107
  $user_reg_ip = $paypal["ip"] = ($user_reg_ip) ? $user_reg_ip : $paypal["ip"]; /* Now merge conditionally. */
108
  /**/
109
- if (is_multisite () && !is_user_member_of_blog ($user_id))
110
  {
111
- add_existing_user_to_blog (array ("user_id" => $user_id, "role" => "s2member_level" . $paypal["level"]));
112
  $user = new WP_User ($user_id);
113
  }
114
  /**/
@@ -117,14 +117,15 @@ if (!class_exists ("c_ws_plugin__s2member_paypal_notify_in_subscr_or_wa_w_level"
117
  if ($current_role !== "s2member_level" . $paypal["level"]) /* Only if we need to. */
118
  $user->set_role ("s2member_level" . $paypal["level"]); /* (upgrade/downgrade) */
119
  /**/
120
- if (!preg_match ("/^\+/", $paypal["ccaps"]))
121
  foreach ($user->allcaps as $cap => $cap_enabled)
122
  if (preg_match ("/^access_s2member_ccap_/", $cap))
123
  $user->remove_cap ($ccap = $cap);
124
  /**/
125
- foreach (preg_split ("/[\r\n\t\s;,]+/", ltrim ($paypal["ccaps"], "+")) as $ccap)
126
- if (strlen ($ccap)) /* Don't add empty Custom Capabilities. */
127
- $user->add_cap ("access_s2member_ccap_" . trim (strtolower ($ccap)));
 
128
  /**/
129
  update_user_option ($user_id, "s2member_subscr_gateway", $paypal["subscr_gateway"]);
130
  update_user_option ($user_id, "s2member_subscr_id", $paypal["subscr_id"]);
@@ -260,7 +261,38 @@ if (!class_exists ("c_ws_plugin__s2member_paypal_notify_in_subscr_or_wa_w_level"
260
  $paypal["s2member_log"][] = "Modification Notification Emails have been processed.";
261
  }
262
  /**/
263
- eval ('foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
264
  do_action ("ws_plugin__s2member_during_paypal_notify_during_subscr_signup_w_update_vars", get_defined_vars ());
265
  unset ($__refs, $__v); /* Unset defined __refs, __v. */
266
  }
@@ -268,9 +300,9 @@ if (!class_exists ("c_ws_plugin__s2member_paypal_notify_in_subscr_or_wa_w_level"
268
  $paypal["s2member_log"][] = "Unable to modify Subscription. The existing User ID is associated with an Administrator. Stopping here. Otherwise, an Administrator could lose access.";
269
  }
270
  else
271
- $paypal["s2member_log"][] = "Unable to modify Subscription. Could not get the existing User ID from the DB. Please check the on0 and os0 variables in your Button Code.";
272
  /**/
273
- eval ('foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;');
274
  do_action ("ws_plugin__s2member_during_paypal_notify_after_subscr_signup_w_update_vars", get_defined_vars ());
275
  unset ($__refs, $__v); /* Unset defined __refs, __v. */
276
  }
@@ -279,7 +311,7 @@ if (!class_exists ("c_ws_plugin__s2member_paypal_notify_in_subscr_or_wa_w_level"
279
  */
280
  else /* Else this is a normal Subscription signup, we are not updating anything. */
281
  {
282
- eval ('foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;');
283
  do_action ("ws_plugin__s2member_during_paypal_notify_before_subscr_signup_wo_update_vars", get_defined_vars ());
284
  unset ($__refs, $__v); /* Unset defined __refs, __v. */
285
  /**/
@@ -417,14 +449,14 @@ if (!class_exists ("c_ws_plugin__s2member_paypal_notify_in_subscr_or_wa_w_level"
417
  }
418
  }
419
  /**/
420
- eval ('foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;');
421
  do_action ("ws_plugin__s2member_during_paypal_notify_during_subscr_signup_wo_update_vars", get_defined_vars ());
422
  unset ($__refs, $__v); /* Unset defined __refs, __v. */
423
  }
424
  else
425
  $paypal["s2member_log"][] = "Unable to generate Registration URL for Membership Access. Possible data corruption within the IPN response.";
426
  /**/
427
- eval ('foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;');
428
  do_action ("ws_plugin__s2member_during_paypal_notify_after_subscr_signup_wo_update_vars", get_defined_vars ());
429
  unset ($__refs, $__v); /* Unset defined __refs, __v. */
430
  }
@@ -620,7 +652,7 @@ if (!class_exists ("c_ws_plugin__s2member_paypal_notify_in_subscr_or_wa_w_level"
620
  $paypal["s2member_log"][] = "Duplicate IPN. Already processed. This IPN will be ignored.";
621
  }
622
  /**/
623
- eval ('foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;');
624
  do_action ("ws_plugin__s2member_during_paypal_notify_after_subscr_signup", get_defined_vars ());
625
  unset ($__refs, $__v); /* Unset defined __refs, __v. */
626
  /**/
15
  * @since 110720
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_paypal_notify_in_subscr_or_wa_w_level"))
21
  {
40
  */
41
  public static function cp ($vars = array ()) /* Conditional phase for ``c_ws_plugin__s2member_paypal_notify_in::paypal_notify()``. */
42
  {
43
+ extract($vars); /* Extract all vars passed in from: ``c_ws_plugin__s2member_paypal_notify_in::paypal_notify()``. */
44
  /**/
45
  if (/**/(!empty ($paypal["txn_type"]) && preg_match ("/^(web_accept|subscr_signup)$/i", $paypal["txn_type"]))/**/
46
  && (!empty ($paypal["item_number"]) && preg_match ($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["membership_item_number_w_level_regex"], $paypal["item_number"]))/**/
48
  && (empty ($paypal["payment_status"]) || empty ($payment_status_issues) || !preg_match ($payment_status_issues, $paypal["payment_status"]))/**/
49
  && (!empty ($paypal["payer_email"]))/**/)
50
  {
51
+ eval('foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;');
52
  do_action ("ws_plugin__s2member_during_paypal_notify_before_subscr_signup", get_defined_vars ());
53
  unset ($__refs, $__v); /* Unset defined __refs, __v. */
54
  /**/
76
  $paypal["regular_term"] = $paypal["period3"]; /* This is just set to keep a standard; this way both initial_term & regular_term are available. */
77
  $paypal["recurring"] = ($paypal["recurring"]) ? $paypal["mc_amount3"] : "0"; /* If non-recurring, this should be zero, otherwise Regular. */
78
  /**/
79
+ eval('$ipn_signup_vars = $paypal; unset($ipn_signup_vars["s2member_log"]);'); /* Create array of IPN signup vars w/o s2member_log. */
80
  /*
81
  New Subscription with advanced update vars ( option_name1, option_selection1 )? These variables are used in Subscr. Modifications.
82
  */
84
  /* This advanced method is required whenever a Subscription that is already completed, or was never setup to recur in the first place needs to be modified.
85
  PayPal® will not allow the `modify=1|2` parameter to be used in those scenarios, because technically there is no billing to update; only the account. */
86
  {
87
+ eval('foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;');
88
  do_action ("ws_plugin__s2member_during_paypal_notify_before_subscr_signup_w_update_vars", get_defined_vars ());
89
  unset ($__refs, $__v); /* Unset defined __refs, __v. */
90
  /**/
97
  {
98
  $processing = $modifying = $during = true; /* Yes, we ARE processing this. */
99
  /**/
100
+ eval('foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;');
101
  do_action ("ws_plugin__s2member_during_paypal_notify_during_before_subscr_signup_w_update_vars", get_defined_vars ());
102
  do_action ("ws_plugin__s2member_during_collective_mods", $user_id, get_defined_vars (), "ipn-upgrade-downgrade", "modification", "s2member_level" . $paypal["level"]);
103
  unset ($__refs, $__v); /* Unset defined __refs, __v. */
106
  $user_reg_ip = get_user_option ("s2member_registration_ip", $user_id); /* Original IP during Registration. */
107
  $user_reg_ip = $paypal["ip"] = ($user_reg_ip) ? $user_reg_ip : $paypal["ip"]; /* Now merge conditionally. */
108
  /**/
109
+ if (is_multisite () && !is_user_member_of_blog ($user_id)) /* Must have a Role on this Blog. */
110
  {
111
+ add_existing_user_to_blog(array ("user_id" => $user_id, "role" => "s2member_level" . $paypal["level"]));
112
  $user = new WP_User ($user_id);
113
  }
114
  /**/
117
  if ($current_role !== "s2member_level" . $paypal["level"]) /* Only if we need to. */
118
  $user->set_role ("s2member_level" . $paypal["level"]); /* (upgrade/downgrade) */
119
  /**/
120
+ if ($paypal["ccaps"] && preg_match ("/^-all/", str_replace ("+", "", $paypal["ccaps"])))
121
  foreach ($user->allcaps as $cap => $cap_enabled)
122
  if (preg_match ("/^access_s2member_ccap_/", $cap))
123
  $user->remove_cap ($ccap = $cap);
124
  /**/
125
+ if ($paypal["ccaps"] && preg_replace ("/^-all[\r\n\t\s;,]*/", "", str_replace ("+", "", $paypal["ccaps"])))
126
+ foreach (preg_split ("/[\r\n\t\s;,]+/", preg_replace ("/^-all[\r\n\t\s;,]*/", "", str_replace ("+", "", $paypal["ccaps"]))) as $ccap)
127
+ if (strlen ($ccap = trim (strtolower (preg_replace ("/[^a-z_0-9]/i", "", $ccap)))))
128
+ $user->add_cap ("access_s2member_ccap_" . $ccap);
129
  /**/
130
  update_user_option ($user_id, "s2member_subscr_gateway", $paypal["subscr_gateway"]);
131
  update_user_option ($user_id, "s2member_subscr_id", $paypal["subscr_id"]);
261
  $paypal["s2member_log"][] = "Modification Notification Emails have been processed.";
262
  }
263
  /**/
264
+ if ($processing && ($code = $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["modification_tracking_codes"]) && is_array ($cv = preg_split ("/\|/", $paypal["custom"])))
265
+ {
266
+ if (($code = preg_replace ("/%%cv([0-9]+)%%/ei", 'trim($cv[$1])', $code)) && ($code = preg_replace ("/%%subscr_id%%/i", c_ws_plugin__s2member_utils_strings::esc_ds ($paypal["subscr_id"]), $code)))
267
+ if (($code = preg_replace ("/%%initial%%/i", c_ws_plugin__s2member_utils_strings::esc_ds ($paypal["initial"]), $code)) && ($code = preg_replace ("/%%regular%%/i", c_ws_plugin__s2member_utils_strings::esc_ds ($paypal["regular"]), $code)) && ($code = preg_replace ("/%%recurring%%/i", c_ws_plugin__s2member_utils_strings::esc_ds ($paypal["recurring"]), $code)))
268
+ if (($code = preg_replace ("/%%initial_term%%/i", c_ws_plugin__s2member_utils_strings::esc_ds ($paypal["initial_term"]), $code)) && ($code = preg_replace ("/%%regular_term%%/i", c_ws_plugin__s2member_utils_strings::esc_ds ($paypal["regular_term"]), $code)))
269
+ if (($code = preg_replace ("/%%item_number%%/i", c_ws_plugin__s2member_utils_strings::esc_ds ($paypal["item_number"]), $code)) && ($code = preg_replace ("/%%item_name%%/i", c_ws_plugin__s2member_utils_strings::esc_ds ($paypal["item_name"]), $code)))
270
+ if (($code = preg_replace ("/%%first_name%%/i", c_ws_plugin__s2member_utils_strings::esc_ds ($paypal["first_name"]), $code)) && ($code = preg_replace ("/%%last_name%%/i", c_ws_plugin__s2member_utils_strings::esc_ds ($paypal["last_name"]), $code)))
271
+ if (($code = preg_replace ("/%%full_name%%/i", c_ws_plugin__s2member_utils_strings::esc_ds (trim ($paypal["first_name"] . " " . $paypal["last_name"])), $code)))
272
+ if (($code = preg_replace ("/%%payer_email%%/i", c_ws_plugin__s2member_utils_strings::esc_ds ($paypal["payer_email"]), $code)))
273
+ {
274
+ if (($code = preg_replace ("/%%user_first_name%%/i", c_ws_plugin__s2member_utils_strings::esc_ds ($user->first_name), $code)) && ($code = preg_replace ("/%%user_last_name%%/i", c_ws_plugin__s2member_utils_strings::esc_ds ($user->last_name), $code)))
275
+ if (($code = preg_replace ("/%%user_full_name%%/i", c_ws_plugin__s2member_utils_strings::esc_ds (trim ($user->first_name . " " . $user->last_name)), $code)))
276
+ if (($code = preg_replace ("/%%user_email%%/i", c_ws_plugin__s2member_utils_strings::esc_ds ($user->user_email), $code)))
277
+ if (($code = preg_replace ("/%%user_login%%/i", c_ws_plugin__s2member_utils_strings::esc_ds ($user->user_login), $code)))
278
+ if (($code = preg_replace ("/%%user_ip%%/i", c_ws_plugin__s2member_utils_strings::esc_ds ($user_reg_ip), $code)))
279
+ if (($code = preg_replace ("/%%user_id%%/i", c_ws_plugin__s2member_utils_strings::esc_ds ($user_id), $code)))
280
+ {
281
+ if (is_array ($fields) && !empty ($fields))
282
+ foreach ($fields as $var => $val) /* Custom Registration Fields. */
283
+ if (!($code = preg_replace ("/%%" . preg_quote ($var, "/") . "%%/i", c_ws_plugin__s2member_utils_strings::esc_ds (maybe_serialize ($val)), $code)))
284
+ break;
285
+ /**/
286
+ if (($code = trim (preg_replace ("/%%(.+?)%%/i", "", $code)))) /* This gets stored into a Transient Queue. */
287
+ {
288
+ $paypal["s2member_log"][] = "Storing Modification Tracking Codes into a Transient Queue. These will be processed on-site.";
289
+ set_transient ("s2m_" . md5 ("s2member_transient_modification_tracking_codes_" . $paypal["subscr_id"]), $code, 43200);
290
+ }
291
+ }
292
+ }
293
+ }
294
+ /**/
295
+ eval('foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;');
296
  do_action ("ws_plugin__s2member_during_paypal_notify_during_subscr_signup_w_update_vars", get_defined_vars ());
297
  unset ($__refs, $__v); /* Unset defined __refs, __v. */
298
  }
300
  $paypal["s2member_log"][] = "Unable to modify Subscription. The existing User ID is associated with an Administrator. Stopping here. Otherwise, an Administrator could lose access.";
301
  }
302
  else
303
+ $paypal["s2member_log"][] = "Unable to modify Subscription. Could not get the existing User ID from the DB. Please check the `on0` and `os0` variables in your Button Code.";
304
  /**/
305
+ eval('foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;');
306
  do_action ("ws_plugin__s2member_during_paypal_notify_after_subscr_signup_w_update_vars", get_defined_vars ());
307
  unset ($__refs, $__v); /* Unset defined __refs, __v. */
308
  }
311
  */
312
  else /* Else this is a normal Subscription signup, we are not updating anything. */
313
  {
314
+ eval('foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;');
315
  do_action ("ws_plugin__s2member_during_paypal_notify_before_subscr_signup_wo_update_vars", get_defined_vars ());
316
  unset ($__refs, $__v); /* Unset defined __refs, __v. */
317
  /**/
449
  }
450
  }
451
  /**/
452
+ eval('foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;');
453
  do_action ("ws_plugin__s2member_during_paypal_notify_during_subscr_signup_wo_update_vars", get_defined_vars ());
454
  unset ($__refs, $__v); /* Unset defined __refs, __v. */
455
  }
456
  else
457
  $paypal["s2member_log"][] = "Unable to generate Registration URL for Membership Access. Possible data corruption within the IPN response.";
458
  /**/
459
+ eval('foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;');
460
  do_action ("ws_plugin__s2member_during_paypal_notify_after_subscr_signup_wo_update_vars", get_defined_vars ());
461
  unset ($__refs, $__v); /* Unset defined __refs, __v. */
462
  }
652
  $paypal["s2member_log"][] = "Duplicate IPN. Already processed. This IPN will be ignored.";
653
  }
654
  /**/
655
+ eval('foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;');
656
  do_action ("ws_plugin__s2member_during_paypal_notify_after_subscr_signup", get_defined_vars ());
657
  unset ($__refs, $__v); /* Unset defined __refs, __v. */
658
  /**/
includes/classes/paypal-notify-in-wa-ccaps-wo-level.inc.php ADDED
@@ -0,0 +1,292 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * s2Member's PayPal® IPN handler ( inner processing routine ).
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\PayPal
15
+ * @since 110815
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_paypal_notify_in_wa_ccaps_wo_level"))
21
+ {
22
+ /**
23
+ * s2Member's PayPal® IPN handler ( inner processing routine ).
24
+ *
25
+ * @package s2Member\PayPal
26
+ * @since 110815
27
+ */
28
+ class c_ws_plugin__s2member_paypal_notify_in_wa_ccaps_wo_level
29
+ {
30
+ /**
31
+ * s2Member's PayPal® IPN handler ( inner processing routine ).
32
+ *
33
+ * @package s2Member\PayPal
34
+ * @since 110815
35
+ *
36
+ * @param array $vars Required. An array of defined variables passed by {@link s2Member\PayPal\c_ws_plugin__s2member_paypal_notify_in::paypal_notify()}.
37
+ * @return array|bool The original ``$paypal`` array passed in ( extracted ) from ``$vars``, or false when conditions do NOT apply.
38
+ *
39
+ * @todo Optimize with ``empty()`` and ``isset()``.
40
+ */
41
+ public static function cp ($vars = array ()) /* Conditional phase for ``c_ws_plugin__s2member_paypal_notify_in::paypal_notify()``. */
42
+ {
43
+ extract ($vars); /* Extract all vars passed in from: ``c_ws_plugin__s2member_paypal_notify_in::paypal_notify()``. */
44
+ /**/
45
+ if (/**/(!empty ($paypal["txn_type"]) && preg_match ("/^web_accept$/i", $paypal["txn_type"]))/**/
46
+ && (!empty ($paypal["item_number"]) && preg_match ($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["membership_item_number_wo_level_regex"], $paypal["item_number"]))/**/
47
+ && (empty ($paypal["payment_status"]) || empty ($payment_status_issues) || !preg_match ($payment_status_issues, $paypal["payment_status"]))/**/
48
+ && (!empty ($paypal["txn_id"]) && ($paypal["subscr_id"] = $paypal["txn_id"])) && (!empty ($paypal["payer_email"]))/**/)
49
+ {
50
+ eval ('foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;');
51
+ do_action ("ws_plugin__s2member_during_paypal_notify_before_new_ccaps", get_defined_vars ());
52
+ unset ($__refs, $__v); /* Unset defined __refs, __v. */
53
+ /**/
54
+ if (!get_transient ($transient_ipn = "s2m_ipn_" . md5 ("s2member_transient_" . $_paypal_s)) && set_transient ($transient_ipn, time (), 31556926 * 10))
55
+ {
56
+ $paypal["s2member_log"][] = "s2Member `txn_type` identified as ( `web_accept` ) w/ update vars for Capabilities w/o Level.";
57
+ /**/
58
+ list ($paypal["level"], $paypal["ccaps"], $paypal["eotper"]) = preg_split ("/\:/", $paypal["item_number"], 3);
59
+ /**/
60
+ $paypal["ip"] = (preg_match ("/ip address/i", $paypal["option_name2"]) && $paypal["option_selection2"]) ? $paypal["option_selection2"] : "";
61
+ $paypal["ip"] = (!$paypal["ip"] && preg_match ("/^[a-z0-9]+~[0-9\.]+$/i", $paypal["invoice"])) ? preg_replace ("/^[a-z0-9]+~/i", "", $paypal["invoice"]) : $paypal["ip"];
62
+ /**/
63
+ if (preg_match ("/(referenc|associat|updat|upgrad)/i", $paypal["option_name1"]) && $paypal["option_selection1"]) /* Must have this information for Capability additions. */
64
+ {
65
+ if (($user_id = c_ws_plugin__s2member_utils_users::get_user_id_with ($paypal["txn_id"], $paypal["option_selection1"])) && is_object ($user = new WP_User ($user_id)) && $user->ID)
66
+ {
67
+ if (!$user->has_cap ("administrator")) /* Do NOT process this routine on Administrators. */
68
+ {
69
+ $processing = $during = true; /* Yes, we ARE processing this. */
70
+ /**/
71
+ eval ('foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;');
72
+ do_action ("ws_plugin__s2member_during_paypal_notify_during_before_new_ccaps", get_defined_vars ());
73
+ unset ($__refs, $__v); /* Unset defined __refs, __v. */
74
+ /**/
75
+ $fields = get_user_option ("s2member_custom_fields", $user_id); /* These will be needed in the routines below. */
76
+ $user_reg_ip = get_user_option ("s2member_registration_ip", $user_id); /* Original IP during Registration. */
77
+ $user_reg_ip = $paypal["ip"] = ($user_reg_ip) ? $user_reg_ip : $paypal["ip"]; /* Now merge conditionally. */
78
+ /**/
79
+ if (is_multisite () && !is_user_member_of_blog ($user_id)) /* Must have a Role on this Blog. */
80
+ {
81
+ add_existing_user_to_blog (array ("user_id" => $user_id, "role" => get_option ("default_role")));
82
+ $user = new WP_User ($user_id);
83
+ }
84
+ /**/
85
+ if ($paypal["ccaps"] && preg_match ("/^-all/", str_replace ("+", "", $paypal["ccaps"])))
86
+ foreach ($user->allcaps as $cap => $cap_enabled)
87
+ if (preg_match ("/^access_s2member_ccap_/", $cap))
88
+ $user->remove_cap ($ccap = $cap);
89
+ /**/
90
+ if ($paypal["ccaps"] && preg_replace ("/^-all[\r\n\t\s;,]*/", "", str_replace ("+", "", $paypal["ccaps"])))
91
+ foreach (preg_split ("/[\r\n\t\s;,]+/", preg_replace ("/^-all[\r\n\t\s;,]*/", "", str_replace ("+", "", $paypal["ccaps"]))) as $ccap)
92
+ if (strlen ($ccap = trim (strtolower (preg_replace ("/[^a-z_0-9]/i", "", $ccap)))))
93
+ $user->add_cap ("access_s2member_ccap_" . $ccap);
94
+ /**/
95
+ if (!get_user_option ("s2member_registration_ip", $user_id))
96
+ update_user_option ($user_id, "s2member_registration_ip", $paypal["ip"]);
97
+ /**/
98
+ $paypal["s2member_log"][] = "s2Member Custom Capabilities updated w/ advanced update routines.";
99
+ /**/
100
+ wp_mail ($paypal["payer_email"], apply_filters ("ws_plugin__s2member_capabilities_email_sbj", "Thank you! Your account has been updated.", get_defined_vars ()), apply_filters ("ws_plugin__s2member_capabilities_email_msg", "Thank you! You now have access to:\n" . $paypal["item_name"] . "\n\nPlease log back in now.\n" . wp_login_url (), get_defined_vars ()), "From: \"" . preg_replace ('/"/', "'", $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["reg_email_from_name"]) . "\" <" . $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["reg_email_from_email"] . ">\r\nContent-Type: text/plain; charset=utf-8");
101
+ /**/
102
+ $paypal["s2member_log"][] = "Capability Confirmation Email sent to Customer, with a URL that provides them with a way to log back in.";
103
+ /**/
104
+ if ($processing && $_GET["s2member_paypal_proxy"] && ($url = $_GET["s2member_paypal_proxy_return_url"]) && is_array ($cv = preg_split ("/\|/", $paypal["custom"]))) /* A Proxy is requesting a Return URL? */
105
+ {
106
+ if (($url = preg_replace ("/%%cv([0-9]+)%%/ei", 'urlencode(trim($cv[$1]))', $url)) && ($url = preg_replace ("/%%subscr_id%%/i", c_ws_plugin__s2member_utils_strings::esc_ds (urlencode ($paypal["subscr_id"])), $url)))
107
+ if (($url = preg_replace ("/%%amount%%/i", c_ws_plugin__s2member_utils_strings::esc_ds (urlencode ($paypal["mc_gross"])), $url)) && ($url = preg_replace ("/%%txn_id%%/i", c_ws_plugin__s2member_utils_strings::esc_ds (urlencode ($paypal["txn_id"])), $url)))
108
+ if (($url = preg_replace ("/%%item_number%%/i", c_ws_plugin__s2member_utils_strings::esc_ds (urlencode ($paypal["item_number"])), $url)) && ($url = preg_replace ("/%%item_name%%/i", c_ws_plugin__s2member_utils_strings::esc_ds (urlencode ($paypal["item_name"])), $url)))
109
+ if (($url = preg_replace ("/%%first_name%%/i", c_ws_plugin__s2member_utils_strings::esc_ds (urlencode ($paypal["first_name"])), $url)) && ($url = preg_replace ("/%%last_name%%/i", c_ws_plugin__s2member_utils_strings::esc_ds (urlencode ($paypal["last_name"])), $url)))
110
+ if (($url = preg_replace ("/%%full_name%%/i", c_ws_plugin__s2member_utils_strings::esc_ds (urlencode (trim ($paypal["first_name"] . " " . $paypal["last_name"]))), $url)))
111
+ if (($url = preg_replace ("/%%payer_email%%/i", c_ws_plugin__s2member_utils_strings::esc_ds (urlencode ($paypal["payer_email"])), $url)))
112
+ {
113
+ if (($url = preg_replace ("/%%user_first_name%%/i", c_ws_plugin__s2member_utils_strings::esc_ds (urlencode ($user->first_name)), $url)) && ($url = preg_replace ("/%%user_last_name%%/i", c_ws_plugin__s2member_utils_strings::esc_ds (urlencode ($user->last_name)), $url)))
114
+ if (($url = preg_replace ("/%%user_full_name%%/i", c_ws_plugin__s2member_utils_strings::esc_ds (urlencode (trim ($user->first_name . " " . $user->last_name))), $url)))
115
+ if (($url = preg_replace ("/%%user_email%%/i", c_ws_plugin__s2member_utils_strings::esc_ds (urlencode ($user->user_email)), $url)))
116
+ if (($url = preg_replace ("/%%user_login%%/i", c_ws_plugin__s2member_utils_strings::esc_ds (urlencode ($user->user_login)), $url)))
117
+ if (($url = preg_replace ("/%%user_ip%%/i", c_ws_plugin__s2member_utils_strings::esc_ds (urlencode ($user_reg_ip)), $url)))
118
+ if (($url = preg_replace ("/%%user_id%%/i", c_ws_plugin__s2member_utils_strings::esc_ds (urlencode ($user_id)), $url)))
119
+ {
120
+ if (is_array ($fields) && !empty ($fields))
121
+ foreach ($fields as $var => $val) /* Custom Registration Fields. */
122
+ if (!($url = preg_replace ("/%%" . preg_quote ($var, "/") . "%%/i", c_ws_plugin__s2member_utils_strings::esc_ds (urlencode (maybe_serialize ($val))), $url)))
123
+ break;
124
+ /**/
125
+ if (($url = trim ($url))) /* Preserve remaining replacements. */
126
+ /* Because the parent routine may perform replacements too. */
127
+ $paypal["s2member_paypal_proxy_return_url"] = $url;
128
+ }
129
+ }
130
+ /**/
131
+ $paypal["s2member_log"][] = "Capability Return, a Proxy Return URL is ready.";
132
+ }
133
+ /**/
134
+ if ($processing && $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["payment_notification_urls"] && is_array ($cv = preg_split ("/\|/", $paypal["custom"])))
135
+ {
136
+ foreach (preg_split ("/[\r\n\t]+/", $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["payment_notification_urls"]) as $url)
137
+ /**/
138
+ if (($url = preg_replace ("/%%cv([0-9]+)%%/ei", 'urlencode(trim($cv[$1]))', $url)) && ($url = preg_replace ("/%%subscr_id%%/i", c_ws_plugin__s2member_utils_strings::esc_ds (urlencode ($paypal["subscr_id"])), $url)))
139
+ if (($url = preg_replace ("/%%amount%%/i", c_ws_plugin__s2member_utils_strings::esc_ds (urlencode ($paypal["mc_gross"])), $url)) && ($url = preg_replace ("/%%txn_id%%/i", c_ws_plugin__s2member_utils_strings::esc_ds (urlencode ($paypal["txn_id"])), $url)))
140
+ if (($url = preg_replace ("/%%item_number%%/i", c_ws_plugin__s2member_utils_strings::esc_ds (urlencode ($paypal["item_number"])), $url)) && ($url = preg_replace ("/%%item_name%%/i", c_ws_plugin__s2member_utils_strings::esc_ds (urlencode ($paypal["item_name"])), $url)))
141
+ if (($url = preg_replace ("/%%first_name%%/i", c_ws_plugin__s2member_utils_strings::esc_ds (urlencode ($paypal["first_name"])), $url)) && ($url = preg_replace ("/%%last_name%%/i", c_ws_plugin__s2member_utils_strings::esc_ds (urlencode ($paypal["last_name"])), $url)))
142
+ if (($url = preg_replace ("/%%full_name%%/i", c_ws_plugin__s2member_utils_strings::esc_ds (urlencode (trim ($paypal["first_name"] . " " . $paypal["last_name"]))), $url)))
143
+ if (($url = preg_replace ("/%%payer_email%%/i", c_ws_plugin__s2member_utils_strings::esc_ds (urlencode ($paypal["payer_email"])), $url)))
144
+ {
145
+ if (($url = preg_replace ("/%%user_first_name%%/i", c_ws_plugin__s2member_utils_strings::esc_ds (urlencode ($user->first_name)), $url)) && ($url = preg_replace ("/%%user_last_name%%/i", c_ws_plugin__s2member_utils_strings::esc_ds (urlencode ($user->last_name)), $url)))
146
+ if (($url = preg_replace ("/%%user_full_name%%/i", c_ws_plugin__s2member_utils_strings::esc_ds (urlencode (trim ($user->first_name . " " . $user->last_name))), $url)))
147
+ if (($url = preg_replace ("/%%user_email%%/i", c_ws_plugin__s2member_utils_strings::esc_ds (urlencode ($user->user_email)), $url)))
148
+ if (($url = preg_replace ("/%%user_login%%/i", c_ws_plugin__s2member_utils_strings::esc_ds (urlencode ($user->user_login)), $url)))
149
+ if (($url = preg_replace ("/%%user_ip%%/i", c_ws_plugin__s2member_utils_strings::esc_ds (urlencode ($user_reg_ip)), $url)))
150
+ if (($url = preg_replace ("/%%user_id%%/i", c_ws_plugin__s2member_utils_strings::esc_ds (urlencode ($user_id)), $url)))
151
+ {
152
+ if (is_array ($fields) && !empty ($fields))
153
+ foreach ($fields as $var => $val) /* Custom Registration Fields. */
154
+ if (!($url = preg_replace ("/%%" . preg_quote ($var, "/") . "%%/i", c_ws_plugin__s2member_utils_strings::esc_ds (urlencode (maybe_serialize ($val))), $url)))
155
+ break;
156
+ /**/
157
+ if (($url = trim (preg_replace ("/%%(.+?)%%/i", "", $url))))
158
+ c_ws_plugin__s2member_utils_urls::remote ($url);
159
+ }
160
+ }
161
+ /**/
162
+ $paypal["s2member_log"][] = "Payment Notification URLs have been processed.";
163
+ }
164
+ /**/
165
+ if ($processing && $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["payment_notification_recipients"] && is_array ($cv = preg_split ("/\|/", $paypal["custom"])))
166
+ {
167
+ $msg = $sbj = "( s2Member / API Notification Email ) - Payment";
168
+ $msg .= "\n\n"; /* Spacing in the message body. */
169
+ /**/
170
+ $msg .= "subscr_id: %%subscr_id%%\n";
171
+ $msg .= "amount: %%amount%%\n";
172
+ $msg .= "txn_id: %%txn_id%%\n";
173
+ $msg .= "item_number: %%item_number%%\n";
174
+ $msg .= "item_name: %%item_name%%\n";
175
+ $msg .= "first_name: %%first_name%%\n";
176
+ $msg .= "last_name: %%last_name%%\n";
177
+ $msg .= "full_name: %%full_name%%\n";
178
+ $msg .= "payer_email: %%payer_email%%\n";
179
+ /**/
180
+ $msg .= "user_first_name: %%user_first_name%%\n";
181
+ $msg .= "user_last_name: %%user_last_name%%\n";
182
+ $msg .= "user_full_name: %%user_full_name%%\n";
183
+ $msg .= "user_email: %%user_email%%\n";
184
+ $msg .= "user_login: %%user_login%%\n";
185
+ $msg .= "user_ip: %%user_ip%%\n";
186
+ $msg .= "user_id: %%user_id%%\n";
187
+ /**/
188
+ if (is_array ($fields) && !empty ($fields))
189
+ foreach ($fields as $var => $val)
190
+ $msg .= $var . ": %%" . $var . "%%\n";
191
+ /**/
192
+ $msg .= "cv0: %%cv0%%\n";
193
+ $msg .= "cv1: %%cv1%%\n";
194
+ $msg .= "cv2: %%cv2%%\n";
195
+ $msg .= "cv3: %%cv3%%\n";
196
+ $msg .= "cv4: %%cv4%%\n";
197
+ $msg .= "cv5: %%cv5%%\n";
198
+ $msg .= "cv6: %%cv6%%\n";
199
+ $msg .= "cv7: %%cv7%%\n";
200
+ $msg .= "cv8: %%cv8%%\n";
201
+ $msg .= "cv9: %%cv9%%";
202
+ /**/
203
+ if (($msg = preg_replace ("/%%cv([0-9]+)%%/ei", 'trim($cv[$1])', $msg)) && ($msg = preg_replace ("/%%subscr_id%%/i", c_ws_plugin__s2member_utils_strings::esc_ds ($paypal["subscr_id"]), $msg)))
204
+ if (($msg = preg_replace ("/%%amount%%/i", c_ws_plugin__s2member_utils_strings::esc_ds ($paypal["mc_gross"]), $msg)) && ($msg = preg_replace ("/%%txn_id%%/i", c_ws_plugin__s2member_utils_strings::esc_ds ($paypal["txn_id"]), $msg)))
205
+ if (($msg = preg_replace ("/%%item_number%%/i", c_ws_plugin__s2member_utils_strings::esc_ds ($paypal["item_number"]), $msg)) && ($msg = preg_replace ("/%%item_name%%/i", c_ws_plugin__s2member_utils_strings::esc_ds ($paypal["item_name"]), $msg)))
206
+ if (($msg = preg_replace ("/%%first_name%%/i", c_ws_plugin__s2member_utils_strings::esc_ds ($paypal["first_name"]), $msg)) && ($msg = preg_replace ("/%%last_name%%/i", c_ws_plugin__s2member_utils_strings::esc_ds ($paypal["last_name"]), $msg)))
207
+ if (($msg = preg_replace ("/%%full_name%%/i", c_ws_plugin__s2member_utils_strings::esc_ds (trim ($paypal["first_name"] . " " . $paypal["last_name"])), $msg)))
208
+ if (($msg = preg_replace ("/%%payer_email%%/i", c_ws_plugin__s2member_utils_strings::esc_ds ($paypal["payer_email"]), $msg)))
209
+ {
210
+ if (($msg = preg_replace ("/%%user_first_name%%/i", c_ws_plugin__s2member_utils_strings::esc_ds ($user->first_name), $msg)) && ($msg = preg_replace ("/%%user_last_name%%/i", c_ws_plugin__s2member_utils_strings::esc_ds ($user->last_name), $msg)))
211
+ if (($msg = preg_replace ("/%%user_full_name%%/i", c_ws_plugin__s2member_utils_strings::esc_ds (trim ($user->first_name . " " . $user->last_name)), $msg)))
212
+ if (($msg = preg_replace ("/%%user_email%%/i", c_ws_plugin__s2member_utils_strings::esc_ds ($user->user_email), $msg)))
213
+ if (($msg = preg_replace ("/%%user_login%%/i", c_ws_plugin__s2member_utils_strings::esc_ds ($user->user_login), $msg)))
214
+ if (($msg = preg_replace ("/%%user_ip%%/i", c_ws_plugin__s2member_utils_strings::esc_ds ($user_reg_ip), $msg)))
215
+ if (($msg = preg_replace ("/%%user_id%%/i", c_ws_plugin__s2member_utils_strings::esc_ds ($user_id), $msg)))
216
+ {
217
+ if (is_array ($fields) && !empty ($fields))
218
+ foreach ($fields as $var => $val) /* Custom Registration Fields. */
219
+ if (!($msg = preg_replace ("/%%" . preg_quote ($var, "/") . "%%/i", c_ws_plugin__s2member_utils_strings::esc_ds (maybe_serialize ($val)), $msg)))
220
+ break;
221
+ /**/
222
+ if (($msg = trim (preg_replace ("/%%(.+?)%%/i", "", $msg))))
223
+ foreach (c_ws_plugin__s2member_utils_strings::trim_deep (preg_split ("/;+/", $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["payment_notification_recipients"])) as $recipient)
224
+ ($recipient) ? wp_mail ($recipient, apply_filters ("ws_plugin__s2member_payment_notification_email_sbj", $sbj, get_defined_vars ()), apply_filters ("ws_plugin__s2member_payment_notification_email_msg", $msg, get_defined_vars ()), "From: \"" . preg_replace ('/"/', "'", $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["reg_email_from_name"]) . "\" <" . $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["reg_email_from_email"] . ">\r\nContent-Type: text/plain; charset=utf-8") : null;
225
+ }
226
+ }
227
+ /**/
228
+ $paypal["s2member_log"][] = "Payment Notification Emails have been processed.";
229
+ }
230
+ /**/
231
+ if ($processing && ($code = $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["ccap_tracking_codes"]) && is_array ($cv = preg_split ("/\|/", $paypal["custom"])))
232
+ {
233
+ if (($code = preg_replace ("/%%cv([0-9]+)%%/ei", 'trim($cv[$1])', $code)) && ($code = preg_replace ("/%%subscr_id%%/i", c_ws_plugin__s2member_utils_strings::esc_ds ($paypal["subscr_id"]), $code)))
234
+ if (($code = preg_replace ("/%%amount%%/i", c_ws_plugin__s2member_utils_strings::esc_ds ($paypal["mc_gross"]), $code)) && ($code = preg_replace ("/%%txn_id%%/i", c_ws_plugin__s2member_utils_strings::esc_ds ($paypal["txn_id"]), $code)))
235
+ if (($code = preg_replace ("/%%item_number%%/i", c_ws_plugin__s2member_utils_strings::esc_ds ($paypal["item_number"]), $code)) && ($code = preg_replace ("/%%item_name%%/i", c_ws_plugin__s2member_utils_strings::esc_ds ($paypal["item_name"]), $code)))
236
+ if (($code = preg_replace ("/%%first_name%%/i", c_ws_plugin__s2member_utils_strings::esc_ds ($paypal["first_name"]), $code)) && ($code = preg_replace ("/%%last_name%%/i", c_ws_plugin__s2member_utils_strings::esc_ds ($paypal["last_name"]), $code)))
237
+ if (($code = preg_replace ("/%%full_name%%/i", c_ws_plugin__s2member_utils_strings::esc_ds (trim ($paypal["first_name"] . " " . $paypal["last_name"])), $code)))
238
+ if (($code = preg_replace ("/%%payer_email%%/i", c_ws_plugin__s2member_utils_strings::esc_ds ($paypal["payer_email"]), $code)))
239
+ {
240
+ if (($code = preg_replace ("/%%user_first_name%%/i", c_ws_plugin__s2member_utils_strings::esc_ds ($user->first_name), $code)) && ($code = preg_replace ("/%%user_last_name%%/i", c_ws_plugin__s2member_utils_strings::esc_ds ($user->last_name), $code)))
241
+ if (($code = preg_replace ("/%%user_full_name%%/i", c_ws_plugin__s2member_utils_strings::esc_ds (trim ($user->first_name . " " . $user->last_name)), $code)))
242
+ if (($code = preg_replace ("/%%user_email%%/i", c_ws_plugin__s2member_utils_strings::esc_ds ($user->user_email), $code)))
243
+ if (($code = preg_replace ("/%%user_login%%/i", c_ws_plugin__s2member_utils_strings::esc_ds ($user->user_login), $code)))
244
+ if (($code = preg_replace ("/%%user_ip%%/i", c_ws_plugin__s2member_utils_strings::esc_ds ($user_reg_ip), $code)))
245
+ if (($code = preg_replace ("/%%user_id%%/i", c_ws_plugin__s2member_utils_strings::esc_ds ($user_id), $code)))
246
+ {
247
+ if (is_array ($fields) && !empty ($fields))
248
+ foreach ($fields as $var => $val) /* Custom Registration Fields. */
249
+ if (!($code = preg_replace ("/%%" . preg_quote ($var, "/") . "%%/i", c_ws_plugin__s2member_utils_strings::esc_ds (maybe_serialize ($val)), $code)))
250
+ break;
251
+ /**/
252
+ if (($code = trim (preg_replace ("/%%(.+?)%%/i", "", $code)))) /* This gets stored into a Transient Queue. */
253
+ {
254
+ $paypal["s2member_log"][] = "Storing Payment Tracking Codes into a Transient Queue. These will be processed on-site.";
255
+ set_transient ("s2m_" . md5 ("s2member_transient_ccap_tracking_codes_" . $paypal["txn_id"]), $code, 43200);
256
+ }
257
+ }
258
+ }
259
+ }
260
+ /**/
261
+ eval ('foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;');
262
+ do_action ("ws_plugin__s2member_during_paypal_notify_during_new_ccaps", get_defined_vars ());
263
+ unset ($__refs, $__v); /* Unset defined __refs, __v. */
264
+ }
265
+ else
266
+ $paypal["s2member_log"][] = "Unable to add new Capabilities. The existing User ID is associated with an Administrator. Stopping here. Otherwise, an Administrator could lose access.";
267
+ }
268
+ else
269
+ $paypal["s2member_log"][] = "Unable to add new Capabilities. Could not get the existing User ID from the DB. Please check the `on0` and `os0` variables in your Button Code.";
270
+ }
271
+ else
272
+ $paypal["s2member_log"][] = "Unable to add new Capabilities. Missing User/Member details. Please check the `on0` and `os0` variables in your Button Code.";
273
+ }
274
+ else /* Else, this is a duplicate IPN. Must stop here. */
275
+ {
276
+ $paypal["s2member_log"][] = "Not processing. Duplicate IPN.";
277
+ $paypal["s2member_log"][] = "s2Member `txn_type` identified as ( `web_accept` ) w/ update vars for Capabilities w/o Level.";
278
+ $paypal["s2member_log"][] = "Duplicate IPN. Already processed. This IPN will be ignored.";
279
+ }
280
+ /**/
281
+ eval ('foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;');
282
+ do_action ("ws_plugin__s2member_during_paypal_notify_after_new_ccaps", get_defined_vars ());
283
+ unset ($__refs, $__v); /* Unset defined __refs, __v. */
284
+ /**/
285
+ return apply_filters ("c_ws_plugin__s2member_paypal_notify_in_wa_ccaps_wo_level", $paypal, get_defined_vars ());
286
+ }
287
+ else
288
+ return apply_filters ("c_ws_plugin__s2member_paypal_notify_in_wa_ccaps_wo_level", false, get_defined_vars ());
289
+ }
290
+ }
291
+ }
292
+ ?>
includes/classes/paypal-notify-in-web-accept-sp.inc.php CHANGED
@@ -116,7 +116,7 @@ if (!class_exists ("c_ws_plugin__s2member_paypal_notify_in_web_accept_sp"))
116
  $paypal["s2member_log"][] = "Specific Post/Page Confirmation Email sent to: " . implode ("; ", $recipients) . ".";
117
  }
118
  /**/
119
- if ($processing && $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["sp_sale_notification_urls"])
120
  {
121
  foreach (preg_split ("/[\r\n\t]+/", $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["sp_sale_notification_urls"]) as $url)
122
  /**/
@@ -135,7 +135,7 @@ if (!class_exists ("c_ws_plugin__s2member_paypal_notify_in_web_accept_sp"))
135
  $paypal["s2member_log"][] = "Specific Post/Page ~ Sale Notification URLs have been processed.";
136
  }
137
  /**/
138
- if ($processing && $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["sp_sale_notification_recipients"])
139
  {
140
  $msg = $sbj = "( s2Member / API Notification Email ) - Specific Post/Page ~ Sale";
141
  $msg .= "\n\n"; /* Spacing in the message body. */
@@ -179,7 +179,7 @@ if (!class_exists ("c_ws_plugin__s2member_paypal_notify_in_web_accept_sp"))
179
  $paypal["s2member_log"][] = "Specific Post/Page ~ Sale Notification Emails have been processed.";
180
  }
181
  /**/
182
- if ($processing && $_GET["s2member_paypal_proxy"] && ($url = $_GET["s2member_paypal_proxy_return_url"])) /* A Proxy is requesting a Return URL for this transaction? */
183
  {
184
  if (($url = preg_replace ("/%%cv([0-9]+)%%/ei", 'urlencode(trim($cv[$1]))', $url)) && ($url = preg_replace ("/%%sp_access_url%%/i", c_ws_plugin__s2member_utils_strings::esc_ds (rawurlencode ($sp_access_url)), $url)))
185
  if (($url = preg_replace ("/%%sp_access_exp%%/i", c_ws_plugin__s2member_utils_strings::esc_ds (urlencode (c_ws_plugin__s2member_utils_time::approx_time_difference (time (), strtotime ("+" . $paypal["hours"] . " hours")))), $url)))
@@ -197,7 +197,7 @@ if (!class_exists ("c_ws_plugin__s2member_paypal_notify_in_web_accept_sp"))
197
  $paypal["s2member_log"][] = "Specific Post/Page Return, a Proxy Return URL is ready.";
198
  }
199
  /**/
200
- if ($processing && ($code = $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["sp_tracking_codes"]))
201
  {
202
  if (($code = preg_replace ("/%%cv([0-9]+)%%/ei", 'trim($cv[$1])', $code)) && ($code = preg_replace ("/%%amount%%/i", c_ws_plugin__s2member_utils_strings::esc_ds ($paypal["mc_gross"]), $code)) && ($code = preg_replace ("/%%txn_id%%/i", c_ws_plugin__s2member_utils_strings::esc_ds ($paypal["txn_id"]), $code)))
203
  if (($code = preg_replace ("/%%item_number%%/i", c_ws_plugin__s2member_utils_strings::esc_ds ($paypal["item_number"]), $code)) && ($code = preg_replace ("/%%item_name%%/i", c_ws_plugin__s2member_utils_strings::esc_ds ($paypal["item_name"]), $code)))
116
  $paypal["s2member_log"][] = "Specific Post/Page Confirmation Email sent to: " . implode ("; ", $recipients) . ".";
117
  }
118
  /**/
119
+ if ($processing && $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["sp_sale_notification_urls"] && is_array ($cv = preg_split ("/\|/", $paypal["custom"])))
120
  {
121
  foreach (preg_split ("/[\r\n\t]+/", $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["sp_sale_notification_urls"]) as $url)
122
  /**/
135
  $paypal["s2member_log"][] = "Specific Post/Page ~ Sale Notification URLs have been processed.";
136
  }
137
  /**/
138
+ if ($processing && $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["sp_sale_notification_recipients"] && is_array ($cv = preg_split ("/\|/", $paypal["custom"])))
139
  {
140
  $msg = $sbj = "( s2Member / API Notification Email ) - Specific Post/Page ~ Sale";
141
  $msg .= "\n\n"; /* Spacing in the message body. */
179
  $paypal["s2member_log"][] = "Specific Post/Page ~ Sale Notification Emails have been processed.";
180
  }
181
  /**/
182
+ if ($processing && $_GET["s2member_paypal_proxy"] && ($url = $_GET["s2member_paypal_proxy_return_url"]) && is_array ($cv = preg_split ("/\|/", $paypal["custom"]))) /* A Proxy is requesting a Return URL? */
183
  {
184
  if (($url = preg_replace ("/%%cv([0-9]+)%%/ei", 'urlencode(trim($cv[$1]))', $url)) && ($url = preg_replace ("/%%sp_access_url%%/i", c_ws_plugin__s2member_utils_strings::esc_ds (rawurlencode ($sp_access_url)), $url)))
185
  if (($url = preg_replace ("/%%sp_access_exp%%/i", c_ws_plugin__s2member_utils_strings::esc_ds (urlencode (c_ws_plugin__s2member_utils_time::approx_time_difference (time (), strtotime ("+" . $paypal["hours"] . " hours")))), $url)))
197
  $paypal["s2member_log"][] = "Specific Post/Page Return, a Proxy Return URL is ready.";
198
  }
199
  /**/
200
+ if ($processing && ($code = $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["sp_tracking_codes"]) && is_array ($cv = preg_split ("/\|/", $paypal["custom"])))
201
  {
202
  if (($code = preg_replace ("/%%cv([0-9]+)%%/ei", 'trim($cv[$1])', $code)) && ($code = preg_replace ("/%%amount%%/i", c_ws_plugin__s2member_utils_strings::esc_ds ($paypal["mc_gross"]), $code)) && ($code = preg_replace ("/%%txn_id%%/i", c_ws_plugin__s2member_utils_strings::esc_ds ($paypal["txn_id"]), $code)))
203
  if (($code = preg_replace ("/%%item_number%%/i", c_ws_plugin__s2member_utils_strings::esc_ds ($paypal["item_number"]), $code)) && ($code = preg_replace ("/%%item_name%%/i", c_ws_plugin__s2member_utils_strings::esc_ds ($paypal["item_name"]), $code)))
includes/classes/paypal-notify-in.inc.php CHANGED
@@ -97,6 +97,9 @@ if (!class_exists ("c_ws_plugin__s2member_paypal_notify_in"))
97
  else if (($_paypal_cp = c_ws_plugin__s2member_paypal_notify_in_web_accept_sp::cp (get_defined_vars ())))
98
  $paypal = $_paypal_cp;
99
  /**/
 
 
 
100
  else if (($_paypal_cp = c_ws_plugin__s2member_paypal_notify_in_subscr_or_wa_w_level::cp (get_defined_vars ())))
101
  $paypal = $_paypal_cp;
102
  /**/
@@ -169,6 +172,7 @@ if (!class_exists ("c_ws_plugin__s2member_paypal_notify_in"))
169
  Logging now supports Multisite Networking as well.
170
  */
171
  $logv = c_ws_plugin__s2member_utilities::ver_details ();
 
172
  $log4 = $_SERVER["HTTP_HOST"] . $_SERVER["REQUEST_URI"] . "\nUser-Agent: " . $_SERVER["HTTP_USER_AGENT"];
173
  $log4 = (is_multisite () && !is_main_site ()) ? ($_log4 = $current_blog->domain . $current_blog->path) . "\n" . $log4 : $log4;
174
  $log2 = (is_multisite () && !is_main_site ()) ? "paypal-ipn-4-" . trim (preg_replace ("/[^a-z0-9]/i", "-", $_log4), "-") . ".log" : "paypal-ipn.log";
@@ -176,7 +180,7 @@ if (!class_exists ("c_ws_plugin__s2member_paypal_notify_in"))
176
  if ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["gateway_debug_logs"])
177
  if (is_dir ($logs_dir = $GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["logs_dir"]))
178
  if (is_writable ($logs_dir) && c_ws_plugin__s2member_utils_logs::archive_oversize_log_files ())
179
- file_put_contents ($logs_dir . "/" . $log2, $logv . "\n" . $log4 . "\n" . var_export ($paypal, true) . "\n\n", FILE_APPEND);
180
  /**/
181
  eval ('foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;');
182
  do_action ("ws_plugin__s2member_during_paypal_notify", get_defined_vars ());
97
  else if (($_paypal_cp = c_ws_plugin__s2member_paypal_notify_in_web_accept_sp::cp (get_defined_vars ())))
98
  $paypal = $_paypal_cp;
99
  /**/
100
+ else if (($_paypal_cp = c_ws_plugin__s2member_paypal_notify_in_wa_ccaps_wo_level::cp (get_defined_vars ())))
101
+ $paypal = $_paypal_cp;
102
+ /**/
103
  else if (($_paypal_cp = c_ws_plugin__s2member_paypal_notify_in_subscr_or_wa_w_level::cp (get_defined_vars ())))
104
  $paypal = $_paypal_cp;
105
  /**/
172
  Logging now supports Multisite Networking as well.
173
  */
174
  $logv = c_ws_plugin__s2member_utilities::ver_details ();
175
+ $logm = c_ws_plugin__s2member_utilities::mem_details ();
176
  $log4 = $_SERVER["HTTP_HOST"] . $_SERVER["REQUEST_URI"] . "\nUser-Agent: " . $_SERVER["HTTP_USER_AGENT"];
177
  $log4 = (is_multisite () && !is_main_site ()) ? ($_log4 = $current_blog->domain . $current_blog->path) . "\n" . $log4 : $log4;
178
  $log2 = (is_multisite () && !is_main_site ()) ? "paypal-ipn-4-" . trim (preg_replace ("/[^a-z0-9]/i", "-", $_log4), "-") . ".log" : "paypal-ipn.log";
180
  if ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["gateway_debug_logs"])
181
  if (is_dir ($logs_dir = $GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["logs_dir"]))
182
  if (is_writable ($logs_dir) && c_ws_plugin__s2member_utils_logs::archive_oversize_log_files ())
183
+ file_put_contents ($logs_dir . "/" . $log2, $logv . "\n" . $logm . "\n" . $log4 . "\n" . var_export ($paypal, true) . "\n\n", FILE_APPEND);
184
  /**/
185
  eval ('foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;');
186
  do_action ("ws_plugin__s2member_during_paypal_notify", get_defined_vars ());
includes/classes/paypal-return-in-subscr-modify-w-level.inc.php CHANGED
@@ -15,7 +15,7 @@
15
  * @since 110720
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_paypal_return_in_subscr_modify_w_level"))
21
  {
@@ -40,21 +40,21 @@ if (!class_exists ("c_ws_plugin__s2member_paypal_return_in_subscr_modify_w_level
40
  */
41
  public static function cp ($vars = array ()) /* Conditional phase for ``c_ws_plugin__s2member_paypal_notify_in::paypal_notify()``. */
42
  {
43
- extract ($vars); /* Extract all vars passed in from: ``c_ws_plugin__s2member_paypal_notify_in::paypal_notify()``. */
44
  /**/
45
  if (/**/(!empty ($paypal["txn_type"]) && preg_match ("/^subscr_modify$/i", $paypal["txn_type"]))/**/
46
  && (!empty ($paypal["item_number"]) && preg_match ($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["membership_item_number_w_level_regex"], $paypal["item_number"]))/**/
47
  && (!empty ($paypal["subscr_id"]))/**/)
48
  {
49
- eval ('foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;');
50
  do_action ("ws_plugin__s2member_during_paypal_return_before_subscr_modify", get_defined_vars ());
51
  unset ($__refs, $__v); /* Unset defined __refs, __v. */
52
  /**/
53
  if (!get_transient ($transient_rtn = "s2m_rtn_" . md5 ("s2member_transient_" . $_paypal_s)) && set_transient ($transient_rtn, time (), 31556926 * 10))
54
  {
55
- $paypal["s2member_log"][] = "s2Member `txn_type` identified as `subscr_modify`.";
56
  /**/
57
- list ($paypal["level"], $paypal["ccaps"]) = preg_split ("/\:/", $paypal["item_number"], 2);
58
  /**/
59
  $paypal["ip"] = (preg_match ("/ip address/i", $paypal["option_name2"]) && $paypal["option_selection2"]) ? $paypal["option_selection2"] : "";
60
  $paypal["ip"] = (!$paypal["ip"] && preg_match ("/^[a-z0-9]+~[0-9\.]+$/i", $paypal["invoice"])) ? preg_replace ("/^[a-z0-9]+~/i", "", $paypal["invoice"]) : $paypal["ip"];
@@ -85,9 +85,9 @@ if (!class_exists ("c_ws_plugin__s2member_paypal_return_in_subscr_modify_w_level
85
  $user_reg_ip = get_user_option ("s2member_registration_ip", $user_id); /* Original IP during Registration. */
86
  $user_reg_ip = $paypal["ip"] = ($user_reg_ip) ? $user_reg_ip : $paypal["ip"]; /* Now merge conditionally. */
87
  /**/
88
- if (is_multisite () && !is_user_member_of_blog ($user_id))
89
  {
90
- add_existing_user_to_blog (array ("user_id" => $user_id, "role" => "s2member_level" . $paypal["level"]));
91
  $user = new WP_User ($user_id); /* Now update the $user object we're using. */
92
  }
93
  /**/
@@ -96,14 +96,15 @@ if (!class_exists ("c_ws_plugin__s2member_paypal_return_in_subscr_modify_w_level
96
  if ($current_role !== "s2member_level" . $paypal["level"]) /* Only if we need to. */
97
  $user->set_role ("s2member_level" . $paypal["level"]); /* (upgrade/downgrade) */
98
  /**/
99
- if (!preg_match ("/^\+/", $paypal["ccaps"]))
100
  foreach ($user->allcaps as $cap => $cap_enabled)
101
  if (preg_match ("/^access_s2member_ccap_/", $cap))
102
  $user->remove_cap ($ccap = $cap);
103
  /**/
104
- foreach (preg_split ("/[\r\n\t\s;,]+/", ltrim ($paypal["ccaps"], "+")) as $ccap)
105
- if (strlen ($ccap)) /* Don't add empty Custom Capabilities. */
106
- $user->add_cap ("access_s2member_ccap_" . trim (strtolower ($ccap)));
 
107
  /**/
108
  update_user_option ($user_id, "s2member_subscr_gateway", $paypal["subscr_gateway"]);
109
  update_user_option ($user_id, "s2member_subscr_id", $paypal["subscr_id"]);
@@ -124,9 +125,44 @@ if (!class_exists ("c_ws_plugin__s2member_paypal_return_in_subscr_modify_w_level
124
  /**/
125
  c_ws_plugin__s2member_user_notes::clear_user_note_lines ($user_id, "/^Demoted by s2Member\:/");
126
  /**/
127
- $paypal["s2member_log"][] = "s2Member Level/Capabilities updated on Subscription modification.";
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
128
  /**/
129
- eval ('foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;');
130
  do_action ("ws_plugin__s2member_during_paypal_return_during_subscr_modify", get_defined_vars ());
131
  unset ($__refs, $__v); /* Unset defined __refs, __v. */
132
  /**/
@@ -134,7 +170,7 @@ if (!class_exists ("c_ws_plugin__s2member_paypal_return_in_subscr_modify_w_level
134
  {
135
  $paypal["s2member_log"][] = "Redirecting this Member to a custom URL after modification: " . $redirection_url_after_modification;
136
  /**/
137
- wp_redirect ($redirection_url_after_modification);
138
  }
139
  else /* Else, use standard/default handling in this scenario. Have the Customer log in again. */
140
  {
@@ -178,7 +214,7 @@ if (!class_exists ("c_ws_plugin__s2member_paypal_return_in_subscr_modify_w_level
178
  "Back To Home Page", home_url ("/"));
179
  }
180
  /**/
181
- eval ('foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;');
182
  do_action ("ws_plugin__s2member_during_paypal_return_after_subscr_modify", get_defined_vars ());
183
  unset ($__refs, $__v); /* Unset defined __refs, __v. */
184
  /**/
15
  * @since 110720
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_paypal_return_in_subscr_modify_w_level"))
21
  {
40
  */
41
  public static function cp ($vars = array ()) /* Conditional phase for ``c_ws_plugin__s2member_paypal_notify_in::paypal_notify()``. */
42
  {
43
+ extract($vars); /* Extract all vars passed in from: ``c_ws_plugin__s2member_paypal_notify_in::paypal_notify()``. */
44
  /**/
45
  if (/**/(!empty ($paypal["txn_type"]) && preg_match ("/^subscr_modify$/i", $paypal["txn_type"]))/**/
46
  && (!empty ($paypal["item_number"]) && preg_match ($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["membership_item_number_w_level_regex"], $paypal["item_number"]))/**/
47
  && (!empty ($paypal["subscr_id"]))/**/)
48
  {
49
+ eval('foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;');
50
  do_action ("ws_plugin__s2member_during_paypal_return_before_subscr_modify", get_defined_vars ());
51
  unset ($__refs, $__v); /* Unset defined __refs, __v. */
52
  /**/
53
  if (!get_transient ($transient_rtn = "s2m_rtn_" . md5 ("s2member_transient_" . $_paypal_s)) && set_transient ($transient_rtn, time (), 31556926 * 10))
54
  {
55
+ $paypal["s2member_log"][] = "s2Member `txn_type` identified as ( `subscr_modify` ), a Subscription Modification.";
56
  /**/
57
+ list ($paypal["level"], $paypal["ccaps"]/*, $paypal["eotper"] */) = preg_split ("/\:/", $paypal["item_number"], 2);
58
  /**/
59
  $paypal["ip"] = (preg_match ("/ip address/i", $paypal["option_name2"]) && $paypal["option_selection2"]) ? $paypal["option_selection2"] : "";
60
  $paypal["ip"] = (!$paypal["ip"] && preg_match ("/^[a-z0-9]+~[0-9\.]+$/i", $paypal["invoice"])) ? preg_replace ("/^[a-z0-9]+~/i", "", $paypal["invoice"]) : $paypal["ip"];
85
  $user_reg_ip = get_user_option ("s2member_registration_ip", $user_id); /* Original IP during Registration. */
86
  $user_reg_ip = $paypal["ip"] = ($user_reg_ip) ? $user_reg_ip : $paypal["ip"]; /* Now merge conditionally. */
87
  /**/
88
+ if (is_multisite () && !is_user_member_of_blog ($user_id)) /* Must have a Role on this Blog. */
89
  {
90
+ add_existing_user_to_blog(array ("user_id" => $user_id, "role" => "s2member_level" . $paypal["level"]));
91
  $user = new WP_User ($user_id); /* Now update the $user object we're using. */
92
  }
93
  /**/
96
  if ($current_role !== "s2member_level" . $paypal["level"]) /* Only if we need to. */
97
  $user->set_role ("s2member_level" . $paypal["level"]); /* (upgrade/downgrade) */
98
  /**/
99
+ if ($paypal["ccaps"] && preg_match ("/^-all/", str_replace ("+", "", $paypal["ccaps"])))
100
  foreach ($user->allcaps as $cap => $cap_enabled)
101
  if (preg_match ("/^access_s2member_ccap_/", $cap))
102
  $user->remove_cap ($ccap = $cap);
103
  /**/
104
+ if ($paypal["ccaps"] && preg_replace ("/^-all[\r\n\t\s;,]*/", "", str_replace ("+", "", $paypal["ccaps"])))
105
+ foreach (preg_split ("/[\r\n\t\s;,]+/", preg_replace ("/^-all[\r\n\t\s;,]*/", "", str_replace ("+", "", $paypal["ccaps"]))) as $ccap)
106
+ if (strlen ($ccap = trim (strtolower (preg_replace ("/[^a-z_0-9]/i", "", $ccap)))))
107
+ $user->add_cap ("access_s2member_ccap_" . $ccap);
108
  /**/
109
  update_user_option ($user_id, "s2member_subscr_gateway", $paypal["subscr_gateway"]);
110
  update_user_option ($user_id, "s2member_subscr_id", $paypal["subscr_id"]);
125
  /**/
126
  c_ws_plugin__s2member_user_notes::clear_user_note_lines ($user_id, "/^Demoted by s2Member\:/");
127
  /**/
128
+ $paypal["s2member_log"][] = "s2Member Level/Capabilities updated on ( `subscr_modify` ), a Subscription Modification.";
129
+ /**/
130
+ setcookie ("s2member_tracking", ($s2member_tracking = c_ws_plugin__s2member_utils_encryption::encrypt ($paypal["subscr_id"])), time () + 31556926, COOKIEPATH, COOKIE_DOMAIN) . setcookie ("s2member_tracking", $s2member_tracking, time () + 31556926, SITECOOKIEPATH, COOKIE_DOMAIN) . ($_COOKIE["s2member_tracking"] = $s2member_tracking);
131
+ /**/
132
+ $paypal["s2member_log"][] = "Transient Tracking Cookie set on ( `subscr_modify` ), a Subscription Modification.";
133
+ /**/
134
+ if ($processing && ($code = $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["modification_tracking_codes"]) && is_array ($cv = preg_split ("/\|/", $paypal["custom"])))
135
+ {
136
+ if (($code = preg_replace ("/%%cv([0-9]+)%%/ei", 'trim($cv[$1])', $code)) && ($code = preg_replace ("/%%subscr_id%%/i", c_ws_plugin__s2member_utils_strings::esc_ds ($paypal["subscr_id"]), $code)))
137
+ if (($code = preg_replace ("/%%initial%%/i", c_ws_plugin__s2member_utils_strings::esc_ds ($paypal["initial"]), $code)) && ($code = preg_replace ("/%%regular%%/i", c_ws_plugin__s2member_utils_strings::esc_ds ($paypal["regular"]), $code)) && ($code = preg_replace ("/%%recurring%%/i", c_ws_plugin__s2member_utils_strings::esc_ds ($paypal["recurring"]), $code)))
138
+ if (($code = preg_replace ("/%%initial_term%%/i", c_ws_plugin__s2member_utils_strings::esc_ds ($paypal["initial_term"]), $code)) && ($code = preg_replace ("/%%regular_term%%/i", c_ws_plugin__s2member_utils_strings::esc_ds ($paypal["regular_term"]), $code)))
139
+ if (($code = preg_replace ("/%%item_number%%/i", c_ws_plugin__s2member_utils_strings::esc_ds ($paypal["item_number"]), $code)) && ($code = preg_replace ("/%%item_name%%/i", c_ws_plugin__s2member_utils_strings::esc_ds ($paypal["item_name"]), $code)))
140
+ if (($code = preg_replace ("/%%first_name%%/i", c_ws_plugin__s2member_utils_strings::esc_ds ($paypal["first_name"]), $code)) && ($code = preg_replace ("/%%last_name%%/i", c_ws_plugin__s2member_utils_strings::esc_ds ($paypal["last_name"]), $code)))
141
+ if (($code = preg_replace ("/%%full_name%%/i", c_ws_plugin__s2member_utils_strings::esc_ds (trim ($paypal["first_name"] . " " . $paypal["last_name"])), $code)))
142
+ if (($code = preg_replace ("/%%payer_email%%/i", c_ws_plugin__s2member_utils_strings::esc_ds ($paypal["payer_email"]), $code)))
143
+ {
144
+ if (($code = preg_replace ("/%%user_first_name%%/i", c_ws_plugin__s2member_utils_strings::esc_ds ($user->first_name), $code)) && ($code = preg_replace ("/%%user_last_name%%/i", c_ws_plugin__s2member_utils_strings::esc_ds ($user->last_name), $code)))
145
+ if (($code = preg_replace ("/%%user_full_name%%/i", c_ws_plugin__s2member_utils_strings::esc_ds (trim ($user->first_name . " " . $user->last_name)), $code)))
146
+ if (($code = preg_replace ("/%%user_email%%/i", c_ws_plugin__s2member_utils_strings::esc_ds ($user->user_email), $code)))
147
+ if (($code = preg_replace ("/%%user_login%%/i", c_ws_plugin__s2member_utils_strings::esc_ds ($user->user_login), $code)))
148
+ if (($code = preg_replace ("/%%user_ip%%/i", c_ws_plugin__s2member_utils_strings::esc_ds ($user_reg_ip), $code)))
149
+ if (($code = preg_replace ("/%%user_id%%/i", c_ws_plugin__s2member_utils_strings::esc_ds ($user_id), $code)))
150
+ {
151
+ if (is_array ($fields) && !empty ($fields))
152
+ foreach ($fields as $var => $val) /* Custom Registration Fields. */
153
+ if (!($code = preg_replace ("/%%" . preg_quote ($var, "/") . "%%/i", c_ws_plugin__s2member_utils_strings::esc_ds (maybe_serialize ($val)), $code)))
154
+ break;
155
+ /**/
156
+ if (($code = trim (preg_replace ("/%%(.+?)%%/i", "", $code)))) /* This gets stored into a Transient Queue. */
157
+ {
158
+ $paypal["s2member_log"][] = "Storing Modification Tracking Codes into a Transient Queue. These will be processed on-site.";
159
+ set_transient ("s2m_" . md5 ("s2member_transient_modification_tracking_codes_" . $paypal["subscr_id"]), $code, 43200);
160
+ }
161
+ }
162
+ }
163
+ }
164
  /**/
165
+ eval('foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;');
166
  do_action ("ws_plugin__s2member_during_paypal_return_during_subscr_modify", get_defined_vars ());
167
  unset ($__refs, $__v); /* Unset defined __refs, __v. */
168
  /**/
170
  {
171
  $paypal["s2member_log"][] = "Redirecting this Member to a custom URL after modification: " . $redirection_url_after_modification;
172
  /**/
173
+ wp_redirect($redirection_url_after_modification);
174
  }
175
  else /* Else, use standard/default handling in this scenario. Have the Customer log in again. */
176
  {
214
  "Back To Home Page", home_url ("/"));
215
  }
216
  /**/
217
+ eval('foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;');
218
  do_action ("ws_plugin__s2member_during_paypal_return_after_subscr_modify", get_defined_vars ());
219
  unset ($__refs, $__v); /* Unset defined __refs, __v. */
220
  /**/
includes/classes/paypal-return-in-subscr-or-wa-w-level.inc.php CHANGED
@@ -123,7 +123,7 @@ if (!class_exists ("c_ws_plugin__s2member_paypal_return_in_subscr_or_wa_w_level"
123
  $user_reg_ip = get_user_option ("s2member_registration_ip", $user_id); /* Original IP during Registration. */
124
  $user_reg_ip = $paypal["ip"] = ($user_reg_ip) ? $user_reg_ip : $paypal["ip"]; /* Now merge conditionally. */
125
  /**/
126
- if (is_multisite () && !is_user_member_of_blog ($user_id))
127
  {
128
  add_existing_user_to_blog (array ("user_id" => $user_id, "role" => "s2member_level" . $paypal["level"]));
129
  $user = new WP_User ($user_id);
@@ -134,14 +134,15 @@ if (!class_exists ("c_ws_plugin__s2member_paypal_return_in_subscr_or_wa_w_level"
134
  if ($current_role !== "s2member_level" . $paypal["level"]) /* Only if we need to. */
135
  $user->set_role ("s2member_level" . $paypal["level"]); /* (upgrade/downgrade) */
136
  /**/
137
- if (!preg_match ("/^\+/", $paypal["ccaps"]))
138
  foreach ($user->allcaps as $cap => $cap_enabled)
139
  if (preg_match ("/^access_s2member_ccap_/", $cap))
140
  $user->remove_cap ($ccap = $cap);
141
  /**/
142
- foreach (preg_split ("/[\r\n\t\s;,]+/", ltrim ($paypal["ccaps"], "+")) as $ccap)
143
- if (strlen ($ccap)) /* Don't add empty Custom Capabilities. */
144
- $user->add_cap ("access_s2member_ccap_" . trim (strtolower ($ccap)));
 
145
  /**/
146
  update_user_option ($user_id, "s2member_subscr_gateway", $paypal["subscr_gateway"]);
147
  update_user_option ($user_id, "s2member_subscr_id", $paypal["subscr_id"]);
@@ -172,6 +173,41 @@ if (!class_exists ("c_ws_plugin__s2member_paypal_return_in_subscr_or_wa_w_level"
172
  /**/
173
  $paypal["s2member_log"][] = "s2Member Level/Capabilities updated w/ advanced update routines.";
174
  /**/
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
175
  eval ('foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;');
176
  do_action ("ws_plugin__s2member_during_paypal_return_during_subscr_signup_w_update_vars", get_defined_vars ());
177
  unset ($__refs, $__v); /* Unset defined __refs, __v. */
@@ -230,14 +266,14 @@ if (!class_exists ("c_ws_plugin__s2member_paypal_return_in_subscr_or_wa_w_level"
230
  /**/
231
  $paypal["s2member_log"][] = "s2Member `txn_type` identified as ( `web_accept|subscr_signup|subscr_payment` ) w/o update vars.";
232
  /**/
233
- setcookie ("s2member_subscr_gateway", ($s2member_subscr_gateway = c_ws_plugin__s2member_utils_encryption::encrypt ($paypal["subscr_gateway"])), time () + 31556926, "/") . ($_COOKIE["s2member_subscr_gateway"] = $s2member_subscr_gateway);
234
- setcookie ("s2member_subscr_id", ($s2member_subscr_id = c_ws_plugin__s2member_utils_encryption::encrypt ($paypal["subscr_id"])), time () + 31556926, "/") . ($_COOKIE["s2member_subscr_id"] = $s2member_subscr_id);
235
- setcookie ("s2member_custom", ($s2member_custom = c_ws_plugin__s2member_utils_encryption::encrypt ($paypal["custom"])), time () + 31556926, "/") . ($_COOKIE["s2member_custom"] = $s2member_custom);
236
- setcookie ("s2member_item_number", ($s2member_item_number = c_ws_plugin__s2member_utils_encryption::encrypt ($paypal["item_number"])), time () + 31556926, "/") . ($_COOKIE["s2member_item_number"] = $s2member_item_number);
237
  /**/
238
  $paypal["s2member_log"][] = "Registration Cookies set on ( `web_accept|subscr_signup|subscr_payment` ) w/o update vars.";
239
  /**/
240
- setcookie ("s2member_signup_tracking", ($s2member_signup_tracking = c_ws_plugin__s2member_utils_encryption::encrypt ($paypal["subscr_id"])), time () + 31556926, "/") . ($_COOKIE["s2member_signup_tracking"] = $s2member_signup_tracking);
241
  /**/
242
  $paypal["s2member_log"][] = "Transient Tracking Cookie set on ( `web_accept|subscr_signup|subscr_payment` ) w/o update vars.";
243
  /**/
123
  $user_reg_ip = get_user_option ("s2member_registration_ip", $user_id); /* Original IP during Registration. */
124
  $user_reg_ip = $paypal["ip"] = ($user_reg_ip) ? $user_reg_ip : $paypal["ip"]; /* Now merge conditionally. */
125
  /**/
126
+ if (is_multisite () && !is_user_member_of_blog ($user_id)) /* Must have a Role on this Blog. */
127
  {
128
  add_existing_user_to_blog (array ("user_id" => $user_id, "role" => "s2member_level" . $paypal["level"]));
129
  $user = new WP_User ($user_id);
134
  if ($current_role !== "s2member_level" . $paypal["level"]) /* Only if we need to. */
135
  $user->set_role ("s2member_level" . $paypal["level"]); /* (upgrade/downgrade) */
136
  /**/
137
+ if ($paypal["ccaps"] && preg_match ("/^-all/", str_replace ("+", "", $paypal["ccaps"])))
138
  foreach ($user->allcaps as $cap => $cap_enabled)
139
  if (preg_match ("/^access_s2member_ccap_/", $cap))
140
  $user->remove_cap ($ccap = $cap);
141
  /**/
142
+ if ($paypal["ccaps"] && preg_replace ("/^-all[\r\n\t\s;,]*/", "", str_replace ("+", "", $paypal["ccaps"])))
143
+ foreach (preg_split ("/[\r\n\t\s;,]+/", preg_replace ("/^-all[\r\n\t\s;,]*/", "", str_replace ("+", "", $paypal["ccaps"]))) as $ccap)
144
+ if (strlen ($ccap = trim (strtolower (preg_replace ("/[^a-z_0-9]/i", "", $ccap)))))
145
+ $user->add_cap ("access_s2member_ccap_" . $ccap);
146
  /**/
147
  update_user_option ($user_id, "s2member_subscr_gateway", $paypal["subscr_gateway"]);
148
  update_user_option ($user_id, "s2member_subscr_id", $paypal["subscr_id"]);
173
  /**/
174
  $paypal["s2member_log"][] = "s2Member Level/Capabilities updated w/ advanced update routines.";
175
  /**/
176
+ setcookie ("s2member_tracking", ($s2member_tracking = c_ws_plugin__s2member_utils_encryption::encrypt ($paypal["subscr_id"])), time () + 31556926, COOKIEPATH, COOKIE_DOMAIN) . setcookie ("s2member_tracking", $s2member_tracking, time () + 31556926, SITECOOKIEPATH, COOKIE_DOMAIN) . ($_COOKIE["s2member_tracking"] = $s2member_tracking);
177
+ /**/
178
+ $paypal["s2member_log"][] = "Transient Tracking Cookie set on ( `web_accept|subscr_signup|subscr_payment` ) w/ update vars.";
179
+ /**/
180
+ if ($processing && $tracking_properties && ($code = $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["modification_tracking_codes"]) && is_array ($cv = preg_split ("/\|/", $paypal["custom"])))
181
+ {
182
+ if (($code = preg_replace ("/%%cv([0-9]+)%%/ei", 'trim($cv[$1])', $code)) && ($code = preg_replace ("/%%subscr_id%%/i", c_ws_plugin__s2member_utils_strings::esc_ds ($paypal["subscr_id"]), $code)))
183
+ if (($code = preg_replace ("/%%initial%%/i", c_ws_plugin__s2member_utils_strings::esc_ds ($paypal["initial"]), $code)) && ($code = preg_replace ("/%%regular%%/i", c_ws_plugin__s2member_utils_strings::esc_ds ($paypal["regular"]), $code)) && ($code = preg_replace ("/%%recurring%%/i", c_ws_plugin__s2member_utils_strings::esc_ds ($paypal["recurring"]), $code)))
184
+ if (($code = preg_replace ("/%%initial_term%%/i", c_ws_plugin__s2member_utils_strings::esc_ds ($paypal["initial_term"]), $code)) && ($code = preg_replace ("/%%regular_term%%/i", c_ws_plugin__s2member_utils_strings::esc_ds ($paypal["regular_term"]), $code)))
185
+ if (($code = preg_replace ("/%%item_number%%/i", c_ws_plugin__s2member_utils_strings::esc_ds ($paypal["item_number"]), $code)) && ($code = preg_replace ("/%%item_name%%/i", c_ws_plugin__s2member_utils_strings::esc_ds ($paypal["item_name"]), $code)))
186
+ if (($code = preg_replace ("/%%first_name%%/i", c_ws_plugin__s2member_utils_strings::esc_ds ($paypal["first_name"]), $code)) && ($code = preg_replace ("/%%last_name%%/i", c_ws_plugin__s2member_utils_strings::esc_ds ($paypal["last_name"]), $code)))
187
+ if (($code = preg_replace ("/%%full_name%%/i", c_ws_plugin__s2member_utils_strings::esc_ds (trim ($paypal["first_name"] . " " . $paypal["last_name"])), $code)))
188
+ if (($code = preg_replace ("/%%payer_email%%/i", c_ws_plugin__s2member_utils_strings::esc_ds ($paypal["payer_email"]), $code)))
189
+ {
190
+ if (($code = preg_replace ("/%%user_first_name%%/i", c_ws_plugin__s2member_utils_strings::esc_ds ($user->first_name), $code)) && ($code = preg_replace ("/%%user_last_name%%/i", c_ws_plugin__s2member_utils_strings::esc_ds ($user->last_name), $code)))
191
+ if (($code = preg_replace ("/%%user_full_name%%/i", c_ws_plugin__s2member_utils_strings::esc_ds (trim ($user->first_name . " " . $user->last_name)), $code)))
192
+ if (($code = preg_replace ("/%%user_email%%/i", c_ws_plugin__s2member_utils_strings::esc_ds ($user->user_email), $code)))
193
+ if (($code = preg_replace ("/%%user_login%%/i", c_ws_plugin__s2member_utils_strings::esc_ds ($user->user_login), $code)))
194
+ if (($code = preg_replace ("/%%user_ip%%/i", c_ws_plugin__s2member_utils_strings::esc_ds ($user_reg_ip), $code)))
195
+ if (($code = preg_replace ("/%%user_id%%/i", c_ws_plugin__s2member_utils_strings::esc_ds ($user_id), $code)))
196
+ {
197
+ if (is_array ($fields) && !empty ($fields))
198
+ foreach ($fields as $var => $val) /* Custom Registration Fields. */
199
+ if (!($code = preg_replace ("/%%" . preg_quote ($var, "/") . "%%/i", c_ws_plugin__s2member_utils_strings::esc_ds (maybe_serialize ($val)), $code)))
200
+ break;
201
+ /**/
202
+ if (($code = trim (preg_replace ("/%%(.+?)%%/i", "", $code)))) /* This gets stored into a Transient Queue. */
203
+ {
204
+ $paypal["s2member_log"][] = "Storing Modification Tracking Codes into a Transient Queue. These will be processed on-site.";
205
+ set_transient ("s2m_" . md5 ("s2member_transient_modification_tracking_codes_" . $paypal["subscr_id"]), $code, 43200);
206
+ }
207
+ }
208
+ }
209
+ }
210
+ /**/
211
  eval ('foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;');
212
  do_action ("ws_plugin__s2member_during_paypal_return_during_subscr_signup_w_update_vars", get_defined_vars ());
213
  unset ($__refs, $__v); /* Unset defined __refs, __v. */
266
  /**/
267
  $paypal["s2member_log"][] = "s2Member `txn_type` identified as ( `web_accept|subscr_signup|subscr_payment` ) w/o update vars.";
268
  /**/
269
+ setcookie ("s2member_subscr_gateway", ($s2member_subscr_gateway = c_ws_plugin__s2member_utils_encryption::encrypt ($paypal["subscr_gateway"])), time () + 31556926, COOKIEPATH, COOKIE_DOMAIN) . setcookie ("s2member_subscr_gateway", $s2member_subscr_gateway, time () + 31556926, SITECOOKIEPATH, COOKIE_DOMAIN) . ($_COOKIE["s2member_subscr_gateway"] = $s2member_subscr_gateway);
270
+ setcookie ("s2member_subscr_id", ($s2member_subscr_id = c_ws_plugin__s2member_utils_encryption::encrypt ($paypal["subscr_id"])), time () + 31556926, COOKIEPATH, COOKIE_DOMAIN) . setcookie ("s2member_subscr_id", $s2member_subscr_id, time () + 31556926, SITECOOKIEPATH, COOKIE_DOMAIN) . ($_COOKIE["s2member_subscr_id"] = $s2member_subscr_id);
271
+ setcookie ("s2member_custom", ($s2member_custom = c_ws_plugin__s2member_utils_encryption::encrypt ($paypal["custom"])), time () + 31556926, COOKIEPATH, COOKIE_DOMAIN) . setcookie ("s2member_custom", $s2member_custom, time () + 31556926, SITECOOKIEPATH, COOKIE_DOMAIN) . ($_COOKIE["s2member_custom"] = $s2member_custom);
272
+ setcookie ("s2member_item_number", ($s2member_item_number = c_ws_plugin__s2member_utils_encryption::encrypt ($paypal["item_number"])), time () + 31556926, COOKIEPATH, COOKIE_DOMAIN) . setcookie ("s2member_item_number", $s2member_item_number, time () + 31556926, SITECOOKIEPATH, COOKIE_DOMAIN) . ($_COOKIE["s2member_item_number"] = $s2member_item_number);
273
  /**/
274
  $paypal["s2member_log"][] = "Registration Cookies set on ( `web_accept|subscr_signup|subscr_payment` ) w/o update vars.";
275
  /**/
276
+ setcookie ("s2member_tracking", ($s2member_tracking = c_ws_plugin__s2member_utils_encryption::encrypt ($paypal["subscr_id"])), time () + 31556926, COOKIEPATH, COOKIE_DOMAIN) . setcookie ("s2member_tracking", $s2member_tracking, time () + 31556926, SITECOOKIEPATH, COOKIE_DOMAIN) . ($_COOKIE["s2member_tracking"] = $s2member_tracking);
277
  /**/
278
  $paypal["s2member_log"][] = "Transient Tracking Cookie set on ( `web_accept|subscr_signup|subscr_payment` ) w/o update vars.";
279
  /**/
includes/classes/paypal-return-in-wa-ccaps-wo-level.inc.php ADDED
@@ -0,0 +1,205 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * s2Member's PayPal® Auto-Return/PDT handler ( inner processing routine ).
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\PayPal
15
+ * @since 110720
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_paypal_return_in_wa_ccaps_wo_level"))
21
+ {
22
+ /**
23
+ * s2Member's PayPal® Auto-Return/PDT handler ( inner processing routine ).
24
+ *
25
+ * @package s2Member\PayPal
26
+ * @since 110720
27
+ */
28
+ class c_ws_plugin__s2member_paypal_return_in_wa_ccaps_wo_level
29
+ {
30
+ /**
31
+ * s2Member's PayPal® Auto-Return/PDT handler ( inner processing routine ).
32
+ *
33
+ * @package s2Member\PayPal
34
+ * @since 110720
35
+ *
36
+ * @param array $vars Required. An array of defined variables passed by {@link s2Member\PayPal\c_ws_plugin__s2member_paypal_return_in::paypal_return()}.
37
+ * @return array|bool The original ``$paypal`` array passed in ( extracted ) from ``$vars``, or false when conditions do NOT apply.
38
+ *
39
+ * @todo Optimize with ``empty()`` and ``isset()``.
40
+ */
41
+ public static function cp ($vars = array ()) /* Conditional phase for ``c_ws_plugin__s2member_paypal_notify_in::paypal_notify()``. */
42
+ {
43
+ extract($vars); /* Extract all vars passed in from: ``c_ws_plugin__s2member_paypal_notify_in::paypal_notify()``. */
44
+ /**/
45
+ if (/**/(!empty ($paypal["txn_type"]) && preg_match ("/^web_accept$/i", $paypal["txn_type"]))/**/
46
+ && (!empty ($paypal["item_number"]) && preg_match ($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["membership_item_number_wo_level_regex"], $paypal["item_number"]))/**/
47
+ && (empty ($paypal["payment_status"]) || empty ($payment_status_issues) || !preg_match ($payment_status_issues, $paypal["payment_status"]))/**/
48
+ && (!empty ($paypal["txn_id"]) && ($paypal["subscr_id"] = $paypal["txn_id"])) && (!empty ($paypal["payer_email"]))/**/)
49
+ {
50
+ eval('foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;');
51
+ do_action ("ws_plugin__s2member_during_paypal_return_before_new_ccaps", get_defined_vars ());
52
+ unset ($__refs, $__v); /* Unset defined __refs, __v. */
53
+ /**/
54
+ if (!get_transient ($transient_rtn = "s2m_rtn_" . md5 ("s2member_transient_" . $_paypal_s)) && set_transient ($transient_rtn, time (), 31556926 * 10))
55
+ {
56
+ $paypal["s2member_log"][] = "s2Member `txn_type` identified as ( `web_accept` ) w/ update vars for Capabilities w/o Level.";
57
+ /**/
58
+ list ($paypal["level"], $paypal["ccaps"], $paypal["eotper"]) = preg_split ("/\:/", $paypal["item_number"], 3);
59
+ /**/
60
+ $paypal["ip"] = (preg_match ("/ip address/i", $paypal["option_name2"]) && $paypal["option_selection2"]) ? $paypal["option_selection2"] : "";
61
+ $paypal["ip"] = (!$paypal["ip"] && preg_match ("/^[a-z0-9]+~[0-9\.]+$/i", $paypal["invoice"])) ? preg_replace ("/^[a-z0-9]+~/i", "", $paypal["invoice"]) : $paypal["ip"];
62
+ $paypal["ip"] = (!$paypal["ip"] && $_SERVER["REMOTE_ADDR"]) ? $_SERVER["REMOTE_ADDR"] : $paypal["ip"];
63
+ /**/
64
+ if (preg_match ("/(referenc|associat|updat|upgrad)/i", $paypal["option_name1"]) && $paypal["option_selection1"]) /* Must have this information for Capability additions. */
65
+ {
66
+ if (($user_id = c_ws_plugin__s2member_utils_users::get_user_id_with ($paypal["txn_id"], $paypal["option_selection1"])) && is_object ($user = new WP_User ($user_id)) && $user->ID)
67
+ {
68
+ if (!$user->has_cap ("administrator")) /* Do NOT process this routine on Administrators. */
69
+ {
70
+ $processing = $during = true; /* Yes, we ARE processing this. */
71
+ /**/
72
+ $fields = get_user_option ("s2member_custom_fields", $user_id); /* These will be needed in the routines below. */
73
+ $user_reg_ip = get_user_option ("s2member_registration_ip", $user_id); /* Original IP during Registration. */
74
+ $user_reg_ip = $paypal["ip"] = ($user_reg_ip) ? $user_reg_ip : $paypal["ip"]; /* Now merge conditionally. */
75
+ /**/
76
+ if (is_multisite () && !is_user_member_of_blog ($user_id)) /* Must have a Role on this Blog. */
77
+ {
78
+ add_existing_user_to_blog(array ("user_id" => $user_id, "role" => get_option ("default_role")));
79
+ $user = new WP_User ($user_id);
80
+ }
81
+ /**/
82
+ if ($paypal["ccaps"] && preg_match ("/^-all/", str_replace ("+", "", $paypal["ccaps"])))
83
+ foreach ($user->allcaps as $cap => $cap_enabled)
84
+ if (preg_match ("/^access_s2member_ccap_/", $cap))
85
+ $user->remove_cap ($ccap = $cap);
86
+ /**/
87
+ if ($paypal["ccaps"] && preg_replace ("/^-all[\r\n\t\s;,]*/", "", str_replace ("+", "", $paypal["ccaps"])))
88
+ foreach (preg_split ("/[\r\n\t\s;,]+/", preg_replace ("/^-all[\r\n\t\s;,]*/", "", str_replace ("+", "", $paypal["ccaps"]))) as $ccap)
89
+ if (strlen ($ccap = trim (strtolower (preg_replace ("/[^a-z_0-9]/i", "", $ccap)))))
90
+ $user->add_cap ("access_s2member_ccap_" . $ccap);
91
+ /**/
92
+ if (!get_user_option ("s2member_registration_ip", $user_id))
93
+ update_user_option ($user_id, "s2member_registration_ip", $paypal["ip"]);
94
+ /**/
95
+ $paypal["s2member_log"][] = "s2Member Custom Capabilities updated w/ advanced update routines.";
96
+ /**/
97
+ setcookie ("s2member_tracking", ($s2member_tracking = c_ws_plugin__s2member_utils_encryption::encrypt ($paypal["subscr_id"])), time () + 31556926, COOKIEPATH, COOKIE_DOMAIN) . setcookie ("s2member_tracking", $s2member_tracking, time () + 31556926, SITECOOKIEPATH, COOKIE_DOMAIN) . ($_COOKIE["s2member_tracking"] = $s2member_tracking);
98
+ /**/
99
+ $paypal["s2member_log"][] = "Transient Tracking Cookie set on ( `web_accept` ) w/ update vars for Capabilities w/o Level.";
100
+ /**/
101
+ if ($processing && ($code = $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["ccap_tracking_codes"]) && is_array ($cv = preg_split ("/\|/", $paypal["custom"])))
102
+ {
103
+ if (($code = preg_replace ("/%%cv([0-9]+)%%/ei", 'trim($cv[$1])', $code)) && ($code = preg_replace ("/%%subscr_id%%/i", c_ws_plugin__s2member_utils_strings::esc_ds ($paypal["subscr_id"]), $code)))
104
+ if (($code = preg_replace ("/%%amount%%/i", c_ws_plugin__s2member_utils_strings::esc_ds ($paypal["mc_gross"]), $code)) && ($code = preg_replace ("/%%txn_id%%/i", c_ws_plugin__s2member_utils_strings::esc_ds ($paypal["txn_id"]), $code)))
105
+ if (($code = preg_replace ("/%%item_number%%/i", c_ws_plugin__s2member_utils_strings::esc_ds ($paypal["item_number"]), $code)) && ($code = preg_replace ("/%%item_name%%/i", c_ws_plugin__s2member_utils_strings::esc_ds ($paypal["item_name"]), $code)))
106
+ if (($code = preg_replace ("/%%first_name%%/i", c_ws_plugin__s2member_utils_strings::esc_ds ($paypal["first_name"]), $code)) && ($code = preg_replace ("/%%last_name%%/i", c_ws_plugin__s2member_utils_strings::esc_ds ($paypal["last_name"]), $code)))
107
+ if (($code = preg_replace ("/%%full_name%%/i", c_ws_plugin__s2member_utils_strings::esc_ds (trim ($paypal["first_name"] . " " . $paypal["last_name"])), $code)))
108
+ if (($code = preg_replace ("/%%payer_email%%/i", c_ws_plugin__s2member_utils_strings::esc_ds ($paypal["payer_email"]), $code)))
109
+ {
110
+ if (($code = preg_replace ("/%%user_first_name%%/i", c_ws_plugin__s2member_utils_strings::esc_ds ($user->first_name), $code)) && ($code = preg_replace ("/%%user_last_name%%/i", c_ws_plugin__s2member_utils_strings::esc_ds ($user->last_name), $code)))
111
+ if (($code = preg_replace ("/%%user_full_name%%/i", c_ws_plugin__s2member_utils_strings::esc_ds (trim ($user->first_name . " " . $user->last_name)), $code)))
112
+ if (($code = preg_replace ("/%%user_email%%/i", c_ws_plugin__s2member_utils_strings::esc_ds ($user->user_email), $code)))
113
+ if (($code = preg_replace ("/%%user_login%%/i", c_ws_plugin__s2member_utils_strings::esc_ds ($user->user_login), $code)))
114
+ if (($code = preg_replace ("/%%user_ip%%/i", c_ws_plugin__s2member_utils_strings::esc_ds ($user_reg_ip), $code)))
115
+ if (($code = preg_replace ("/%%user_id%%/i", c_ws_plugin__s2member_utils_strings::esc_ds ($user_id), $code)))
116
+ {
117
+ if (is_array ($fields) && !empty ($fields))
118
+ foreach ($fields as $var => $val) /* Custom Registration Fields. */
119
+ if (!($code = preg_replace ("/%%" . preg_quote ($var, "/") . "%%/i", c_ws_plugin__s2member_utils_strings::esc_ds (maybe_serialize ($val)), $code)))
120
+ break;
121
+ /**/
122
+ if (($code = trim (preg_replace ("/%%(.+?)%%/i", "", $code)))) /* This gets stored into a Transient Queue. */
123
+ {
124
+ $paypal["s2member_log"][] = "Storing Payment Tracking Codes into a Transient Queue. These will be processed on-site.";
125
+ set_transient ("s2m_" . md5 ("s2member_transient_ccap_tracking_codes_" . $paypal["txn_id"]), $code, 43200);
126
+ }
127
+ }
128
+ }
129
+ }
130
+ /**/
131
+ eval('foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;');
132
+ do_action ("ws_plugin__s2member_during_paypal_return_during_new_ccaps", get_defined_vars ());
133
+ unset ($__refs, $__v); /* Unset defined __refs, __v. */
134
+ /**/
135
+ if (($redirection_url_after_capabilities = apply_filters ("ws_plugin__s2member_redirection_url_after_capabilities", false, get_defined_vars ())))
136
+ {
137
+ $paypal["s2member_log"][] = "Redirecting Customer to a custom URL after Capabilities: " . $redirection_url_after_capabilities;
138
+ /**/
139
+ wp_redirect($redirection_url_after_capabilities);
140
+ }
141
+ else /* Else, use standard/default handling in this scenario. Have the Customer log in again. */
142
+ {
143
+ $paypal["s2member_log"][] = "Redirecting Customer to the Login Page. They need to log back in.";
144
+ /**/
145
+ echo c_ws_plugin__s2member_return_templates::return_template ($paypal["subscr_gateway"],/**/
146
+ '<strong>Thank you! You now have access to:<br /><em>' . esc_html ($paypal["item_name"]) . '</em></strong>',/**/
147
+ "Please Log Back In ( Click Here )", wp_login_url ());
148
+ }
149
+ }
150
+ else /* Unable to add new Capabilities. The existing User ID is associated with an Administrator. Stopping here. */
151
+ {
152
+ $paypal["s2member_log"][] = "Unable to add new Capabilities. The existing User ID is associated with an Administrator. Stopping here. Otherwise, an Administrator could lose access. Please make sure that you are NOT logged in as an Administrator while testing.";
153
+ /**/
154
+ $paypal["s2member_log"][] = "Redirecting Customer to the Home Page, due to an error that occurred.";
155
+ /**/
156
+ echo c_ws_plugin__s2member_return_templates::return_template ($paypal["subscr_gateway"],/**/
157
+ '<strong>ERROR:</strong> Unable to add new Capabilities.<br />Please contact Support for assistance.<br /><br />The existing User ID is associated with an Administrator. Stopping here. Otherwise, an Administrator could lose access. Please make sure that you are NOT logged in as an Administrator while testing.',/**/
158
+ "Back To Home Page", home_url ("/"));
159
+ }
160
+ }
161
+ else /* Unable to add new Capabilities. Could not get the existing User ID from the DB. */
162
+ {
163
+ $paypal["s2member_log"][] = "Unable to add new Capabilities. Could not get the existing User ID from the DB.";
164
+ /**/
165
+ $paypal["s2member_log"][] = "Redirecting Customer to the Home Page, due to an error that occurred.";
166
+ /**/
167
+ echo c_ws_plugin__s2member_return_templates::return_template ($paypal["subscr_gateway"],/**/
168
+ '<strong>ERROR:</strong> Unable to add new Capabilities.<br />Please contact Support for assistance.<br /><br />Could not get the existing User ID from the DB.',/**/
169
+ "Back To Home Page", home_url ("/"));
170
+ }
171
+ }
172
+ else /* Unable to add new Capabilities. Missing User/Member details. */
173
+ {
174
+ $paypal["s2member_log"][] = "Unable to add new Capabilities. Missing User/Member details. Please check the `on0` and `os0` variables in your Button Code.";
175
+ /**/
176
+ $paypal["s2member_log"][] = "Redirecting Customer to the Home Page, due to an error that occurred.";
177
+ /**/
178
+ echo c_ws_plugin__s2member_return_templates::return_template ($paypal["subscr_gateway"],/**/
179
+ '<strong>ERROR:</strong> Unable to add new Capabilities.<br />Please contact Support for assistance.<br /><br />Missing User/Member details.',/**/
180
+ "Back To Home Page", home_url ("/"));
181
+ }
182
+ }
183
+ else /* Page Expired. Duplicate Return-Data. */
184
+ {
185
+ $paypal["s2member_log"][] = "Page Expired. Duplicate Return-Data.";
186
+ $paypal["s2member_log"][] = "s2Member `txn_type` identified as ( `web_accept` ) w/ update vars for Capabilities w/o Level.";
187
+ $paypal["s2member_log"][] = "Page Expired. Redirecting Customer to the Home Page.";
188
+ /**/
189
+ echo c_ws_plugin__s2member_return_templates::return_template ($paypal["subscr_gateway"],/**/
190
+ '<strong>Page Expired:</strong> Duplicate Return-Data.<br />Please contact Support if you need any assistance.',/**/
191
+ "Back To Home Page", home_url ("/"));
192
+ }
193
+ /**/
194
+ eval('foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;');
195
+ do_action ("ws_plugin__s2member_during_paypal_return_after_new_ccaps", get_defined_vars ());
196
+ unset ($__refs, $__v); /* Unset defined __refs, __v. */
197
+ /**/
198
+ return apply_filters ("c_ws_plugin__s2member_paypal_return_in_wa_ccaps_wo_level", $paypal, get_defined_vars ());
199
+ }
200
+ else
201
+ return apply_filters ("c_ws_plugin__s2member_paypal_return_in_wa_ccaps_wo_level", false, get_defined_vars ());
202
+ }
203
+ }
204
+ }
205
+ ?>
includes/classes/paypal-return-in-web-accept-sp.inc.php CHANGED
@@ -65,7 +65,7 @@ if (!class_exists ("c_ws_plugin__s2member_paypal_return_in_web_accept_sp"))
65
  {
66
  $processing = $during = true; /* Yes, we ARE processing this. */
67
  /**/
68
- setcookie ("s2member_sp_tracking", ($s2member_sp_tracking = c_ws_plugin__s2member_utils_encryption::encrypt ($paypal["txn_id"])), time () + 31556926, "/") . ($_COOKIE["s2member_sp_tracking"] = $s2member_sp_tracking);
69
  /**/
70
  $paypal["s2member_log"][] = "Transient Tracking Cookie set on ( `web_accept` ) for Specific Post/Page Access.";
71
  /**/
65
  {
66
  $processing = $during = true; /* Yes, we ARE processing this. */
67
  /**/
68
+ setcookie ("s2member_sp_tracking", ($s2member_sp_tracking = c_ws_plugin__s2member_utils_encryption::encrypt ($paypal["txn_id"])), time () + 31556926, COOKIEPATH, COOKIE_DOMAIN) . setcookie ("s2member_sp_tracking", $s2member_sp_tracking, time () + 31556926, SITECOOKIEPATH, COOKIE_DOMAIN) . ($_COOKIE["s2member_sp_tracking"] = $s2member_sp_tracking);
69
  /**/
70
  $paypal["s2member_log"][] = "Transient Tracking Cookie set on ( `web_accept` ) for Specific Post/Page Access.";
71
  /**/
includes/classes/paypal-return-in.inc.php CHANGED
@@ -71,6 +71,9 @@ if (!class_exists ("c_ws_plugin__s2member_paypal_return_in"))
71
  if (($_paypal_cp = c_ws_plugin__s2member_paypal_return_in_web_accept_sp::cp (get_defined_vars ())))
72
  $paypal = $_paypal_cp;
73
  /**/
 
 
 
74
  else if (($_paypal_cp = c_ws_plugin__s2member_paypal_return_in_subscr_or_wa_w_level::cp (get_defined_vars ())))
75
  $paypal = $_paypal_cp;
76
  /**/
@@ -159,6 +162,7 @@ if (!class_exists ("c_ws_plugin__s2member_paypal_return_in"))
159
  Logging now supports Multisite Networking as well.
160
  */
161
  $logv = c_ws_plugin__s2member_utilities::ver_details ();
 
162
  $log4 = $_SERVER["HTTP_HOST"] . $_SERVER["REQUEST_URI"] . "\nUser-Agent: " . $_SERVER["HTTP_USER_AGENT"];
163
  $log4 = (is_multisite () && !is_main_site ()) ? ($_log4 = $current_blog->domain . $current_blog->path) . "\n" . $log4 : $log4;
164
  $log2 = (is_multisite () && !is_main_site ()) ? "paypal-rtn-4-" . trim (preg_replace ("/[^a-z0-9]/i", "-", $_log4), "-") . ".log" : "paypal-rtn.log";
@@ -166,7 +170,7 @@ if (!class_exists ("c_ws_plugin__s2member_paypal_return_in"))
166
  if ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["gateway_debug_logs"])
167
  if (is_dir ($logs_dir = $GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["logs_dir"]))
168
  if (is_writable ($logs_dir) && c_ws_plugin__s2member_utils_logs::archive_oversize_log_files ())
169
- file_put_contents ($logs_dir . "/" . $log2, $logv . "\n" . $log4 . "\n" . var_export ($paypal, true) . "\n\n", FILE_APPEND);
170
  /**/
171
  eval ('foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;');
172
  do_action ("ws_plugin__s2member_during_paypal_return", get_defined_vars ());
71
  if (($_paypal_cp = c_ws_plugin__s2member_paypal_return_in_web_accept_sp::cp (get_defined_vars ())))
72
  $paypal = $_paypal_cp;
73
  /**/
74
+ else if (($_paypal_cp = c_ws_plugin__s2member_paypal_return_in_wa_ccaps_wo_level::cp (get_defined_vars ())))
75
+ $paypal = $_paypal_cp;
76
+ /**/
77
  else if (($_paypal_cp = c_ws_plugin__s2member_paypal_return_in_subscr_or_wa_w_level::cp (get_defined_vars ())))
78
  $paypal = $_paypal_cp;
79
  /**/
162
  Logging now supports Multisite Networking as well.
163
  */
164
  $logv = c_ws_plugin__s2member_utilities::ver_details ();
165
+ $logm = c_ws_plugin__s2member_utilities::mem_details ();
166
  $log4 = $_SERVER["HTTP_HOST"] . $_SERVER["REQUEST_URI"] . "\nUser-Agent: " . $_SERVER["HTTP_USER_AGENT"];
167
  $log4 = (is_multisite () && !is_main_site ()) ? ($_log4 = $current_blog->domain . $current_blog->path) . "\n" . $log4 : $log4;
168
  $log2 = (is_multisite () && !is_main_site ()) ? "paypal-rtn-4-" . trim (preg_replace ("/[^a-z0-9]/i", "-", $_log4), "-") . ".log" : "paypal-rtn.log";
170
  if ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["gateway_debug_logs"])
171
  if (is_dir ($logs_dir = $GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["logs_dir"]))
172
  if (is_writable ($logs_dir) && c_ws_plugin__s2member_utils_logs::archive_oversize_log_files ())
173
+ file_put_contents ($logs_dir . "/" . $log2, $logv . "\n" . $logm . "\n" . $log4 . "\n" . var_export ($paypal, true) . "\n\n", FILE_APPEND);
174
  /**/
175
  eval ('foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;');
176
  do_action ("ws_plugin__s2member_during_paypal_return", get_defined_vars ());
includes/classes/paypal-utilities.inc.php CHANGED
@@ -177,6 +177,7 @@ if (!class_exists ("c_ws_plugin__s2member_paypal_utilities"))
177
  Logging now supports Multisite Networking as well.
178
  */
179
  $logv = c_ws_plugin__s2member_utilities::ver_details ();
 
180
  $log4 = $_SERVER["HTTP_HOST"] . $_SERVER["REQUEST_URI"] . "\nUser-Agent: " . $_SERVER["HTTP_USER_AGENT"];
181
  $log4 = (is_multisite () && !is_main_site ()) ? ($_log4 = $current_blog->domain . $current_blog->path) . "\n" . $log4 : $log4;
182
  $log2 = (is_multisite () && !is_main_site ()) ? "paypal-api-4-" . trim (preg_replace ("/[^a-z0-9]/i", "-", $_log4), "-") . ".log" : "paypal-api.log";
@@ -189,7 +190,7 @@ if (!class_exists ("c_ws_plugin__s2member_paypal_utilities"))
189
  if (is_writable ($logs_dir) && c_ws_plugin__s2member_utils_logs::archive_oversize_log_files ())
190
  if (($log = "-------- Input vars: ( " . $input_time . " ) --------\n" . var_export ($post_vars, true) . "\n"))
191
  if (($log .= "-------- Output string/vars: ( " . $output_time . " ) --------\n" . $nvp . "\n" . var_export ($response, true)))
192
- file_put_contents ($logs_dir . "/" . $log2, $logv . "\n" . $log4 . "\n" . $log . "\n\n", FILE_APPEND);
193
  /**/
194
  return apply_filters ("ws_plugin__s2member_paypal_api_response", c_ws_plugin__s2member_paypal_utilities::_paypal_api_response_filters ($response), get_defined_vars ());
195
  }
177
  Logging now supports Multisite Networking as well.
178
  */
179
  $logv = c_ws_plugin__s2member_utilities::ver_details ();
180
+ $logm = c_ws_plugin__s2member_utilities::mem_details ();
181
  $log4 = $_SERVER["HTTP_HOST"] . $_SERVER["REQUEST_URI"] . "\nUser-Agent: " . $_SERVER["HTTP_USER_AGENT"];
182
  $log4 = (is_multisite () && !is_main_site ()) ? ($_log4 = $current_blog->domain . $current_blog->path) . "\n" . $log4 : $log4;
183
  $log2 = (is_multisite () && !is_main_site ()) ? "paypal-api-4-" . trim (preg_replace ("/[^a-z0-9]/i", "-", $_log4), "-") . ".log" : "paypal-api.log";
190
  if (is_writable ($logs_dir) && c_ws_plugin__s2member_utils_logs::archive_oversize_log_files ())
191
  if (($log = "-------- Input vars: ( " . $input_time . " ) --------\n" . var_export ($post_vars, true) . "\n"))
192
  if (($log .= "-------- Output string/vars: ( " . $output_time . " ) --------\n" . $nvp . "\n" . var_export ($response, true)))
193
+ file_put_contents ($logs_dir . "/" . $log2, $logv . "\n" . $logm . "\n" . $log4 . "\n" . $log . "\n\n", FILE_APPEND);
194
  /**/
195
  return apply_filters ("ws_plugin__s2member_paypal_api_response", c_ws_plugin__s2member_paypal_utilities::_paypal_api_response_filters ($response), get_defined_vars ());
196
  }
includes/classes/profile-in.inc.php CHANGED
@@ -118,7 +118,7 @@ if (!class_exists ("c_ws_plugin__s2member_profile_in"))
118
  echo '<td>' . "\n";
119
  echo '<label for="ws-plugin--s2member-profile-first-name">' . "\n";
120
  echo '<strong>First Name *</strong><br />' . "\n";
121
- echo '<input aria-required="true" type="text" maxlength="100" name="ws_plugin__s2member_profile_first_name" id="ws-plugin--s2member-profile-first-name" class="ws-plugin--s2member-profile-field" value="' . format_to_edit ($user->first_name) . '" tabindex="' . esc_attr (($tabindex = $tabindex + 10)) . '" />' . "\n";
122
  echo '</label>' . "\n";
123
  echo '</td>' . "\n";
124
  echo '</tr>' . "\n";
@@ -138,7 +138,7 @@ if (!class_exists ("c_ws_plugin__s2member_profile_in"))
138
  echo '<td>' . "\n";
139
  echo '<label for="ws-plugin--s2member-profile-last-name">' . "\n";
140
  echo '<strong>Last Name *</strong><br />' . "\n";
141
- echo '<input aria-required="true" type="text" maxlength="100" name="ws_plugin__s2member_profile_last_name" id="ws-plugin--s2member-profile-last-name" class="ws-plugin--s2member-profile-field" value="' . format_to_edit ($user->last_name) . '" tabindex="' . esc_attr (($tabindex = $tabindex + 10)) . '" />' . "\n";
142
  echo '</label>' . "\n";
143
  echo '</td>' . "\n";
144
  echo '</tr>' . "\n";
@@ -158,7 +158,7 @@ if (!class_exists ("c_ws_plugin__s2member_profile_in"))
158
  echo '<td>' . "\n";
159
  echo '<label for="ws-plugin--s2member-profile-display-name">' . "\n";
160
  echo '<strong>Display Name *</strong><br />' . "\n";
161
- echo '<input aria-required="true" type="text" maxlength="100" name="ws_plugin__s2member_profile_display_name" id="ws-plugin--s2member-profile-display-name" class="ws-plugin--s2member-profile-field" value="' . format_to_edit ($user->display_name) . '" tabindex="' . esc_attr (($tabindex = $tabindex + 10)) . '" />' . "\n";
162
  echo '</label>' . "\n";
163
  echo '</td>' . "\n";
164
  echo '</tr>' . "\n";
118
  echo '<td>' . "\n";
119
  echo '<label for="ws-plugin--s2member-profile-first-name">' . "\n";
120
  echo '<strong>First Name *</strong><br />' . "\n";
121
+ echo '<input aria-required="true" type="text" maxlength="100" name="ws_plugin__s2member_profile_first_name" id="ws-plugin--s2member-profile-first-name" class="ws-plugin--s2member-profile-field" value="' . esc_attr ($user->first_name) . '" tabindex="' . esc_attr (($tabindex = $tabindex + 10)) . '" />' . "\n";
122
  echo '</label>' . "\n";
123
  echo '</td>' . "\n";
124
  echo '</tr>' . "\n";
138
  echo '<td>' . "\n";
139
  echo '<label for="ws-plugin--s2member-profile-last-name">' . "\n";
140
  echo '<strong>Last Name *</strong><br />' . "\n";
141
+ echo '<input aria-required="true" type="text" maxlength="100" name="ws_plugin__s2member_profile_last_name" id="ws-plugin--s2member-profile-last-name" class="ws-plugin--s2member-profile-field" value="' . esc_attr ($user->last_name) . '" tabindex="' . esc_attr (($tabindex = $tabindex + 10)) . '" />' . "\n";
142
  echo '</label>' . "\n";
143
  echo '</td>' . "\n";
144
  echo '</tr>' . "\n";
158
  echo '<td>' . "\n";
159
  echo '<label for="ws-plugin--s2member-profile-display-name">' . "\n";
160
  echo '<strong>Display Name *</strong><br />' . "\n";
161
+ echo '<input aria-required="true" type="text" maxlength="100" name="ws_plugin__s2member_profile_display_name" id="ws-plugin--s2member-profile-display-name" class="ws-plugin--s2member-profile-field" value="' . esc_attr ($user->display_name) . '" tabindex="' . esc_attr (($tabindex = $tabindex + 10)) . '" />' . "\n";
162
  echo '</label>' . "\n";
163
  echo '</td>' . "\n";
164
  echo '</tr>' . "\n";
includes/classes/register-in.inc.php CHANGED
@@ -56,10 +56,10 @@ if (!class_exists ("c_ws_plugin__s2member_register_in"))
56
  /**/
57
  if (($reg_cookies = c_ws_plugin__s2member_register_access::reg_cookies_ok ()) && extract ($reg_cookies))
58
  {
59
- setcookie ("s2member_subscr_gateway", $_COOKIE["s2member_subscr_gateway"], time () + 31556926, "/");
60
- setcookie ("s2member_subscr_id", $_COOKIE["s2member_subscr_id"], time () + 31556926, "/");
61
- setcookie ("s2member_custom", $_COOKIE["s2member_custom"], time () + 31556926, "/");
62
- setcookie ("s2member_item_number", $_COOKIE["s2member_item_number"], time () + 31556926, "/");
63
  /**/
64
  do_action ("ws_plugin__s2member_during_register", get_defined_vars ());
65
  /**/
56
  /**/
57
  if (($reg_cookies = c_ws_plugin__s2member_register_access::reg_cookies_ok ()) && extract ($reg_cookies))
58
  {
59
+ setcookie ("s2member_subscr_gateway", $_COOKIE["s2member_subscr_gateway"], time () + 31556926, COOKIEPATH, COOKIE_DOMAIN) . setcookie ("s2member_subscr_gateway", $_COOKIE["s2member_subscr_gateway"], time () + 31556926, SITECOOKIEPATH, COOKIE_DOMAIN);
60
+ setcookie ("s2member_subscr_id", $_COOKIE["s2member_subscr_id"], time () + 31556926, COOKIEPATH, COOKIE_DOMAIN) . setcookie ("s2member_subscr_id", $_COOKIE["s2member_subscr_id"], time () + 31556926, SITECOOKIEPATH, COOKIE_DOMAIN);
61
+ setcookie ("s2member_custom", $_COOKIE["s2member_custom"], time () + 31556926, COOKIEPATH, COOKIE_DOMAIN) . setcookie ("s2member_custom", $_COOKIE["s2member_custom"], time () + 31556926, SITECOOKIEPATH, COOKIE_DOMAIN);
62
+ setcookie ("s2member_item_number", $_COOKIE["s2member_item_number"], time () + 31556926, COOKIEPATH, COOKIE_DOMAIN) . setcookie ("s2member_item_number", $_COOKIE["s2member_item_number"], time () + 31556926, SITECOOKIEPATH, COOKIE_DOMAIN);
63
  /**/
64
  do_action ("ws_plugin__s2member_during_register", get_defined_vars ());
65
  /**/
includes/classes/registrations.inc.php CHANGED
@@ -495,7 +495,7 @@ if (!class_exists ("c_ws_plugin__s2member_registrations"))
495
  if ($_pmr["field_1"] && preg_match ("/^(.+?) (.+)$/", $_pmr["field_1"]))
496
  $lname = trim (preg_replace ("/^(.+?) (.+)$/", "$2", $_pmr["field_1"]));
497
  /**/
498
- if (!$fname) /* Default to Username? */
499
  if ($login) /* Username and empty Last Name. */
500
  eval ('$fname = trim ($login); $lname = "";');
501
  /**/
@@ -553,15 +553,15 @@ if (!class_exists ("c_ws_plugin__s2member_registrations"))
553
  if ($current_role !== $role) /* Only if NOT the current Role. */
554
  $user->set_role ($role); /* s2Member. */
555
  /**/
556
- if (!preg_match ("/^\+/", $ccaps))
557
  foreach ($user->allcaps as $cap => $cap_enabled)
558
  if (preg_match ("/^access_s2member_ccap_/", $cap))
559
  $user->remove_cap ($ccap = $cap);
560
  /**/
561
- if ($ccaps) /* Add Custom Capabilities. */
562
- foreach (preg_split ("/[\r\n\t\s;,]+/", ltrim ($ccaps, "+")) as $ccap)
563
- if (strlen ($ccap)) /* Don't add empty Custom Capabilities. */
564
- $user->add_cap ("access_s2member_ccap_" . trim (strtolower ($ccap)));
565
  /**/
566
  if ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["custom_reg_fields"])
567
  foreach (json_decode ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["custom_reg_fields"], true) as $field)
@@ -601,8 +601,8 @@ if (!class_exists ("c_ws_plugin__s2member_registrations"))
601
  delete_transient ($transient); /* This can be deleted now. */
602
  }
603
  /**/
604
- if (!headers_sent ()) /* Only if headers are NOT yet sent. */
605
- @setcookie ("s2member_signup_tracking", ($s2member_signup_tracking = c_ws_plugin__s2member_utils_encryption::encrypt ($subscr_id)), time () + 31556926, "/") . ($_COOKIE["s2member_signup_tracking"] = $s2member_signup_tracking);
606
  /**/
607
  eval ('foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;');
608
  do_action ("ws_plugin__s2member_during_configure_user_registration_front_side_paid", get_defined_vars ());
@@ -662,7 +662,7 @@ if (!class_exists ("c_ws_plugin__s2member_registrations"))
662
  if ($_pmr["field_1"] && preg_match ("/^(.+?) (.+)$/", $_pmr["field_1"]))
663
  $lname = trim (preg_replace ("/^(.+?) (.+)$/", "$2", $_pmr["field_1"]));
664
  /**/
665
- if (!$fname) /* Default to Username? */
666
  if ($login) /* Username and empty Last Name. */
667
  eval ('$fname = trim ($login); $lname = "";');
668
  /**/
@@ -720,15 +720,15 @@ if (!class_exists ("c_ws_plugin__s2member_registrations"))
720
  if ($current_role !== $role) /* Only if NOT the current Role. */
721
  $user->set_role ($role); /* s2Member. */
722
  /**/
723
- if (!preg_match ("/^\+/", $ccaps))
724
  foreach ($user->allcaps as $cap => $cap_enabled)
725
  if (preg_match ("/^access_s2member_ccap_/", $cap))
726
  $user->remove_cap ($ccap = $cap);
727
  /**/
728
- if ($ccaps) /* Add Custom Capabilities. */
729
- foreach (preg_split ("/[\r\n\t\s;,]+/", ltrim ($ccaps, "+")) as $ccap)
730
- if (strlen ($ccap)) /* Don't add empty Custom Capabilities. */
731
- $user->add_cap ("access_s2member_ccap_" . trim (strtolower ($ccap)));
732
  /**/
733
  if ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["custom_reg_fields"])
734
  foreach (json_decode ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["custom_reg_fields"], true) as $field)
@@ -796,7 +796,7 @@ if (!class_exists ("c_ws_plugin__s2member_registrations"))
796
  if ($_pmr["ws_plugin__s2member_custom_reg_field_last_name"])
797
  $lname = $_pmr["ws_plugin__s2member_custom_reg_field_last_name"];
798
  /**/
799
- if (!$fname) /* Default to Username? */
800
  if ($login) /* Username and empty Last Name. */
801
  eval ('$fname = trim ($login); $lname = "";');
802
  /**/
@@ -854,15 +854,15 @@ if (!class_exists ("c_ws_plugin__s2member_registrations"))
854
  if ($current_role !== $role) /* Only if NOT the current Role. */
855
  $user->set_role ($role); /* s2Member. */
856
  /**/
857
- if (!preg_match ("/^\+/", $ccaps))
858
  foreach ($user->allcaps as $cap => $cap_enabled)
859
  if (preg_match ("/^access_s2member_ccap_/", $cap))
860
  $user->remove_cap ($ccap = $cap);
861
  /**/
862
- if ($ccaps) /* Add Custom Capabilities. */
863
- foreach (preg_split ("/[\r\n\t\s;,]+/", ltrim ($ccaps, "+")) as $ccap)
864
- if (strlen ($ccap)) /* Don't add empty Custom Capabilities. */
865
- $user->add_cap ("access_s2member_ccap_" . trim (strtolower ($ccap)));
866
  /**/
867
  if ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["custom_reg_fields"])
868
  foreach (json_decode ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["custom_reg_fields"], true) as $field)
@@ -1009,10 +1009,10 @@ if (!class_exists ("c_ws_plugin__s2member_registrations"))
1009
  */
1010
  if (!headers_sent ()) /* Only if headers are NOT yet sent. */
1011
  {
1012
- @setcookie ("s2member_subscr_gateway", "", time () + 31556926, "/");
1013
- @setcookie ("s2member_subscr_id", "", time () + 31556926, "/");
1014
- @setcookie ("s2member_custom", "", time () + 31556926, "/");
1015
- @setcookie ("s2member_item_number", "", time () + 31556926, "/");
1016
  }
1017
  /**/
1018
  eval ('foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;');
495
  if ($_pmr["field_1"] && preg_match ("/^(.+?) (.+)$/", $_pmr["field_1"]))
496
  $lname = trim (preg_replace ("/^(.+?) (.+)$/", "$2", $_pmr["field_1"]));
497
  /**/
498
+ if ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["custom_reg_names"] && !$fname)
499
  if ($login) /* Username and empty Last Name. */
500
  eval ('$fname = trim ($login); $lname = "";');
501
  /**/
553
  if ($current_role !== $role) /* Only if NOT the current Role. */
554
  $user->set_role ($role); /* s2Member. */
555
  /**/
556
+ if ($ccaps && preg_match ("/^-all/", str_replace ("+", "", $ccaps)))
557
  foreach ($user->allcaps as $cap => $cap_enabled)
558
  if (preg_match ("/^access_s2member_ccap_/", $cap))
559
  $user->remove_cap ($ccap = $cap);
560
  /**/
561
+ if ($ccaps && preg_replace ("/^-all[\r\n\t\s;,]*/", "", str_replace ("+", "", $ccaps)))
562
+ foreach (preg_split ("/[\r\n\t\s;,]+/", preg_replace ("/^-all[\r\n\t\s;,]*/", "", str_replace ("+", "", $ccaps))) as $ccap)
563
+ if (strlen ($ccap = trim (strtolower (preg_replace ("/[^a-z_0-9]/i", "", $ccap)))))
564
+ $user->add_cap ("access_s2member_ccap_" . $ccap);
565
  /**/
566
  if ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["custom_reg_fields"])
567
  foreach (json_decode ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["custom_reg_fields"], true) as $field)
601
  delete_transient ($transient); /* This can be deleted now. */
602
  }
603
  /**/
604
+ if (!headers_sent ()) /* Only if headers are NOT yet sent. Here we establish both Signup and Payment Tracking Cookies. */
605
+ @setcookie ("s2member_tracking", ($s2member_tracking = c_ws_plugin__s2member_utils_encryption::encrypt ($subscr_id)), time () + 31556926, COOKIEPATH, COOKIE_DOMAIN) . @setcookie ("s2member_tracking", $s2member_tracking, time () + 31556926, SITECOOKIEPATH, COOKIE_DOMAIN) . ($_COOKIE["s2member_tracking"] = $s2member_tracking);
606
  /**/
607
  eval ('foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;');
608
  do_action ("ws_plugin__s2member_during_configure_user_registration_front_side_paid", get_defined_vars ());
662
  if ($_pmr["field_1"] && preg_match ("/^(.+?) (.+)$/", $_pmr["field_1"]))
663
  $lname = trim (preg_replace ("/^(.+?) (.+)$/", "$2", $_pmr["field_1"]));
664
  /**/
665
+ if ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["custom_reg_names"] && !$fname)
666
  if ($login) /* Username and empty Last Name. */
667
  eval ('$fname = trim ($login); $lname = "";');
668
  /**/
720
  if ($current_role !== $role) /* Only if NOT the current Role. */
721
  $user->set_role ($role); /* s2Member. */
722
  /**/
723
+ if ($ccaps && preg_match ("/^-all/", str_replace ("+", "", $ccaps)))
724
  foreach ($user->allcaps as $cap => $cap_enabled)
725
  if (preg_match ("/^access_s2member_ccap_/", $cap))
726
  $user->remove_cap ($ccap = $cap);
727
  /**/
728
+ if ($ccaps && preg_replace ("/^-all[\r\n\t\s;,]*/", "", str_replace ("+", "", $ccaps)))
729
+ foreach (preg_split ("/[\r\n\t\s;,]+/", preg_replace ("/^-all[\r\n\t\s;,]*/", "", str_replace ("+", "", $ccaps))) as $ccap)
730
+ if (strlen ($ccap = trim (strtolower (preg_replace ("/[^a-z_0-9]/i", "", $ccap)))))
731
+ $user->add_cap ("access_s2member_ccap_" . $ccap);
732
  /**/
733
  if ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["custom_reg_fields"])
734
  foreach (json_decode ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["custom_reg_fields"], true) as $field)
796
  if ($_pmr["ws_plugin__s2member_custom_reg_field_last_name"])
797
  $lname = $_pmr["ws_plugin__s2member_custom_reg_field_last_name"];
798
  /**/
799
+ if ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["custom_reg_names"] && !$fname)
800
  if ($login) /* Username and empty Last Name. */
801
  eval ('$fname = trim ($login); $lname = "";');
802
  /**/
854
  if ($current_role !== $role) /* Only if NOT the current Role. */
855
  $user->set_role ($role); /* s2Member. */
856
  /**/
857
+ if ($ccaps && preg_match ("/^-all/", str_replace ("+", "", $ccaps)))
858
  foreach ($user->allcaps as $cap => $cap_enabled)
859
  if (preg_match ("/^access_s2member_ccap_/", $cap))
860
  $user->remove_cap ($ccap = $cap);
861
  /**/
862
+ if ($ccaps && preg_replace ("/^-all[\r\n\t\s;,]*/", "", str_replace ("+", "", $ccaps)))
863
+ foreach (preg_split ("/[\r\n\t\s;,]+/", preg_replace ("/^-all[\r\n\t\s;,]*/", "", str_replace ("+", "", $ccaps))) as $ccap)
864
+ if (strlen ($ccap = trim (strtolower (preg_replace ("/[^a-z_0-9]/i", "", $ccap)))))
865
+ $user->add_cap ("access_s2member_ccap_" . $ccap);
866
  /**/
867
  if ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["custom_reg_fields"])
868
  foreach (json_decode ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["custom_reg_fields"], true) as $field)
1009
  */
1010
  if (!headers_sent ()) /* Only if headers are NOT yet sent. */
1011
  {
1012
+ @setcookie ("s2member_subscr_gateway", "", time () + 31556926, COOKIEPATH, COOKIE_DOMAIN) . @setcookie ("s2member_subscr_gateway", "", time () + 31556926, SITECOOKIEPATH, COOKIE_DOMAIN);
1013
+ @setcookie ("s2member_subscr_id", "", time () + 31556926, COOKIEPATH, COOKIE_DOMAIN) . @setcookie ("s2member_subscr_id", "", time () + 31556926, SITECOOKIEPATH, COOKIE_DOMAIN);
1014
+ @setcookie ("s2member_custom", "", time () + 31556926, COOKIEPATH, COOKIE_DOMAIN) . @setcookie ("s2member_custom", "", time () + 31556926, SITECOOKIEPATH, COOKIE_DOMAIN);
1015
+ @setcookie ("s2member_item_number", "", time () + 31556926, COOKIEPATH, COOKIE_DOMAIN) . @setcookie ("s2member_item_number", "", time () + 31556926, SITECOOKIEPATH, COOKIE_DOMAIN);
1016
  }
1017
  /**/
1018
  eval ('foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;');
includes/classes/sc-paypal-button-in.inc.php CHANGED
@@ -15,7 +15,7 @@
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_sc_paypal_button_in"))
21
  {
@@ -42,7 +42,7 @@ if (!class_exists ("c_ws_plugin__s2member_sc_paypal_button_in"))
42
  */
43
  public static function sc_paypal_button ($attr = FALSE, $content = FALSE, $shortcode = FALSE)
44
  {
45
- eval ('foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;');
46
  do_action ("ws_plugin__s2member_before_sc_paypal_button", get_defined_vars ());
47
  unset ($__refs, $__v); /* Unset defined __refs, __v. */
48
  /**/
@@ -61,13 +61,14 @@ if (!class_exists ("c_ws_plugin__s2member_sc_paypal_button_in"))
61
  $attr["rr"] = strtoupper ($attr["rr"]); /* Must be provided in upper-case format. Numerical, or BN value. Only after running shortcode_atts(). */
62
  $attr["ccaps"] = strtolower ($attr["ccaps"]); /* Custom Capabilities must be typed in lower-case format. Only after running shortcode_atts(). */
63
  $attr["rr"] = ($attr["rt"] === "L") ? "BN" : $attr["rr"]; /* Lifetime Subscriptions require Buy Now. Only after running shortcode_atts(). */
 
64
  $attr["ns"] = ($attr["dg"] === "1") ? "1" : $attr["ns"]; /* No shipping directive must be 1 for digital items. After shortcode_atts(). */
65
  /**/
66
- eval ('foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;');
67
  do_action ("ws_plugin__s2member_before_sc_paypal_button_after_shortcode_atts", get_defined_vars ());
68
  unset ($__refs, $__v); /* Unset defined __refs, __v. */
69
  /**/
70
- if ($attr["cancel"]) /* This is a special routine for Cancellation Buttons. Cancellation Buttons use a different template. */
71
  {
72
  $default_image = "https://www.paypal.com/en_US/i/btn/btn_unsubscribe_LG.gif"; /* Default Image. */
73
  /**/
@@ -83,12 +84,12 @@ if (!class_exists ("c_ws_plugin__s2member_sc_paypal_button_in"))
83
  $code = ($attr["output"] === "anchor") ? $code : $code; /* Cancellation Buttons are already in anchor format; Button format is not used in Cancellations. */
84
  $code = ($attr["output"] === "url") ? "https://" . (($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["paypal_sandbox"]) ? "www.sandbox.paypal.com" : "www.paypal.com") . "/cgi-bin/webscr?cmd=_subscr-find&alias=" . urlencode ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["paypal_business"]) : $code;
85
  /**/
86
- eval ('foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;');
87
  do_action ("ws_plugin__s2member_during_sc_paypal_cancellation_button", get_defined_vars ());
88
  unset ($__refs, $__v); /* Unset defined __refs, __v. */
89
  }
90
  /**/
91
- else if ($attr["sp"]) /* This is a special routine for Specific Post/Page Buttons. Specific Post/Page Buttons use a different template. */
92
  {
93
  $default_image = "https://www.paypal.com/en_US/i/btn/btn_xpressCheckout.gif"; /* Default Image. */
94
  /**/
@@ -138,11 +139,66 @@ if (!class_exists ("c_ws_plugin__s2member_sc_paypal_button_in"))
138
  $code = ($attr["output"] === "anchor") ? '<a href="' . esc_attr (c_ws_plugin__s2member_utils_forms::form_whips_2_url ($code)) . '"><img src="' . esc_attr (($attr["image"] && $attr["image"] !== "default") ? $attr["image"] : $default_image) . '" style="width:auto; height:auto; border:0;" alt="PayPal®" /></a>' : $code;
139
  $code = ($attr["output"] === "url") ? c_ws_plugin__s2member_utils_forms::form_whips_2_url ($code) : $code;
140
  /**/
141
- eval ('foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;');
142
  do_action ("ws_plugin__s2member_during_sc_paypal_sp_button", get_defined_vars ());
143
  unset ($__refs, $__v); /* Unset defined __refs, __v. */
144
  }
145
- else /* Otherwise, we'll process this Button normally, using the Membership routines. Also handles Modification Buttons. */
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
146
  {
147
  $default_image = "https://www.paypal.com/en_US/i/btn/btn_xpressCheckout.gif"; /* Default PayPal® Image. */
148
  /**/
@@ -220,7 +276,7 @@ if (!class_exists ("c_ws_plugin__s2member_sc_paypal_button_in"))
220
  $code = ($attr["output"] === "anchor") ? '<a href="' . esc_attr (c_ws_plugin__s2member_utils_forms::form_whips_2_url ($code)) . '"><img src="' . esc_attr (($attr["image"] && $attr["image"] !== "default") ? $attr["image"] : $default_image) . '" style="width:auto; height:auto; border:0;" alt="PayPal®" /></a>' : $code;
221
  $code = ($attr["output"] === "url") ? c_ws_plugin__s2member_utils_forms::form_whips_2_url ($code) : $code;
222
  /**/
223
- eval ('foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;');
224
  ($attr["modify"]) ? do_action ("ws_plugin__s2member_during_sc_paypal_modification_button", get_defined_vars ())/**/
225
  : do_action ("ws_plugin__s2member_during_sc_paypal_button", get_defined_vars ()); /* Else, we process normally. */
226
  unset ($__refs, $__v); /* Unset defined __refs, __v. */
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_sc_paypal_button_in"))
21
  {
42
  */
43
  public static function sc_paypal_button ($attr = FALSE, $content = FALSE, $shortcode = FALSE)
44
  {
45
+ eval('foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;');
46
  do_action ("ws_plugin__s2member_before_sc_paypal_button", get_defined_vars ());
47
  unset ($__refs, $__v); /* Unset defined __refs, __v. */
48
  /**/
61
  $attr["rr"] = strtoupper ($attr["rr"]); /* Must be provided in upper-case format. Numerical, or BN value. Only after running shortcode_atts(). */
62
  $attr["ccaps"] = strtolower ($attr["ccaps"]); /* Custom Capabilities must be typed in lower-case format. Only after running shortcode_atts(). */
63
  $attr["rr"] = ($attr["rt"] === "L") ? "BN" : $attr["rr"]; /* Lifetime Subscriptions require Buy Now. Only after running shortcode_atts(). */
64
+ $attr["rr"] = ($attr["level"] === "*") ? "BN" : $attr["rr"]; /* Independent Ccaps require Buy Now. Only after running shortcode_atts(). */
65
  $attr["ns"] = ($attr["dg"] === "1") ? "1" : $attr["ns"]; /* No shipping directive must be 1 for digital items. After shortcode_atts(). */
66
  /**/
67
+ eval('foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;');
68
  do_action ("ws_plugin__s2member_before_sc_paypal_button_after_shortcode_atts", get_defined_vars ());
69
  unset ($__refs, $__v); /* Unset defined __refs, __v. */
70
  /**/
71
+ if ($attr["cancel"]) /* This is a special routine for Cancellation Buttons. */
72
  {
73
  $default_image = "https://www.paypal.com/en_US/i/btn/btn_unsubscribe_LG.gif"; /* Default Image. */
74
  /**/
84
  $code = ($attr["output"] === "anchor") ? $code : $code; /* Cancellation Buttons are already in anchor format; Button format is not used in Cancellations. */
85
  $code = ($attr["output"] === "url") ? "https://" . (($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["paypal_sandbox"]) ? "www.sandbox.paypal.com" : "www.paypal.com") . "/cgi-bin/webscr?cmd=_subscr-find&alias=" . urlencode ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["paypal_business"]) : $code;
86
  /**/
87
+ eval('foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;');
88
  do_action ("ws_plugin__s2member_during_sc_paypal_cancellation_button", get_defined_vars ());
89
  unset ($__refs, $__v); /* Unset defined __refs, __v. */
90
  }
91
  /**/
92
+ else if ($attr["sp"]) /* This is a special routine for Specific Post/Page Buttons. */
93
  {
94
  $default_image = "https://www.paypal.com/en_US/i/btn/btn_xpressCheckout.gif"; /* Default Image. */
95
  /**/
139
  $code = ($attr["output"] === "anchor") ? '<a href="' . esc_attr (c_ws_plugin__s2member_utils_forms::form_whips_2_url ($code)) . '"><img src="' . esc_attr (($attr["image"] && $attr["image"] !== "default") ? $attr["image"] : $default_image) . '" style="width:auto; height:auto; border:0;" alt="PayPal®" /></a>' : $code;
140
  $code = ($attr["output"] === "url") ? c_ws_plugin__s2member_utils_forms::form_whips_2_url ($code) : $code;
141
  /**/
142
+ eval('foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;');
143
  do_action ("ws_plugin__s2member_during_sc_paypal_sp_button", get_defined_vars ());
144
  unset ($__refs, $__v); /* Unset defined __refs, __v. */
145
  }
146
+ else if ($attr["level"] === "*") /* This is a special routine for Independent Custom Capabilities. */
147
+ {
148
+ $default_image = "https://www.paypal.com/en_US/i/btn/btn_xpressCheckout.gif"; /* Default Image. */
149
+ /**/
150
+ $paypal_on0_input_value = ($referencing = c_ws_plugin__s2member_utils_users::get_user_subscr_or_wp_id ()) ? "Referencing Customer ID" : "Originating Domain";
151
+ $paypal_os0_input_value = ($referencing) ? $referencing : $_SERVER["HTTP_HOST"]; /* Current User's Paid Subscr. ID, or WP® User ID, or domain. */
152
+ /**/
153
+ $paypal_on1_input_value = "Customer IP Address"; /* Identifies the Customer's IP Address for tracking purposes. */
154
+ $paypal_os1_input_value = $_SERVER["REMOTE_ADDR"]; /* Current User's IP Address for tracking purposes. */
155
+ /**/
156
+ $paypal_invoice_input_value = uniqid () . "~" . $_SERVER["REMOTE_ADDR"]; /* s2Member's Unique Code~IP combo. */
157
+ /**/
158
+ $attr["level_ccaps_eotper"] = ($attr["rr"] === "BN" && $attr["rt"] !== "L") ? $attr["level"] . ":" . $attr["ccaps"] . ":" . $attr["rp"] . " " . $attr["rt"] : $attr["level"] . ":" . $attr["ccaps"];
159
+ $attr["level_ccaps_eotper"] = rtrim ($attr["level_ccaps_eotper"], ":"); /* Clean any trailing separators from this string. */
160
+ /**/
161
+ $success_return_url = site_url ("/?s2member_paypal_return=1"); /* s2Member handles this all by itself. However, it can be Filtered. */
162
+ $success_return_url = apply_filters ("ws_plugin__s2member_during_sc_paypal_button_success_return_url", $success_return_url, get_defined_vars ());
163
+ /**/
164
+ $code = trim (file_get_contents (dirname (dirname (__FILE__)) . "/templates/buttons/paypal-ccaps-checkout-button.html"));
165
+ $code = preg_replace ("/%%images%%/", c_ws_plugin__s2member_utils_strings::esc_ds (esc_attr ($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["dir_url"] . "/images")), $code);
166
+ $code = preg_replace ("/%%wpurl%%/", c_ws_plugin__s2member_utils_strings::esc_ds (esc_attr (site_url ())), $code);
167
+ /**/
168
+ $code = preg_replace ("/%%endpoint%%/", c_ws_plugin__s2member_utils_strings::esc_ds (esc_attr (($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["paypal_sandbox"]) ? "www.sandbox.paypal.com" : "www.paypal.com")), $code);
169
+ $code = preg_replace ("/%%paypal_business%%/", c_ws_plugin__s2member_utils_strings::esc_ds (esc_attr ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["paypal_business"])), $code);
170
+ $code = preg_replace ("/%%cancel_return%%/", c_ws_plugin__s2member_utils_strings::esc_ds (esc_attr (home_url ("/"))), $code);
171
+ $code = preg_replace ("/%%notify_url%%/", c_ws_plugin__s2member_utils_strings::esc_ds (esc_attr (site_url ("/?s2member_paypal_notify=1"))), $code);
172
+ $code = preg_replace ("/%%return%%/", c_ws_plugin__s2member_utils_strings::esc_ds (esc_attr ($success_return_url)), $code);
173
+ $code = preg_replace ("/%%custom%%/", c_ws_plugin__s2member_utils_strings::esc_ds (esc_attr ($attr["custom"])), $code);
174
+ /**/
175
+ $code = preg_replace ('/ name\="lc" value\="(.*?)"/', ' name="lc" value="' . c_ws_plugin__s2member_utils_strings::esc_ds (esc_attr ($attr["lc"])) . '"', $code);
176
+ $code = preg_replace ('/ name\="no_shipping" value\="(.*?)"/', ' name="no_shipping" value="' . c_ws_plugin__s2member_utils_strings::esc_ds (esc_attr ($attr["ns"])) . '"', $code);
177
+ $code = preg_replace ('/ name\="item_name" value\="(.*?)"/', ' name="item_name" value="' . c_ws_plugin__s2member_utils_strings::esc_ds (esc_attr ($attr["desc"])) . '"', $code);
178
+ $code = preg_replace ('/ name\="item_number" value\="(.*?)"/', ' name="item_number" value="' . c_ws_plugin__s2member_utils_strings::esc_ds (esc_attr ($attr["level_ccaps_eotper"])) . '"', $code);
179
+ $code = preg_replace ('/ name\="page_style" value\="(.*?)"/', ' name="page_style" value="' . c_ws_plugin__s2member_utils_strings::esc_ds (esc_attr ($attr["ps"])) . '"', $code);
180
+ $code = preg_replace ('/ name\="currency_code" value\="(.*?)"/', ' name="currency_code" value="' . c_ws_plugin__s2member_utils_strings::esc_ds (esc_attr ($attr["cc"])) . '"', $code);
181
+ $code = preg_replace ('/ name\="custom" value\="(.*?)"/', ' name="custom" value="' . c_ws_plugin__s2member_utils_strings::esc_ds (esc_attr ($attr["custom"])) . '"', $code);
182
+ /**/
183
+ $code = preg_replace ('/ name\="invoice" value\="(.*?)"/', ' name="invoice" value="' . c_ws_plugin__s2member_utils_strings::esc_ds (esc_attr ($paypal_invoice_input_value)) . '"', $code);
184
+ /**/
185
+ $code = preg_replace ('/ name\="on0" value\="(.*?)"/', ' name="on0" value="' . c_ws_plugin__s2member_utils_strings::esc_ds (esc_attr ($paypal_on0_input_value)) . '"', $code);
186
+ $code = preg_replace ('/ name\="os0" value\="(.*?)"/', ' name="os0" value="' . c_ws_plugin__s2member_utils_strings::esc_ds (esc_attr ($paypal_os0_input_value)) . '"', $code);
187
+ $code = preg_replace ('/ name\="on1" value\="(.*?)"/', ' name="on1" value="' . c_ws_plugin__s2member_utils_strings::esc_ds (esc_attr ($paypal_on1_input_value)) . '"', $code);
188
+ $code = preg_replace ('/ name\="os1" value\="(.*?)"/', ' name="os1" value="' . c_ws_plugin__s2member_utils_strings::esc_ds (esc_attr ($paypal_os1_input_value)) . '"', $code);
189
+ /**/
190
+ $code = preg_replace ('/ name\="amount" value\="(.*?)"/', ' name="amount" value="' . c_ws_plugin__s2member_utils_strings::esc_ds (esc_attr ($attr["ra"])) . '"', $code);
191
+ /**/
192
+ $code = $_code = ($attr["image"] && $attr["image"] !== "default") ? preg_replace ('/ src\="(.*?)"/', ' src="' . c_ws_plugin__s2member_utils_strings::esc_ds (esc_attr ($attr["image"])) . '"', $code) : preg_replace ('/ src\="(.*?)"/', ' src="' . c_ws_plugin__s2member_utils_strings::esc_ds (esc_attr ($default_image)) . '"', $code);
193
+ /**/
194
+ $code = ($attr["output"] === "anchor") ? '<a href="' . esc_attr (c_ws_plugin__s2member_utils_forms::form_whips_2_url ($code)) . '"><img src="' . esc_attr (($attr["image"] && $attr["image"] !== "default") ? $attr["image"] : $default_image) . '" style="width:auto; height:auto; border:0;" alt="PayPal®" /></a>' : $code;
195
+ $code = ($attr["output"] === "url") ? c_ws_plugin__s2member_utils_forms::form_whips_2_url ($code) : $code;
196
+ /**/
197
+ eval('foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;');
198
+ do_action ("ws_plugin__s2member_during_sc_paypal_ccaps_button", get_defined_vars ());
199
+ unset ($__refs, $__v); /* Unset defined __refs, __v. */
200
+ }
201
+ else /* Otherwise, we'll process this Button normally, using the Membership routines. */
202
  {
203
  $default_image = "https://www.paypal.com/en_US/i/btn/btn_xpressCheckout.gif"; /* Default PayPal® Image. */
204
  /**/
276
  $code = ($attr["output"] === "anchor") ? '<a href="' . esc_attr (c_ws_plugin__s2member_utils_forms::form_whips_2_url ($code)) . '"><img src="' . esc_attr (($attr["image"] && $attr["image"] !== "default") ? $attr["image"] : $default_image) . '" style="width:auto; height:auto; border:0;" alt="PayPal®" /></a>' : $code;
277
  $code = ($attr["output"] === "url") ? c_ws_plugin__s2member_utils_forms::form_whips_2_url ($code) : $code;
278
  /**/
279
+ eval('foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;');
280
  ($attr["modify"]) ? do_action ("ws_plugin__s2member_during_sc_paypal_modification_button", get_defined_vars ())/**/
281
  : do_action ("ws_plugin__s2member_during_sc_paypal_button", get_defined_vars ()); /* Else, we process normally. */
282
  unset ($__refs, $__v); /* Unset defined __refs, __v. */
includes/classes/sc-profile-in.inc.php CHANGED
@@ -134,7 +134,7 @@ if (!class_exists ("c_ws_plugin__s2member_sc_profile_in"))
134
  echo '<td>' . "\n";
135
  echo '<label for="ws-plugin--s2member-profile-first-name">' . "\n";
136
  echo '<strong>First Name *</strong><br />' . "\n";
137
- echo '<input aria-required="true" type="text" maxlength="100" name="ws_plugin__s2member_profile_first_name" id="ws-plugin--s2member-profile-first-name" class="ws-plugin--s2member-profile-field" value="' . format_to_edit ($user->first_name) . '" tabindex="' . esc_attr (($tabindex = $tabindex + 10)) . '" />' . "\n";
138
  echo '</label>' . "\n";
139
  echo '</td>' . "\n";
140
  echo '</tr>' . "\n";
@@ -154,7 +154,7 @@ if (!class_exists ("c_ws_plugin__s2member_sc_profile_in"))
154
  echo '<td>' . "\n";
155
  echo '<label for="ws-plugin--s2member-profile-last-name">' . "\n";
156
  echo '<strong>Last Name *</strong><br />' . "\n";
157
- echo '<input aria-required="true" type="text" maxlength="100" name="ws_plugin__s2member_profile_last_name" id="ws-plugin--s2member-profile-last-name" class="ws-plugin--s2member-profile-field" value="' . format_to_edit ($user->last_name) . '" tabindex="' . esc_attr (($tabindex = $tabindex + 10)) . '" />' . "\n";
158
  echo '</label>' . "\n";
159
  echo '</td>' . "\n";
160
  echo '</tr>' . "\n";
@@ -174,7 +174,7 @@ if (!class_exists ("c_ws_plugin__s2member_sc_profile_in"))
174
  echo '<td>' . "\n";
175
  echo '<label for="ws-plugin--s2member-profile-display-name">' . "\n";
176
  echo '<strong>Display Name *</strong><br />' . "\n";
177
- echo '<input aria-required="true" type="text" maxlength="100" name="ws_plugin__s2member_profile_display_name" id="ws-plugin--s2member-profile-display-name" class="ws-plugin--s2member-profile-field" value="' . format_to_edit ($user->display_name) . '" tabindex="' . esc_attr (($tabindex = $tabindex + 10)) . '" />' . "\n";
178
  echo '</label>' . "\n";
179
  echo '</td>' . "\n";
180
  echo '</tr>' . "\n";
134
  echo '<td>' . "\n";
135
  echo '<label for="ws-plugin--s2member-profile-first-name">' . "\n";
136
  echo '<strong>First Name *</strong><br />' . "\n";
137
+ echo '<input aria-required="true" type="text" maxlength="100" name="ws_plugin__s2member_profile_first_name" id="ws-plugin--s2member-profile-first-name" class="ws-plugin--s2member-profile-field" value="' . esc_attr ($user->first_name) . '" tabindex="' . esc_attr (($tabindex = $tabindex + 10)) . '" />' . "\n";
138
  echo '</label>' . "\n";
139
  echo '</td>' . "\n";
140
  echo '</tr>' . "\n";
154
  echo '<td>' . "\n";
155
  echo '<label for="ws-plugin--s2member-profile-last-name">' . "\n";
156
  echo '<strong>Last Name *</strong><br />' . "\n";
157
+ echo '<input aria-required="true" type="text" maxlength="100" name="ws_plugin__s2member_profile_last_name" id="ws-plugin--s2member-profile-last-name" class="ws-plugin--s2member-profile-field" value="' . esc_attr ($user->last_name) . '" tabindex="' . esc_attr (($tabindex = $tabindex + 10)) . '" />' . "\n";
158
  echo '</label>' . "\n";
159
  echo '</td>' . "\n";
160
  echo '</tr>' . "\n";
174
  echo '<td>' . "\n";
175
  echo '<label for="ws-plugin--s2member-profile-display-name">' . "\n";
176
  echo '<strong>Display Name *</strong><br />' . "\n";
177
+ echo '<input aria-required="true" type="text" maxlength="100" name="ws_plugin__s2member_profile_display_name" id="ws-plugin--s2member-profile-display-name" class="ws-plugin--s2member-profile-field" value="' . esc_attr ($user->display_name) . '" tabindex="' . esc_attr (($tabindex = $tabindex + 10)) . '" />' . "\n";
178
  echo '</label>' . "\n";
179
  echo '</td>' . "\n";
180
  echo '</tr>' . "\n";
includes/classes/sp-access.inc.php CHANGED
@@ -15,7 +15,7 @@
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_sp_access"))
21
  {
@@ -40,7 +40,7 @@ if (!class_exists ("c_ws_plugin__s2member_sp_access"))
40
  */
41
  public static function sp_access_link_gen ($sp_ids = FALSE, $hours = 72, $shrink = TRUE)
42
  {
43
- eval('foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;');
44
  do_action ("ws_plugin__s2member_before_sp_access_link_gen", get_defined_vars ());
45
  unset ($__refs, $__v); /* Unset defined __refs, __v. */
46
  /**/
@@ -152,7 +152,7 @@ if (!class_exists ("c_ws_plugin__s2member_sp_access"))
152
  */
153
  public static function sp_access_session ($add_sp_access_value = FALSE)
154
  {
155
- eval('foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;');
156
  do_action ("ws_plugin__s2member_before_sp_access_session", get_defined_vars ());
157
  unset ($__refs, $__v); /* Unset defined __refs, __v. */
158
  /**/
@@ -166,9 +166,9 @@ if (!class_exists ("c_ws_plugin__s2member_sp_access"))
166
  $cookie = implode (":.:|:.:", $sp_access_values); /* Implode the access values into a delimited string. */
167
  $cookie = (strlen ($cookie) >= 4096) ? $add_sp_access_value : $cookie; /* Max cookie size is 4kbs. */
168
  /**/
169
- setcookie ("s2member_sp_access", $cookie, time () + 31556926, "/") . ($_COOKIE["s2member_sp_access"] = $cookie);
170
  /**/
171
- eval('foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;');
172
  do_action ("ws_plugin__s2member_during_sp_access_session", get_defined_vars ());
173
  unset ($__refs, $__v); /* Unset defined __refs, __v. */
174
  }
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_sp_access"))
21
  {
40
  */
41
  public static function sp_access_link_gen ($sp_ids = FALSE, $hours = 72, $shrink = TRUE)
42
  {
43
+ eval ('foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;');
44
  do_action ("ws_plugin__s2member_before_sp_access_link_gen", get_defined_vars ());
45
  unset ($__refs, $__v); /* Unset defined __refs, __v. */
46
  /**/
152
  */
153
  public static function sp_access_session ($add_sp_access_value = FALSE)
154
  {
155
+ eval ('foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;');
156
  do_action ("ws_plugin__s2member_before_sp_access_session", get_defined_vars ());
157
  unset ($__refs, $__v); /* Unset defined __refs, __v. */
158
  /**/
166
  $cookie = implode (":.:|:.:", $sp_access_values); /* Implode the access values into a delimited string. */
167
  $cookie = (strlen ($cookie) >= 4096) ? $add_sp_access_value : $cookie; /* Max cookie size is 4kbs. */
168
  /**/
169
+ setcookie ("s2member_sp_access", $cookie, time () + 31556926, COOKIEPATH, COOKIE_DOMAIN) . setcookie ("s2member_sp_access", $cookie, time () + 31556926, SITECOOKIEPATH, COOKIE_DOMAIN) . ($_COOKIE["s2member_sp_access"] = $cookie);
170
  /**/
171
+ eval ('foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;');
172
  do_action ("ws_plugin__s2member_during_sp_access_session", get_defined_vars ());
173
  unset ($__refs, $__v); /* Unset defined __refs, __v. */
174
  }
includes/classes/tracking-codes.inc.php CHANGED
@@ -15,7 +15,7 @@
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_tracking_codes"))
21
  {
@@ -33,9 +33,10 @@ if (!class_exists ("c_ws_plugin__s2member_tracking_codes"))
33
  * These are stored inside s2Member's Transient Queue by the IPN processor.
34
  *
35
  * Tracking Codes are only displayed/processed one time.
36
- * s2Member will display Tracking Codes in (1) of these 3 locations:
37
  *
38
- * o If possible, on the Registration Form, after returning from your Payment Gateway.
 
39
  * o Otherwise, if possible, on the Login Form *( in the footer )* after Registration is completed.
40
  * o Otherwise, in the footer of your WordPress® theme, as soon as possible; or after the Customer's very first login.
41
  *
@@ -52,15 +53,15 @@ if (!class_exists ("c_ws_plugin__s2member_tracking_codes"))
52
  {
53
  do_action ("ws_plugin__s2member_before_display_signup_tracking_codes", get_defined_vars ());
54
  /**/
55
- if ((($reg_cookies = c_ws_plugin__s2member_register_access::reg_cookies_ok ()) && extract ($reg_cookies)) || (!empty ($_COOKIE["s2member_signup_tracking"]) && ($subscr_id = c_ws_plugin__s2member_utils_encryption::decrypt ($_COOKIE["s2member_signup_tracking"]))))
56
  {
57
- if (($code = get_transient ($transient = "s2m_" . md5 ("s2member_transient_signup_tracking_codes_" . $subscr_id))))
58
  {
59
- delete_transient ($transient); /* Only display this ONE time. Delete transient immediately. */
60
  /**/
61
- echo '<img src="' . esc_attr (site_url ("/?s2member_delete_signup_tracking_cookie=1")) . '" alt="." style="width:1px; height:1px; border:0;" />' . "\n";
62
  /**/
63
- eval ('foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;');
64
  do_action ("ws_plugin__s2member_during_display_signup_tracking_codes", get_defined_vars ());
65
  unset ($__refs, $__v); /* Unset defined __refs, __v. */
66
  /**/
@@ -80,6 +81,110 @@ if (!class_exists ("c_ws_plugin__s2member_tracking_codes"))
80
  return; /* Return for uniformity. */
81
  }
82
  /**
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
83
  * Displays Specific Post/Page Tracking Codes.
84
  *
85
  * These are stored inside s2Member's Transient Queue, by BOTH the IPN & Return-Data processors.
@@ -104,11 +209,11 @@ if (!class_exists ("c_ws_plugin__s2member_tracking_codes"))
104
  {
105
  if (($code = get_transient ($transient = "s2m_" . md5 ("s2member_transient_sp_tracking_codes_" . $txn_id))))
106
  {
107
- delete_transient ($transient); /* Only display this ONE time. Delete transient immediately. */
108
  /**/
109
  echo '<img src="' . esc_attr (site_url ("/?s2member_delete_sp_tracking_cookie=1")) . '" alt="." style="width:1px; height:1px; border:0;" />' . "\n";
110
  /**/
111
- eval ('foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;');
112
  do_action ("ws_plugin__s2member_during_display_sp_tracking_codes", get_defined_vars ());
113
  unset ($__refs, $__v); /* Unset defined __refs, __v. */
114
  /**/
@@ -118,7 +223,7 @@ if (!class_exists ("c_ws_plugin__s2member_tracking_codes"))
118
  }
119
  else /* Otherwise, it's safe to allow PHP code. */
120
  {
121
- eval ("?>" . $code);
122
  }
123
  }
124
  }
@@ -142,6 +247,8 @@ if (!class_exists ("c_ws_plugin__s2member_tracking_codes"))
142
  ob_start (); /* Begin output buffering so we can "return". */
143
  /**/
144
  c_ws_plugin__s2member_tracking_codes::display_signup_tracking_codes ();
 
 
145
  c_ws_plugin__s2member_tracking_codes::display_sp_tracking_codes ();
146
  /**/
147
  return apply_filters ("ws_plugin__s2member_generate_all_tracking_codes", ob_get_clean (), get_defined_vars ());
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_tracking_codes"))
21
  {
33
  * These are stored inside s2Member's Transient Queue by the IPN processor.
34
  *
35
  * Tracking Codes are only displayed/processed one time.
36
+ * s2Member will display Tracking Codes in (1) of these 4 locations:
37
  *
38
+ * o On the Return URL / Thank-You Page, after returning from your Payment Gateway.
39
+ * o Otherwise, on the Registration Form, after returning from your Payment Gateway.
40
  * o Otherwise, if possible, on the Login Form *( in the footer )* after Registration is completed.
41
  * o Otherwise, in the footer of your WordPress® theme, as soon as possible; or after the Customer's very first login.
42
  *
53
  {
54
  do_action ("ws_plugin__s2member_before_display_signup_tracking_codes", get_defined_vars ());
55
  /**/
56
+ if ((!empty ($_COOKIE["s2member_tracking"]) && ($subscr_or_txn_id = c_ws_plugin__s2member_utils_encryption::decrypt ($_COOKIE["s2member_tracking"]))) || (($reg_cookies = c_ws_plugin__s2member_register_access::reg_cookies_ok ()) && extract ($reg_cookies) && ($subscr_or_txn_id = $subscr_id)))
57
  {
58
+ if (($code = get_transient ($transient = "s2m_" . md5 ("s2member_transient_signup_tracking_codes_" . $subscr_or_txn_id))))
59
  {
60
+ delete_transient($transient); /* Only display this ONE time. Delete transient immediately. */
61
  /**/
62
+ echo '<img src="' . esc_attr (site_url ("/?s2member_delete_tracking_cookie=1")) . '" alt="." style="width:1px; height:1px; border:0;" />' . "\n";
63
  /**/
64
+ eval('foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;');
65
  do_action ("ws_plugin__s2member_during_display_signup_tracking_codes", get_defined_vars ());
66
  unset ($__refs, $__v); /* Unset defined __refs, __v. */
67
  /**/
81
  return; /* Return for uniformity. */
82
  }
83
  /**
84
+ * Displays Modification Tracking Codes.
85
+ *
86
+ * These are stored inside s2Member's Transient Queue by the IPN processor.
87
+ *
88
+ * Tracking Codes are only displayed/processed one time.
89
+ * s2Member will display Tracking Codes in (1) of these 3 locations:
90
+ *
91
+ * o On the Return URL / Thank-You Page, after returning from your Payment Gateway.
92
+ * o Otherwise, if possible, on the Login Form *( in the footer )* after returning from your Payment Gateway.
93
+ * o Otherwise, in the footer of your WordPress® theme, as soon as possible; or after the Customer's next login.
94
+ *
95
+ * @package s2Member\Tracking
96
+ * @since 110815
97
+ *
98
+ * @attaches-to: ``add_action("login_footer");``
99
+ * @attaches-to: ``add_action("wp_footer");``
100
+ * @also-called-by: {@link s2Member\Tracking\c_ws_plugin__s2member_tracking_codes::generate_all_tracking_codes()}
101
+ *
102
+ * @return null After displaying possible Tracking Code(s).
103
+ */
104
+ public static function display_modification_tracking_codes ()
105
+ {
106
+ do_action ("ws_plugin__s2member_before_display_modification_tracking_codes", get_defined_vars ());
107
+ /**/
108
+ if ((!empty ($_COOKIE["s2member_tracking"]) && ($subscr_or_txn_id = c_ws_plugin__s2member_utils_encryption::decrypt ($_COOKIE["s2member_tracking"]))) || (($reg_cookies = c_ws_plugin__s2member_register_access::reg_cookies_ok ()) && extract ($reg_cookies) && ($subscr_or_txn_id = $subscr_id)))
109
+ {
110
+ if (($code = get_transient ($transient = "s2m_" . md5 ("s2member_transient_modification_tracking_codes_" . $subscr_or_txn_id))))
111
+ {
112
+ delete_transient($transient); /* Only display this ONE time. Delete transient immediately. */
113
+ /**/
114
+ echo '<img src="' . esc_attr (site_url ("/?s2member_delete_tracking_cookie=1")) . '" alt="." style="width:1px; height:1px; border:0;" />' . "\n";
115
+ /**/
116
+ eval('foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;');
117
+ do_action ("ws_plugin__s2member_during_display_modification_tracking_codes", get_defined_vars ());
118
+ unset ($__refs, $__v); /* Unset defined __refs, __v. */
119
+ /**/
120
+ if (is_multisite () && c_ws_plugin__s2member_utils_conds::is_multisite_farm () && !is_main_site ())
121
+ {
122
+ echo do_shortcode ($code) . "\n"; /* No PHP here. */
123
+ }
124
+ else /* Otherwise, safe to allow PHP code. */
125
+ {
126
+ echo do_shortcode (c_ws_plugin__s2member_utilities::evl ($code));
127
+ }
128
+ }
129
+ }
130
+ /**/
131
+ do_action ("ws_plugin__s2member_after_display_modification_tracking_codes", get_defined_vars ());
132
+ /**/
133
+ return; /* Return for uniformity. */
134
+ }
135
+ /**
136
+ * Displays Capability Tracking Codes.
137
+ *
138
+ * These are stored inside s2Member's Transient Queue by the IPN processor.
139
+ *
140
+ * Tracking Codes are only displayed/processed one time.
141
+ * s2Member will display Tracking Codes in (1) of these 3 locations:
142
+ *
143
+ * o On the Return URL / Thank-You Page, after returning from your Payment Gateway.
144
+ * o Otherwise, if possible, on the Login Form *( in the footer )* after returning from your Payment Gateway.
145
+ * o Otherwise, in the footer of your WordPress® theme, as soon as possible; or after the Customer's next login.
146
+ *
147
+ * @package s2Member\Tracking
148
+ * @since 110815
149
+ *
150
+ * @attaches-to: ``add_action("login_footer");``
151
+ * @attaches-to: ``add_action("wp_footer");``
152
+ * @also-called-by: {@link s2Member\Tracking\c_ws_plugin__s2member_tracking_codes::generate_all_tracking_codes()}
153
+ *
154
+ * @return null After displaying possible Tracking Code(s).
155
+ */
156
+ public static function display_ccap_tracking_codes ()
157
+ {
158
+ do_action ("ws_plugin__s2member_before_display_ccap_tracking_codes", get_defined_vars ());
159
+ /**/
160
+ if ((!empty ($_COOKIE["s2member_tracking"]) && ($subscr_or_txn_id = c_ws_plugin__s2member_utils_encryption::decrypt ($_COOKIE["s2member_tracking"]))) || (($reg_cookies = c_ws_plugin__s2member_register_access::reg_cookies_ok ()) && extract ($reg_cookies) && ($subscr_or_txn_id = $subscr_id)))
161
+ {
162
+ if (($code = get_transient ($transient = "s2m_" . md5 ("s2member_transient_ccap_tracking_codes_" . $subscr_or_txn_id))))
163
+ {
164
+ delete_transient($transient); /* Only display this ONE time. Delete transient immediately. */
165
+ /**/
166
+ echo '<img src="' . esc_attr (site_url ("/?s2member_delete_tracking_cookie=1")) . '" alt="." style="width:1px; height:1px; border:0;" />' . "\n";
167
+ /**/
168
+ eval('foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;');
169
+ do_action ("ws_plugin__s2member_during_display_ccap_tracking_codes", get_defined_vars ());
170
+ unset ($__refs, $__v); /* Unset defined __refs, __v. */
171
+ /**/
172
+ if (is_multisite () && c_ws_plugin__s2member_utils_conds::is_multisite_farm () && !is_main_site ())
173
+ {
174
+ echo do_shortcode ($code) . "\n"; /* No PHP here. */
175
+ }
176
+ else /* Otherwise, safe to allow PHP code. */
177
+ {
178
+ echo do_shortcode (c_ws_plugin__s2member_utilities::evl ($code));
179
+ }
180
+ }
181
+ }
182
+ /**/
183
+ do_action ("ws_plugin__s2member_after_display_ccap_tracking_codes", get_defined_vars ());
184
+ /**/
185
+ return; /* Return for uniformity. */
186
+ }
187
+ /**
188
  * Displays Specific Post/Page Tracking Codes.
189
  *
190
  * These are stored inside s2Member's Transient Queue, by BOTH the IPN & Return-Data processors.
209
  {
210
  if (($code = get_transient ($transient = "s2m_" . md5 ("s2member_transient_sp_tracking_codes_" . $txn_id))))
211
  {
212
+ delete_transient($transient); /* Only display this ONE time. Delete transient immediately. */
213
  /**/
214
  echo '<img src="' . esc_attr (site_url ("/?s2member_delete_sp_tracking_cookie=1")) . '" alt="." style="width:1px; height:1px; border:0;" />' . "\n";
215
  /**/
216
+ eval('foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;');
217
  do_action ("ws_plugin__s2member_during_display_sp_tracking_codes", get_defined_vars ());
218
  unset ($__refs, $__v); /* Unset defined __refs, __v. */
219
  /**/
223
  }
224
  else /* Otherwise, it's safe to allow PHP code. */
225
  {
226
+ eval("?>" . $code);
227
  }
228
  }
229
  }
247
  ob_start (); /* Begin output buffering so we can "return". */
248
  /**/
249
  c_ws_plugin__s2member_tracking_codes::display_signup_tracking_codes ();
250
+ c_ws_plugin__s2member_tracking_codes::display_modification_tracking_codes ();
251
+ c_ws_plugin__s2member_tracking_codes::display_ccap_tracking_codes ();
252
  c_ws_plugin__s2member_tracking_codes::display_sp_tracking_codes ();
253
  /**/
254
  return apply_filters ("ws_plugin__s2member_generate_all_tracking_codes", ob_get_clean (), get_defined_vars ());
includes/classes/tracking-cookies-in.inc.php CHANGED
@@ -15,7 +15,7 @@
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_tracking_cookies_in"))
21
  {
@@ -31,26 +31,29 @@ if (!class_exists ("c_ws_plugin__s2member_tracking_cookies_in"))
31
  * Deletes s2Member's temporary tracking cookie.
32
  *
33
  * @package s2Member\Tracking
34
- * @since 3.5
35
  *
36
  * @attaches-to: ``add_action("init");``
37
  *
38
  * @return null Or exits script execution after deleting Cookie.
39
  */
40
- public static function delete_signup_tracking_cookie ()
41
  {
42
- do_action ("ws_plugin__s2member_before_delete_signup_tracking_cookie", get_defined_vars ());
43
  /**/
44
- if (!empty ($_GET["s2member_delete_signup_tracking_cookie"])) /* Deletes cookie. */
45
  {
46
- setcookie ("s2member_signup_tracking", "", time () + 31556926, "/");
 
 
 
47
  /**/
48
- do_action ("ws_plugin__s2member_during_delete_signup_tracking_cookie", get_defined_vars ());
49
  /**/
50
- exit (); /* Clean exit. */
51
  }
52
  /**/
53
- do_action ("ws_plugin__s2member_after_delete_signup_tracking_cookie", get_defined_vars ());
54
  }
55
  /**
56
  * Deletes s2Member's temporary tracking cookie.
@@ -68,11 +71,14 @@ if (!class_exists ("c_ws_plugin__s2member_tracking_cookies_in"))
68
  /**/
69
  if (!empty ($_GET["s2member_delete_sp_tracking_cookie"])) /* Deletes cookie. */
70
  {
71
- setcookie ("s2member_sp_tracking", "", time () + 31556926, "/");
 
72
  /**/
73
  do_action ("ws_plugin__s2member_during_delete_sp_tracking_cookie", get_defined_vars ());
74
  /**/
75
- exit (); /* Clean exit. */
 
 
76
  }
77
  /**/
78
  do_action ("ws_plugin__s2member_after_delete_sp_tracking_cookie", get_defined_vars ());
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_tracking_cookies_in"))
21
  {
31
  * Deletes s2Member's temporary tracking cookie.
32
  *
33
  * @package s2Member\Tracking
34
+ * @since 110815
35
  *
36
  * @attaches-to: ``add_action("init");``
37
  *
38
  * @return null Or exits script execution after deleting Cookie.
39
  */
40
+ public static function delete_tracking_cookie ()
41
  {
42
+ do_action ("ws_plugin__s2member_before_delete_tracking_cookie", get_defined_vars ());
43
  /**/
44
+ if (!empty ($_GET["s2member_delete_tracking_cookie"])) /* Deletes cookie. */
45
  {
46
+ setcookie ("s2member_tracking", "", time () + 31556926, COOKIEPATH, COOKIE_DOMAIN);
47
+ setcookie ("s2member_tracking", "", time () + 31556926, SITECOOKIEPATH, COOKIE_DOMAIN);
48
+ /**/
49
+ do_action ("ws_plugin__s2member_during_delete_tracking_cookie", get_defined_vars ());
50
  /**/
51
+ header("Content-Type: image/png"); /* Send a 1px transparent PNG image to browser. */
52
  /**/
53
+ exit(file_get_contents (dirname (dirname (dirname (__FILE__))) . "/images/trans-1px.png"));
54
  }
55
  /**/
56
+ do_action ("ws_plugin__s2member_after_delete_tracking_cookie", get_defined_vars ());
57
  }
58
  /**
59
  * Deletes s2Member's temporary tracking cookie.
71
  /**/
72
  if (!empty ($_GET["s2member_delete_sp_tracking_cookie"])) /* Deletes cookie. */
73
  {
74
+ setcookie ("s2member_sp_tracking", "", time () + 31556926, COOKIEPATH, COOKIE_DOMAIN);
75
+ setcookie ("s2member_sp_tracking", "", time () + 31556926, SITECOOKIEPATH, COOKIE_DOMAIN);
76
  /**/
77
  do_action ("ws_plugin__s2member_during_delete_sp_tracking_cookie", get_defined_vars ());
78
  /**/
79
+ header("Content-Type: image/png"); /* Send a 1px transparent PNG image to browser. */
80
+ /**/
81
+ exit(file_get_contents (dirname (dirname (dirname (__FILE__))) . "/images/trans-1px.png"));
82
  }
83
  /**/
84
  do_action ("ws_plugin__s2member_after_delete_sp_tracking_cookie", get_defined_vars ());
includes/classes/tracking-cookies.inc.php CHANGED
@@ -15,7 +15,7 @@
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_tracking_cookies"))
21
  {
@@ -31,17 +31,17 @@ if (!class_exists ("c_ws_plugin__s2member_tracking_cookies"))
31
  * Deletes s2Member's temporary tracking cookie.
32
  *
33
  * @package s2Member\Tracking
34
- * @since 3.5
35
  *
36
  * @attaches-to: ``add_action("init");``
37
  *
38
  * @return null|inner Return-value of inner routine.
39
  */
40
- public static function delete_signup_tracking_cookie ()
41
  {
42
- if (!empty ($_GET["s2member_delete_signup_tracking_cookie"])) /* Call inner routine? */
43
  {
44
- return c_ws_plugin__s2member_tracking_cookies_in::delete_signup_tracking_cookie ();
45
  }
46
  }
47
  /**
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_tracking_cookies"))
21
  {
31
  * Deletes s2Member's temporary tracking cookie.
32
  *
33
  * @package s2Member\Tracking
34
+ * @since 110815
35
  *
36
  * @attaches-to: ``add_action("init");``
37
  *
38
  * @return null|inner Return-value of inner routine.
39
  */
40
+ public static function delete_tracking_cookie ()
41
  {
42
+ if (!empty ($_GET["s2member_delete_tracking_cookie"])) /* Call inner routine? */
43
  {
44
+ return c_ws_plugin__s2member_tracking_cookies_in::delete_tracking_cookie ();
45
  }
46
  }
47
  /**
includes/classes/user-new-in.inc.php CHANGED
@@ -69,7 +69,7 @@ if (!class_exists ("c_ws_plugin__s2member_user_new_in"))
69
  /**/
70
  $unfs .= '<tr>' . "\n";
71
  $unfs .= '<th><label for="ws-plugin--s2member-user-new-first-name">First Name:</label></th>' . "\n";
72
- $unfs .= '<td><input type="text" name="ws_plugin__s2member_user_new_first_name" id="ws-plugin--s2member-user-new-first-name" value="' . format_to_edit ($_p["ws_plugin__s2member_user_new_first_name"]) . '" class="regular-text" /></td>' . "\n";
73
  $unfs .= '</tr>' . "\n";
74
  /**/
75
  eval ('foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;');
@@ -82,7 +82,7 @@ if (!class_exists ("c_ws_plugin__s2member_user_new_in"))
82
  /**/
83
  $unfs .= '<tr>' . "\n";
84
  $unfs .= '<th><label for="ws-plugin--s2member-user-new-last-name">Last Name:</label></th>' . "\n";
85
- $unfs .= '<td><input type="text" name="ws_plugin__s2member_user_new_last_name" id="ws-plugin--s2member-user-new-last-name" value="' . format_to_edit ($_p["ws_plugin__s2member_user_new_last_name"]) . '" class="regular-text" /></td>' . "\n";
86
  $unfs .= '</tr>' . "\n";
87
  /**/
88
  eval ('foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;');
@@ -155,7 +155,7 @@ if (!class_exists ("c_ws_plugin__s2member_user_new_in"))
155
  /**/
156
  $unfs .= '<tr>' . "\n";
157
  $unfs .= '<th><label for="ws-plugin--s2member-user-new-s2member-ccaps">Custom Capabilities:</label> <a href="#" onclick="alert(\'Optional. This is VERY advanced.\\nSee: s2Member -> API Scripting -> Custom Capabilities.' . ((is_multisite ()) ? '\\n\\nCustom Capabilities are assigned on a per-Blog basis. So having a set of Custom Capabilities for one Blog, and having NO Custom Capabilities on another Blog - is very common. This is how permissions are designed to work.' : '') . '\'); return false;" tabindex="-1">[?]</a></th>' . "\n";
158
- $unfs .= '<td><input type="text" name="ws_plugin__s2member_user_new_s2member_ccaps" id="ws-plugin--s2member-user-new-s2member-ccaps" value="' . format_to_edit ($_p["ws_plugin__s2member_user_new_s2member_ccaps"]) . '" class="regular-text" 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 ());" /></td>' . "\n";
159
  $unfs .= '</tr>' . "\n";
160
  /**/
161
  eval ('foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;');
69
  /**/
70
  $unfs .= '<tr>' . "\n";
71
  $unfs .= '<th><label for="ws-plugin--s2member-user-new-first-name">First Name:</label></th>' . "\n";
72
+ $unfs .= '<td><input type="text" name="ws_plugin__s2member_user_new_first_name" id="ws-plugin--s2member-user-new-first-name" value="' . esc_attr ($_p["ws_plugin__s2member_user_new_first_name"]) . '" class="regular-text" /></td>' . "\n";
73
  $unfs .= '</tr>' . "\n";
74
  /**/
75
  eval ('foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;');
82
  /**/
83
  $unfs .= '<tr>' . "\n";
84
  $unfs .= '<th><label for="ws-plugin--s2member-user-new-last-name">Last Name:</label></th>' . "\n";
85
+ $unfs .= '<td><input type="text" name="ws_plugin__s2member_user_new_last_name" id="ws-plugin--s2member-user-new-last-name" value="' . esc_attr ($_p["ws_plugin__s2member_user_new_last_name"]) . '" class="regular-text" /></td>' . "\n";
86
  $unfs .= '</tr>' . "\n";
87
  /**/
88
  eval ('foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;');
155
  /**/
156
  $unfs .= '<tr>' . "\n";
157
  $unfs .= '<th><label for="ws-plugin--s2member-user-new-s2member-ccaps">Custom Capabilities:</label> <a href="#" onclick="alert(\'Optional. This is VERY advanced.\\nSee: s2Member -> API Scripting -> Custom Capabilities.' . ((is_multisite ()) ? '\\n\\nCustom Capabilities are assigned on a per-Blog basis. So having a set of Custom Capabilities for one Blog, and having NO Custom Capabilities on another Blog - is very common. This is how permissions are designed to work.' : '') . '\'); return false;" tabindex="-1">[?]</a></th>' . "\n";
158
+ $unfs .= '<td><input type="text" name="ws_plugin__s2member_user_new_s2member_ccaps" id="ws-plugin--s2member-user-new-s2member-ccaps" value="' . format_to_edit ($_p["ws_plugin__s2member_user_new_s2member_ccaps"]) . '" class="regular-text" 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 ());" /></td>' . "\n";
159
  $unfs .= '</tr>' . "\n";
160
  /**/
161
  eval ('foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;');
includes/classes/user-securities.inc.php CHANGED
@@ -28,7 +28,7 @@ if (!class_exists ("c_ws_plugin__s2member_user_securities"))
28
  class c_ws_plugin__s2member_user_securities
29
  {
30
  /**
31
- * Initializes a Multisite Filter for `user_has_cap`.
32
  *
33
  * It's very important that this is NOT attached before WordPress® creates `$current_user` via `$wp->init()`.
34
  * This prevents crashes when other plugins attempt to call upon `current_user_can()` before WordPress is initialized.
@@ -43,13 +43,13 @@ if (!class_exists ("c_ws_plugin__s2member_user_securities"))
43
  */
44
  public static function initialize () /* Initializes the Filter for `user_has_cap`. */
45
  {
46
- add_filter ("user_has_cap", "c_ws_plugin__s2member_user_securities::ms_user_capabilities", 10, 3);
47
  }
48
  /**
49
- * Alters `WP_User->has_cap()` on a Multisite Blog Farm.
50
  *
51
  * @package s2Member\User_Securities
52
- * @since 3.5
53
  *
54
  * @attaches-to: ``add_filter("user_has_cap");``
55
  *
@@ -63,17 +63,20 @@ if (!class_exists ("c_ws_plugin__s2member_user_securities"))
63
  * Other arguments starting from array index `[2]` are normal.
64
  * @return array An array of Capabilities.
65
  */
66
- public static function ms_user_capabilities ($capabilities = FALSE, $caps_map = FALSE, $args = FALSE)
67
  {
68
  eval ('foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;');
69
- do_action ("ws_plugin__s2member_before_ms_user_capabilities", get_defined_vars ());
70
  unset ($__refs, $__v); /* Unset defined __refs, __v. */
71
  /**/
72
- if (is_multisite () && c_ws_plugin__s2member_utils_conds::is_multisite_farm () && (is_super_admin () || !empty ($capabilities["administrator"])) && !empty ($args[0]) && ($args[0] === "edit_user" || $args[0] === "edit_users"))
 
 
 
73
  if ($args[0] === "edit_users" || ($args[0] === "edit_user" && !empty ($args[2]) && ((!empty ($args[1]) && (int)$args[1] === (int)$args[2]) || is_user_member_of_blog ($args[2]))))
74
- $capabilities = array_merge ((array)$capabilities, array ("edit_users" => 1, "do_not_allow" => 1));
75
  /**/
76
- return apply_filters ("ws_plugin__s2member_ms_user_capabilities", $capabilities, get_defined_vars ());
77
  }
78
  /**
79
  * Alters this Filter inside `/wp-admin/user-edit.php`.
@@ -123,11 +126,11 @@ if (!class_exists ("c_ws_plugin__s2member_user_securities"))
123
  unset ($__refs, $__v); /* Unset defined __refs, __v. */
124
  /**/
125
  if ($show && is_multisite () && c_ws_plugin__s2member_utils_conds::is_multisite_farm ())
126
- if (!is_super_admin () && is_object ($user) && $user->ID && is_object ($current_user = wp_get_current_user ()) && $current_user->ID)
127
  if ($user->ID !== $current_user->ID)
128
  $show = false;
129
  /**/
130
- if ($show && is_object ($user) && $user->ID && $user->user_login === "demo")
131
  $show = false; /* Lock Password on Demos. */
132
  /**/
133
  return apply_filters ("ws_plugin__s2member_hide_password_fields", $show, get_defined_vars ());
28
  class c_ws_plugin__s2member_user_securities
29
  {
30
  /**
31
+ * Initializes Filter for `user_has_cap`.
32
  *
33
  * It's very important that this is NOT attached before WordPress® creates `$current_user` via `$wp->init()`.
34
  * This prevents crashes when other plugins attempt to call upon `current_user_can()` before WordPress is initialized.
43
  */
44
  public static function initialize () /* Initializes the Filter for `user_has_cap`. */
45
  {
46
+ add_filter ("user_has_cap", "c_ws_plugin__s2member_user_securities::user_capabilities", 10, 3);
47
  }
48
  /**
49
+ * Alters `WP_User->has_cap()` in special cases for Administrators.
50
  *
51
  * @package s2Member\User_Securities
52
+ * @since 110815
53
  *
54
  * @attaches-to: ``add_filter("user_has_cap");``
55
  *
63
  * Other arguments starting from array index `[2]` are normal.
64
  * @return array An array of Capabilities.
65
  */
66
+ public static function user_capabilities ($capabilities = FALSE, $caps_map = FALSE, $args = FALSE)
67
  {
68
  eval ('foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;');
69
+ do_action ("ws_plugin__s2member_before_user_capabilities", get_defined_vars ());
70
  unset ($__refs, $__v); /* Unset defined __refs, __v. */
71
  /**/
72
+ if (!is_multisite () && !empty ($capabilities["administrator"]) && !empty ($args[0]) && preg_match ("/^access_s2member_ccap_/i", $args[0]) && apply_filters ("ws_plugin__s2member_admins_have_all_ccaps", true, get_defined_vars ()))
73
+ $capabilities = array_merge ((array)$capabilities, array ($args[0] => 1));
74
+ /**/
75
+ else if (is_multisite () && c_ws_plugin__s2member_utils_conds::is_multisite_farm () && (is_super_admin () || !empty ($capabilities["administrator"])) && !empty ($args[0]) && ($args[0] === "edit_user" || $args[0] === "edit_users"))
76
  if ($args[0] === "edit_users" || ($args[0] === "edit_user" && !empty ($args[2]) && ((!empty ($args[1]) && (int)$args[1] === (int)$args[2]) || is_user_member_of_blog ($args[2]))))
77
+ $capabilities = array_merge ((array)$capabilities, array ("edit_users" => 1));
78
  /**/
79
+ return apply_filters ("ws_plugin__s2member_user_capabilities", $capabilities, get_defined_vars ());
80
  }
81
  /**
82
  * Alters this Filter inside `/wp-admin/user-edit.php`.
126
  unset ($__refs, $__v); /* Unset defined __refs, __v. */
127
  /**/
128
  if ($show && is_multisite () && c_ws_plugin__s2member_utils_conds::is_multisite_farm ())
129
+ if (!is_super_admin () && is_object ($user) && !empty ($user->ID) && is_object ($current_user = wp_get_current_user ()) && !empty ($current_user->ID))
130
  if ($user->ID !== $current_user->ID)
131
  $show = false;
132
  /**/
133
+ if ($show && is_object ($user) && !empty ($user->ID) && $user->user_login === "demo")
134
  $show = false; /* Lock Password on Demos. */
135
  /**/
136
  return apply_filters ("ws_plugin__s2member_hide_password_fields", $show, get_defined_vars ());
includes/classes/users-list-in.inc.php CHANGED
@@ -152,7 +152,7 @@ if (!class_exists ("c_ws_plugin__s2member_users_list_in"))
152
  /**/
153
  echo '<tr>' . "\n";
154
  echo '<th><label for="ws-plugin--s2member-profile-s2member-ccaps">Custom Capabilities:</label> <a href="#" onclick="alert(\'Optional. This is VERY advanced.\\nSee: s2Member -> API Scripting -> Custom Capabilities.' . ((is_multisite ()) ? '\\n\\nCustom Capabilities are assigned on a per-Blog basis. So having a set of Custom Capabilities for one Blog, and having NO Custom Capabilities on another Blog - is very common. This is how permissions are designed to work.' : '') . '\'); return false;" tabindex="-1">[?]</a>' . ((is_multisite ()) ? '<br /><small>( for this Blog )</small>' : '') . '</th>' . "\n";
155
- echo '<td><input type="text" name="ws_plugin__s2member_profile_s2member_ccaps" id="ws-plugin--s2member-profile-s2member-ccaps" value="' . format_to_edit (((!empty ($ccaps)) ? implode (",", $ccaps) : "")) . '" class="regular-text" 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 ());" /></td>' . "\n";
156
  echo '</tr>' . "\n";
157
  /**/
158
  eval('foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;');
@@ -444,9 +444,10 @@ if (!class_exists ("c_ws_plugin__s2member_users_list_in"))
444
  if (preg_match ("/^access_s2member_ccap_/", $cap))
445
  $user->remove_cap ($ccap = $cap);
446
  /**/
447
- foreach (preg_split ("/[\r\n\t\s;,]+/", $_p["ws_plugin__s2member_profile_s2member_ccaps"]) as $ccap)
448
- if (strlen ($ccap)) /* Don't add empty Capabilities. */
449
- $user->add_cap ("access_s2member_ccap_" . trim (strtolower ($ccap)));
 
450
  }
451
  /**/
452
  if ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["custom_reg_fields"])
152
  /**/
153
  echo '<tr>' . "\n";
154
  echo '<th><label for="ws-plugin--s2member-profile-s2member-ccaps">Custom Capabilities:</label> <a href="#" onclick="alert(\'Optional. This is VERY advanced.\\nSee: s2Member -> API Scripting -> Custom Capabilities.' . ((is_multisite ()) ? '\\n\\nCustom Capabilities are assigned on a per-Blog basis. So having a set of Custom Capabilities for one Blog, and having NO Custom Capabilities on another Blog - is very common. This is how permissions are designed to work.' : '') . '\'); return false;" tabindex="-1">[?]</a>' . ((is_multisite ()) ? '<br /><small>( for this Blog )</small>' : '') . '</th>' . "\n";
155
+ echo '<td><input type="text" name="ws_plugin__s2member_profile_s2member_ccaps" id="ws-plugin--s2member-profile-s2member-ccaps" value="' . format_to_edit (((!empty ($ccaps)) ? implode (",", $ccaps) : "")) . '" class="regular-text" 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 ());" /></td>' . "\n";
156
  echo '</tr>' . "\n";
157
  /**/
158
  eval('foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;');
444
  if (preg_match ("/^access_s2member_ccap_/", $cap))
445
  $user->remove_cap ($ccap = $cap);
446
  /**/
447
+ if (!empty ($_p["ws_plugin__s2member_profile_s2member_ccaps"]))
448
+ foreach (preg_split ("/[\r\n\t\s;,]+/", $_p["ws_plugin__s2member_profile_s2member_ccaps"]) as $ccap)
449
+ if (strlen ($ccap = trim (strtolower (preg_replace ("/[^a-z_0-9]/i", "", $ccap)))))
450
+ $user->add_cap ("access_s2member_ccap_" . $ccap);
451
  }
452
  /**/
453
  if ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["custom_reg_fields"])
includes/classes/utilities.inc.php CHANGED
@@ -135,6 +135,25 @@ if (!class_exists ("c_ws_plugin__s2member_utilities"))
135
  /**/
136
  return (!empty ($badge)) ? $badge : ""; /* Return Security Badge. */
137
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
138
  }
139
  }
140
  ?>
135
  /**/
136
  return (!empty ($badge)) ? $badge : ""; /* Return Security Badge. */
137
  }
138
+ /**
139
+ * Acquires information about memory usage.
140
+ *
141
+ * @package s2Member\Utilities
142
+ * @since 110815
143
+ *
144
+ * @return str String with `Memory x MB :: Real Memory x MB :: Peak Memory x MB :: Real Peak Memory x MB`.
145
+ */
146
+ public static function mem_details ()
147
+ {
148
+ $memory = number_format (memory_get_usage () / 1048576, 2, ".", "");
149
+ $real_memory = number_format (memory_get_usage (true) / 1048576, 2, ".", "");
150
+ $peak_memory = number_format (memory_get_peak_usage () / 1048576, 2, ".", "");
151
+ $real_peak_memory = number_format (memory_get_peak_usage (true) / 1048576, 2, ".", "");
152
+ /**/
153
+ $details = "Memory " . $memory . " MB :: Real Memory " . $real_memory . " MB :: Peak Memory " . $peak_memory . " MB :: Real Peak Memory " . $real_peak_memory . " MB";
154
+ /**/
155
+ return $details; /* Return all details. */
156
+ }
157
  }
158
  }
159
  ?>
includes/classes/utils-captchas.inc.php CHANGED
@@ -59,9 +59,10 @@ if (!class_exists ("c_ws_plugin__s2member_utils_captchas"))
59
  $theme = ($theme) ? $theme : "clean"; /* Defaults to the `clean` theme style. */
60
  $tabindex = (strlen ($tabindex)) ? (int)$tabindex : -1; /* -1 default. */
61
  /**/
62
- $s = '<script type="text/javascript">' . "if(typeof RecaptchaOptions !== 'object'){ var RecaptchaOptions = {theme: '" . c_ws_plugin__s2member_utils_strings::esc_sq ($theme) . "', lang: '" . c_ws_plugin__s2member_utils_strings::esc_sq ($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["recaptcha"]["lang"]) . "', tabindex: " . $tabindex . " }; }" . '</script>' . "\n";
 
63
  /**/
64
- return $s . '<script type="text/javascript" src="' . esc_attr ('https://www.google.com/recaptcha/api/challenge?k=' . urlencode ($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["recaptcha"]["public_key"])) . '' . (($error) ? '&amp;error=' . urlencode ($error) : '') . '"></script>';
65
  }
66
  }
67
  }
59
  $theme = ($theme) ? $theme : "clean"; /* Defaults to the `clean` theme style. */
60
  $tabindex = (strlen ($tabindex)) ? (int)$tabindex : -1; /* -1 default. */
61
  /**/
62
+ $options = '<script type="text/javascript">' . "if(typeof RecaptchaOptions !== 'object'){ var RecaptchaOptions = {theme: '" . c_ws_plugin__s2member_utils_strings::esc_sq ($theme) . "', lang: '" . c_ws_plugin__s2member_utils_strings::esc_sq ($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["recaptcha"]["lang"]) . "', tabindex: " . $tabindex . " }; }" . '</script>' . "\n";
63
+ $adjustments = '<script type="text/javascript">' . "if(typeof jQuery === 'function'){ jQuery('td a[id^=\"recaptcha\"]').removeAttr('tabindex'); }" . '</script>';
64
  /**/
65
+ return $options . '<script type="text/javascript" src="' . esc_attr ('https://www.google.com/recaptcha/api/challenge?k=' . urlencode ($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["recaptcha"]["public_key"])) . '' . (($error) ? '&amp;error=' . urlencode ($error) : '') . '"></script>' . $adjustments;
66
  }
67
  }
68
  }
includes/classes/utils-logs.inc.php CHANGED
@@ -15,7 +15,7 @@
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_logs"))
21
  {
@@ -47,7 +47,7 @@ if (!class_exists ("c_ws_plugin__s2member_utils_logs"))
47
  {
48
  $max = apply_filters ("ws_plugin__s2member_oversize_log_file_bytes", 2097152, get_defined_vars ());
49
  /**/
50
- eval('$log_files = scandir ($dir); shuffle($log_files); $counter = 1;');
51
  /**/
52
  foreach ($log_files as $file) /* Go through each log file. Up to 25 files at a time. */
53
  {
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_logs"))
21
  {
47
  {
48
  $max = apply_filters ("ws_plugin__s2member_oversize_log_file_bytes", 2097152, get_defined_vars ());
49
  /**/
50
+ eval ('$log_files = scandir ($dir); shuffle($log_files); $counter = 1;');
51
  /**/
52
  foreach ($log_files as $file) /* Go through each log file. Up to 25 files at a time. */
53
  {
includes/classes/utils-strings.inc.php CHANGED
@@ -15,7 +15,7 @@
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_strings"))
21
  {
@@ -38,7 +38,7 @@ if (!class_exists ("c_ws_plugin__s2member_utils_strings"))
38
  */
39
  public static function esc_dq ($string = FALSE)
40
  {
41
- return preg_replace ('/"/', '\"', (string)$string);
42
  }
43
  /**
44
  * Escapes single quotes.
@@ -51,7 +51,7 @@ if (!class_exists ("c_ws_plugin__s2member_utils_strings"))
51
  */
52
  public static function esc_sq ($string = FALSE)
53
  {
54
- return preg_replace ("/'/", "\'", (string)$string);
55
  }
56
  /**
57
  * Escapes dollars signs ( for regex patterns ).
@@ -64,7 +64,7 @@ if (!class_exists ("c_ws_plugin__s2member_utils_strings"))
64
  */
65
  public static function esc_ds ($string = FALSE)
66
  {
67
- return preg_replace ('/\$/', '\\\$', (string)$string);
68
  }
69
  /**
70
  * Sanitizes a string; by removing non-standard characters.
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_strings"))
21
  {
38
  */
39
  public static function esc_dq ($string = FALSE)
40
  {
41
+ return str_replace ('"', '\"', (string)$string);
42
  }
43
  /**
44
  * Escapes single quotes.
51
  */
52
  public static function esc_sq ($string = FALSE)
53
  {
54
+ return str_replace ("'", "\'", (string)$string);
55
  }
56
  /**
57
  * Escapes dollars signs ( for regex patterns ).
64
  */
65
  public static function esc_ds ($string = FALSE)
66
  {
67
+ return str_replace ('$', '\\$', (string)$string);
68
  }
69
  /**
70
  * Sanitizes a string; by removing non-standard characters.
includes/functions/api-functions.inc.php CHANGED
@@ -131,8 +131,15 @@ if (!function_exists ("user_is"))
131
  {
132
  function user_is ($id = FALSE, $role = FALSE)
133
  {
134
- $role = ($role === "s2member_level0") ? "subscriber" : $role;
135
- return user_can ($id, preg_replace ("/^access_/i", "", $role));
 
 
 
 
 
 
 
136
  }
137
  }
138
  /**
@@ -209,8 +216,7 @@ if (!function_exists ("user_is_not"))
209
  {
210
  function user_is_not ($id = FALSE, $role = FALSE)
211
  {
212
- $role = ($role === "s2member_level0") ? "subscriber" : $role;
213
- return (!user_can ($id, preg_replace ("/^access_/i", "", $role)));
214
  }
215
  }
216
  /**
@@ -287,8 +293,15 @@ if (!function_exists ("current_user_is"))
287
  {
288
  function current_user_is ($role = FALSE)
289
  {
290
- $role = ($role === "s2member_level0") ? "subscriber" : $role;
291
- return current_user_can (preg_replace ("/^access_/i", "", $role));
 
 
 
 
 
 
 
292
  }
293
  }
294
  /**
@@ -364,8 +377,7 @@ if (!function_exists ("current_user_is_not"))
364
  {
365
  function current_user_is_not ($role = FALSE)
366
  {
367
- $role = ($role === "s2member_level0") ? "subscriber" : $role;
368
- return (!current_user_can (preg_replace ("/^access_/i", "", $role)));
369
  }
370
  }
371
  /**
@@ -448,8 +460,15 @@ if (!function_exists ("current_user_is_for_blog"))
448
  {
449
  function current_user_is_for_blog ($blog_id = FALSE, $role = FALSE)
450
  {
451
- $role = ($role === "s2member_level0") ? "subscriber" : $role;
452
- return current_user_can_for_blog ($blog_id, preg_replace ("/^access_/i", "", $role));
 
 
 
 
 
 
 
453
  }
454
  }
455
  /**
@@ -520,8 +539,7 @@ if (!function_exists ("current_user_is_not_for_blog"))
520
  {
521
  function current_user_is_not_for_blog ($blog_id = FALSE, $role = FALSE)
522
  {
523
- $role = ($role === "s2member_level0") ? "subscriber" : $role;
524
- return (!current_user_can_for_blog ($blog_id, preg_replace ("/^access_/i", "", $role)));
525
  }
526
  }
527
  /**
131
  {
132
  function user_is ($id = FALSE, $role = FALSE)
133
  {
134
+ $role = ($role === "s2member_level0") ? "subscriber" : preg_replace ("/^access_/i", "", $role);
135
+ /**/
136
+ if (($role === "super_administrator" || $role === "administrator") && is_multisite () && is_super_admin ($id))
137
+ return true; /* Return true, Super Admins are always considered an Admnistrator, for all Blogs. */
138
+ /**/
139
+ else if (is_multisite () && is_super_admin ($id)) /* Else return false for Super Admins here. */
140
+ return false; /* Super Admins can access all Capabilities, so the default handling would fail. */
141
+ /**/
142
+ return user_can ($id, $role);
143
  }
144
  }
145
  /**
216
  {
217
  function user_is_not ($id = FALSE, $role = FALSE)
218
  {
219
+ return (!user_is ($id, $role));
 
220
  }
221
  }
222
  /**
293
  {
294
  function current_user_is ($role = FALSE)
295
  {
296
+ $role = ($role === "s2member_level0") ? "subscriber" : preg_replace ("/^access_/i", "", $role);
297
+ /**/
298
+ if (($role === "super_administrator" || $role === "administrator") && is_multisite () && is_super_admin ())
299
+ return true; /* Return true, Super Admins are always considered an Admnistrator, for all Blogs. */
300
+ /**/
301
+ else if (is_multisite () && is_super_admin ()) /* Else return false for Super Admins here. */
302
+ return false; /* Super Admins can access all Capabilities, so the default handling would fail. */
303
+ /**/
304
+ return current_user_can ($role);
305
  }
306
  }
307
  /**
377
  {
378
  function current_user_is_not ($role = FALSE)
379
  {
380
+ return (!current_user_is ($role));
 
381
  }
382
  }
383
  /**
460
  {
461
  function current_user_is_for_blog ($blog_id = FALSE, $role = FALSE)
462
  {
463
+ $role = ($role === "s2member_level0") ? "subscriber" : preg_replace ("/^access_/i", "", $role);
464
+ /**/
465
+ if (($role === "super_administrator" || $role === "administrator") && is_multisite () && is_super_admin ())
466
+ return true; /* Return true, Super Admins are always considered an Admnistrator, for all Blogs. */
467
+ /**/
468
+ else if (is_multisite () && is_super_admin ()) /* Else return false for Super Admins here. */
469
+ return false; /* Super Admins can access all Capabilities, so the default handling would fail. */
470
+ /**/
471
+ return current_user_can_for_blog ($blog_id, $role);
472
  }
473
  }
474
  /**
539
  {
540
  function current_user_is_not_for_blog ($blog_id = FALSE, $role = FALSE)
541
  {
542
+ return (!current_user_is_for_blog ($blog_id, $role));
 
543
  }
544
  }
545
  /**
includes/hooks.inc.php CHANGED
@@ -15,7 +15,7 @@
15
  * @since 3.0
16
  */
17
  if (realpath (__FILE__) === realpath ($_SERVER["SCRIPT_FILENAME"]))
18
- exit("Do not access this file directly.");
19
  /*
20
  Add the plugin Actions/Filters here.
21
  */
@@ -33,8 +33,8 @@ add_action ("init", "c_ws_plugin__s2member_paypal_notify::paypal_notify", 1);
33
  add_action ("init", "c_ws_plugin__s2member_files::check_file_download_access", 1);
34
  add_action ("init", "c_ws_plugin__s2member_profile_mods::handle_profile_modifications", 1);
35
  add_action ("init", "c_ws_plugin__s2member_profile_mods_4bp::handle_profile_modifications_4bp", 1);
36
- add_action ("init", "c_ws_plugin__s2member_tracking_cookies::delete_signup_tracking_cookie", 1);
37
  add_action ("init", "c_ws_plugin__s2member_tracking_cookies::delete_sp_tracking_cookie", 1);
 
38
  add_action ("init", "c_ws_plugin__s2member_cron_jobs::auto_eot_system_via_cron", 1);
39
  add_action ("init", "c_ws_plugin__s2member_mo_page::membership_options_page", 1);
40
  add_action ("init", "c_ws_plugin__s2member_s_badge_status::s_badge_status", 1);
@@ -109,6 +109,12 @@ add_action ("login_footer", "c_ws_plugin__s2member_login_customizations::login_f
109
  add_action ("login_footer", "c_ws_plugin__s2member_tracking_codes::display_signup_tracking_codes");
110
  add_action ("wp_footer", "c_ws_plugin__s2member_tracking_codes::display_signup_tracking_codes");
111
  /**/
 
 
 
 
 
 
112
  add_action ("login_footer", "c_ws_plugin__s2member_tracking_codes::display_sp_tracking_codes");
113
  add_action ("wp_footer", "c_ws_plugin__s2member_tracking_codes::display_sp_tracking_codes");
114
  /**/
15
  * @since 3.0
16
  */
17
  if (realpath (__FILE__) === realpath ($_SERVER["SCRIPT_FILENAME"]))
18
+ exit ("Do not access this file directly.");
19
  /*
20
  Add the plugin Actions/Filters here.
21
  */
33
  add_action ("init", "c_ws_plugin__s2member_files::check_file_download_access", 1);
34
  add_action ("init", "c_ws_plugin__s2member_profile_mods::handle_profile_modifications", 1);
35
  add_action ("init", "c_ws_plugin__s2member_profile_mods_4bp::handle_profile_modifications_4bp", 1);
 
36
  add_action ("init", "c_ws_plugin__s2member_tracking_cookies::delete_sp_tracking_cookie", 1);
37
+ add_action ("init", "c_ws_plugin__s2member_tracking_cookies::delete_tracking_cookie", 1);
38
  add_action ("init", "c_ws_plugin__s2member_cron_jobs::auto_eot_system_via_cron", 1);
39
  add_action ("init", "c_ws_plugin__s2member_mo_page::membership_options_page", 1);
40
  add_action ("init", "c_ws_plugin__s2member_s_badge_status::s_badge_status", 1);
109
  add_action ("login_footer", "c_ws_plugin__s2member_tracking_codes::display_signup_tracking_codes");
110
  add_action ("wp_footer", "c_ws_plugin__s2member_tracking_codes::display_signup_tracking_codes");
111
  /**/
112
+ add_action ("login_footer", "c_ws_plugin__s2member_tracking_codes::display_modification_tracking_codes");
113
+ add_action ("wp_footer", "c_ws_plugin__s2member_tracking_codes::display_modification_tracking_codes");
114
+ /**/
115
+ add_action ("login_footer", "c_ws_plugin__s2member_tracking_codes::display_ccap_tracking_codes");
116
+ add_action ("wp_footer", "c_ws_plugin__s2member_tracking_codes::display_ccap_tracking_codes");
117
+ /**/
118
  add_action ("login_footer", "c_ws_plugin__s2member_tracking_codes::display_sp_tracking_codes");
119
  add_action ("wp_footer", "c_ws_plugin__s2member_tracking_codes::display_sp_tracking_codes");
120
  /**/
includes/menu-pages/api-ops.inc.php CHANGED
@@ -53,7 +53,9 @@ if (!class_exists ("c_ws_plugin__s2member_menu_page_api_ops"))
53
  /**/
54
  echo '<div class="ws-menu-page-section ws-plugin--s2member-signup-notifications-section">' . "\n";
55
  echo '<h3>Signup Notification URLs ( optional )</h3>' . "\n";
56
- echo '<p>If you use affiliate software, or have back-office routines that need to be notified whenever a new Subscription is created, you\'ll want to read this section. This is marked `Signup`, because the URLs that you list below, will be notified each time a "new" "paying" Member signs up. Depending on your fee structure, this may include a first Initial Payment that establishes their Subscription. This Notification will only be triggered once for each Member. Signup Notifications are sent right after a "new" Member signs up successfully through your Payment Gateway, regardless of whether any money has actually been transacted initially. In other words, this Notification is triggered anytime a "new" "paying" Member signs up, even if you provided them with a 100% Free Trial Period. However, this Notification will NOT be processed for Free Subscribers that register without going through your Payment Gateway at all. In addition, this Notification will NOT be processed when an "existing" User/Member pays for a new Subscription <em>( see: Modification Notifications for that scenario )</em>. Please note, this feature is not to be confused with the PayPal® IPN service. PayPal® IPN <em>( and other service integrations )</em> are already built into s2Member. They remain active at all times. These Signup Notifications are an added layer of functionality, and they are completely optional.</p>' . "\n";
 
 
57
  do_action ("ws_plugin__s2member_during_api_ops_page_during_left_sections_during_signup_notifications", get_defined_vars ());
58
  /**/
59
  echo '<table class="form-table">' . "\n";
@@ -75,7 +77,7 @@ if (!class_exists ("c_ws_plugin__s2member_menu_page_api_ops"))
75
  echo 'Signup Notifications take place silently behind-the-scene, using an HTTP connection.<br /><br />' . "\n";
76
  echo '<strong>You can also use these special Replacement Codes if you need them:</strong>' . "\n";
77
  echo '<ul>' . "\n";
78
- echo '<li><code>%%subscr_id%%</code> = The Paid Subscription ID, which remains constant throughout any &amp; all future payments. [ <a href="#" onclick="alert(\'There is one exception. If you are selling Lifetime or Fixed-Term ( non-recurring ) access, using Buy Now functionality; the %%subscr_id%% is actually set to the Transaction ID for the purchase.\\n\\nPayment Gateways do not provide a specific Subscription ID for Buy Now purchases. Since Lifetime &amp; Fixed-Term Subscriptions are NOT recurring ( i.e. there is only ONE payment ), using the Transaction ID as the Subscription ID is a graceful way to deal with this minor conflict.\'); return false;">?</a> ]</li>' . "\n";
79
  echo '<li><code>%%initial%%</code> = The Initial Fee charged during signup. If you offered a 100% Free Trial, this will be <code>0</code>. [ <a href="#" onclick="alert(\'This will always represent the amount of money the Customer spent, whenever they initially signed up, no matter what. Even if that amount is 0.\\n\\nIf a Customer signs up, under the terms of a 100% Free Trial Period, this will be 0. So be careful using %%initial%% when you offer a 100% Free Trial Period, because a $0.00 sale amount could cause havoc with affiliate programs.\\n\\nIf you\\\'re offering a 100% Free Trial Period, and you need to track sales through affiliate programs, you can either hard-code an amount; or use `Payment Notifications` instead.\'); return false;">?</a> ]</li>' . "\n";
80
  echo '<li><code>%%regular%%</code> = The Regular Amount of the Subscription. This value is <code>always > 0</code>, no matter what. [ <a href="#" onclick="alert(\'This is how much the Subscription costs after an Initial Period expires. The %%regular%% rate is always > 0. If you did NOT offer an Initial Period at a different price, %%initial%% and %%regular%% will be equal to the same thing.\'); return false;">?</a> ]</li>' . "\n";
81
  echo '<li><code>%%recurring%%</code> = This is the amount that will be charged on a recurring basis, or <code>0</code> if non-recurring. [ <a href="#" onclick="alert(\'If Recurring Payments have not been required, this will be equal to 0. That being said, %%regular%% &amp; %%recurring%% are usually the same value. This variable can be used in two different ways. You can use it to determine what the Regular Recurring Rate is, or to determine whether the Subscription will recur or not. If it is going to recur, %%recurring%% will be > 0.\'); return false;">?</a> ]</li>' . "\n";
@@ -142,7 +144,9 @@ if (!class_exists ("c_ws_plugin__s2member_menu_page_api_ops"))
142
  /**/
143
  echo '<div class="ws-menu-page-section ws-plugin--s2member-registration-notifications-section">' . "\n";
144
  echo '<h3>Registration Notification URLs ( optional )</h3>' . "\n";
145
- echo '<p>If you use affiliate software, or have back-office routines that need to be notified whenever a "new" Member is created, you\'ll want to read this section. This is marked `Registration`, because the URLs that you list below, will be notified each time a "new" Member registers a Username. This is usually triggered right after a `Signup` Notification; at the point in which a "new" Member successfully completes the Registration form, and they are assigned a Username. However, this is ALSO triggered whenever you create a "new" User inside your WordPress® Dashboard. Please note, this feature is not to be confused with the PayPal® IPN service. PayPal® IPN <em>( and other service integrations )</em> are already built into s2Member. They remain active at all times. These Registration Notifications are an added layer of functionality, and they are completely optional.</p>' . "\n";
 
 
146
  do_action ("ws_plugin__s2member_during_api_ops_page_during_left_sections_during_registration_notifications", get_defined_vars ());
147
  /**/
148
  echo '<table class="form-table">' . "\n";
@@ -240,7 +244,10 @@ if (!class_exists ("c_ws_plugin__s2member_menu_page_api_ops"))
240
  /**/
241
  echo '<div class="ws-menu-page-section ws-plugin--s2member-payment-notifications-section">' . "\n";
242
  echo '<h3>Payment Notification URLs ( optional )</h3>' . "\n";
243
- echo '<p>If you use affiliate software, or have back-office routines that need to be notified whenever payment transactions <em>( including Recurring Payments )</em> take place, you\'ll want to read this section. This is marked `Payment`, because the URLs that you list below, will be notified each time an actual payment occurs. Depending on your fee structure, this may include a first Initial Payment that establishes a Subscription. But more importantly, this will be triggered on all future payments that are received for the lifetime of the Subscription. So unlike the `Signup` Notification, `Payment` Notifications take place whenever actual payments are received, instead of just once after signup is completed. If a payment is required during signup <em>( i.e. no Free Trial is being offered )</em>, a Signup Notification will be triggered, and a Payment Notification will ALSO be triggered. In other words, a Payment Notification occurs anytime funds are received, no matter what. Please note, this feature is not to be confused with the PayPal® IPN service. PayPal® IPN <em>( and other service integrations )</em> are already built into s2Member. They remain active at all times. These Payment Notifications are an added layer of functionality, and they are completely optional.</p>' . "\n";
 
 
 
244
  do_action ("ws_plugin__s2member_during_api_ops_page_during_left_sections_during_payment_notifications", get_defined_vars ());
245
  /**/
246
  echo '<table class="form-table">' . "\n";
@@ -262,14 +269,14 @@ if (!class_exists ("c_ws_plugin__s2member_menu_page_api_ops"))
262
  echo 'Payment Notifications take place silently behind-the-scene, using an HTTP connection.<br /><br />' . "\n";
263
  echo '<strong>You can also use these special Replacement Codes if you need them:</strong>' . "\n";
264
  echo '<ul>' . "\n";
265
- echo '<li><code>%%subscr_id%%</code> = The Paid Subscription ID, which remains constant throughout any &amp; all future payments. [ <a href="#" onclick="alert(\'There is one exception. If you are selling Lifetime or Fixed-Term ( non-recurring ) access, using Buy Now functionality; the %%subscr_id%% is actually set to the Transaction ID for the payment.\\n\\nPayment Gateways do not provide a specific Subscription ID for Buy Now purchases. Since Lifetime &amp; Fixed-Term Subscriptions are NOT recurring ( i.e. there is only ONE payment ), using the Transaction ID as the Subscription ID is a graceful way to deal with this minor conflict.\'); return false;">?</a> ]</li>' . "\n";
266
  echo '<li><code>%%txn_id%%</code> = The Payment Transaction ID, which is always unique for each payment received.</li>' . "\n";
267
  echo '<li><code>%%amount%%</code> = The Amount of the payment. Most affiliate programs calculate commissions from this.</li>' . "\n";
268
- echo '<li><code>%%first_name%%</code> = The First Name of the Customer who purchased the Membership Subscription.</li>' . "\n";
269
- echo '<li><code>%%last_name%%</code> = The Last Name of the Customer who purchased the Membership Subscription.</li>' . "\n";
270
- echo '<li><code>%%full_name%%</code> = The Full Name ( First &amp; Last ) of the Customer who purchased the Membership Subscription.</li>' . "\n";
271
- echo '<li><code>%%payer_email%%</code> = The Email Address of the Customer who purchased the Membership Subscription.</li>' . "\n";
272
- echo '<li><code>%%item_number%%</code> = The Item Number ( colon separated <code><em>level:custom_capabilities:fixed term</em></code> ) that the payment is for.</li>' . "\n";
273
  echo '<li><code>%%item_name%%</code> = The Item Name ( as provided by the <code>desc=""</code> attribute in your Shortcode, which briefly describes the Item Number ).</li>' . "\n";
274
  echo '<li><code>%%user_first_name%%</code> = The First Name listed on their User account. This might be different than what is on file with your Payment Gateway.</li>' . "\n";
275
  echo '<li><code>%%user_last_name%%</code> = The Last Name listed on their User account. This might be different than what is on file with your Payment Gateway.</li>' . "\n";
@@ -342,7 +349,10 @@ if (!class_exists ("c_ws_plugin__s2member_menu_page_api_ops"))
342
  /**/
343
  echo '<div class="ws-menu-page-section ws-plugin--s2member-modification-notifications-section">' . "\n";
344
  echo '<h3>Modification Notification URLs ( optional )</h3>' . "\n";
345
- echo '<p>If you use affiliate software, or have back-office routines that need to be notified whenever a new Subscription is created by an "existing" User/Member, or an "existing" Member modifies their paid Subscription terms, you\'ll want to read this section. This is marked `Modification`, because the URLs that you list below, will be notified each time an "existing" User/Member signs up for a paid Subscription <em>( i.e. a Modification takes place against an existing account )</em>, or an "existing" Member modifies their paid Subscription terms <em>( again, a Modification takes places against an existing account )</em>. Depending on your fee structure, this may include a first Initial Payment that establishes their Subscription. Modification Notifications are sent right after a Member signs up and/or modifies billing terms successfully through your Payment Gateway, regardless of whether any money has actually been transacted initially. In other words, this Notification is triggered, even if you provided them with a 100% Free Trial Period. However, this Notification will NOT be processed for Free Subscribers that register without going through your Payment Gateway at all. In addition, this Notification will NOT be processed for "new" Users/Members <em>( see: Signup Notifications for that scenario )</em>. Please note, this feature is not to be confused with the PayPal® IPN service. PayPal® IPN <em>( and other service integrations )</em> are already built into s2Member. They remain active at all times. These Modification Notifications are an added layer of functionality, and they are completely optional.</p>' . "\n";
 
 
 
346
  do_action ("ws_plugin__s2member_during_api_ops_page_during_left_sections_during_modification_notifications", get_defined_vars ());
347
  /**/
348
  echo '<table class="form-table">' . "\n";
@@ -364,7 +374,7 @@ if (!class_exists ("c_ws_plugin__s2member_menu_page_api_ops"))
364
  echo 'Modification Notifications take place silently behind-the-scene, using an HTTP connection.<br /><br />' . "\n";
365
  echo '<strong>You can also use these special Replacement Codes if you need them:</strong>' . "\n";
366
  echo '<ul>' . "\n";
367
- echo '<li><code>%%subscr_id%%</code> = The Paid Subscription ID, which remains constant throughout any &amp; all future payments. [ <a href="#" onclick="alert(\'There is one exception. If you are selling Lifetime or Fixed-Term ( non-recurring ) access, using Buy Now functionality; the %%subscr_id%% is actually set to the Transaction ID for the purchase.\\n\\nPayment Gateways do not provide a specific Subscription ID for Buy Now purchases. Since Lifetime &amp; Fixed-Term Subscriptions are NOT recurring ( i.e. there is only ONE payment ), using the Transaction ID as the Subscription ID is a graceful way to deal with this minor conflict.\'); return false;">?</a> ]</li>' . "\n";
368
  echo '<li><code>%%initial%%</code> = The Initial Fee charged during signup. If you offered a 100% Free Trial, this will be <code>0</code>. [ <a href="#" onclick="alert(\'This will always represent the amount of money the Customer spent, whenever they initially signed up, no matter what. Even if that amount is 0.\\n\\nIf a Customer signs up, under the terms of a 100% Free Trial Period, this will be 0. So be careful using %%initial%% when you offer a 100% Free Trial Period, because a $0.00 sale amount could cause havoc with affiliate programs.\\n\\nIf you\\\'re offering a 100% Free Trial Period, and you need to track sales through affiliate programs, you can either hard-code an amount; or use `Payment Notifications` instead.\'); return false;">?</a> ]</li>' . "\n";
369
  echo '<li><code>%%regular%%</code> = The Regular Amount of the Subscription. This value is <code>always > 0</code>, no matter what. [ <a href="#" onclick="alert(\'This is how much the Subscription costs after an Initial Period expires. The %%regular%% rate is always > 0. If you did NOT offer an Initial Period at a different price, %%initial%% and %%regular%% will be equal to the same thing.\'); return false;">?</a> ]</li>' . "\n";
370
  echo '<li><code>%%recurring%%</code> = This is the amount that will be charged on a recurring basis, or <code>0</code> if non-recurring. [ <a href="#" onclick="alert(\'If Recurring Payments have not been required, this will be equal to 0. That being said, %%regular%% &amp; %%recurring%% are usually the same value. This variable can be used in two different ways. You can use it to determine what the Regular Recurring Rate is, or to determine whether the Subscription will recur or not. If it is going to recur, %%recurring%% will be > 0.\'); return false;">?</a> ]</li>' . "\n";
@@ -445,9 +455,11 @@ if (!class_exists ("c_ws_plugin__s2member_menu_page_api_ops"))
445
  /**/
446
  echo '<div class="ws-menu-page-section ws-plugin--s2member-cancellation-notifications-section">' . "\n";
447
  echo '<h3>Cancellation Notification URLs ( optional )</h3>' . "\n";
448
- echo '<p>If you use affiliate software, or have back-office routines that need to be notified whenever Subscriptions are cancelled through your Payment Gateway, you\'ll want to read this section. This is marked `Cancellation`, because the URLs that you list below, will be notified each time a Subscription is cancelled. A Cancellation is triggered when you cancel a Customer\'s Subscription through your Payment Gateway, or when a Customer cancels their own Subscription. Please note, this feature is not to be confused with the PayPal® IPN service. PayPal® IPN <em>( and other service integrations )</em> are already built into s2Member. They remain active at all times. These Cancellation Notifications are an added layer of functionality, and they are completely optional.</p>' . "\n";
 
449
  echo '<p><em><strong>*Understanding Cancellations*</strong> It\'s important to realize that a Cancellation is not an EOT ( End Of Term ). All that happens during a Cancellation event, is that billing is stopped, and it\'s understood that the Customer is going to lose access, at some point in the future. This does NOT mean, that access will be revoked immediately. A separate EOT event will automatically handle a (demotion or deletion) later, at the appropriate time; which could be several days, or even a year after the Cancellation took place.</em></p>' . "\n";
450
- echo '<p><em><strong>*Some Hairy Details*</strong> There might be times whenever you notice that a Member\'s Subscription has been cancelled through your Payment Gateway... but, s2Member continues allowing the User access to your site as a paid Member. Please don\'t be confused by this... in 99.9% of these cases, the reason for this is legitimate. s2Member will only remove the User\'s Membership privileges when an EOT ( End Of Term ) is processed, a refund occurs, a chargeback occurs, or when a cancellation occurs - which would later result in a delayed Auto-EOT by s2Member. s2Member will not process an EOT ( End Of Term ) 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";
 
451
  do_action ("ws_plugin__s2member_during_api_ops_page_during_left_sections_during_cancellation_notifications", get_defined_vars ());
452
  /**/
453
  echo '<table class="form-table">' . "\n";
@@ -469,7 +481,7 @@ if (!class_exists ("c_ws_plugin__s2member_menu_page_api_ops"))
469
  echo 'Cancellation Notifications take place silently behind-the-scene, using an HTTP connection.<br /><br />' . "\n";
470
  echo '<strong>You can also use these special Replacement Codes if you need them:</strong>' . "\n";
471
  echo '<ul>' . "\n";
472
- echo '<li><code>%%subscr_id%%</code> = The Paid Subscription ID, which remained constant throughout the lifetime of the Membership. [ <a href="#" onclick="alert(\'There is one exception. If you are selling Lifetime or Fixed-Term ( non-recurring ) access, using Buy Now functionality; the %%subscr_id%% is actually set to the original Transaction ID for the purchase.\\n\\nPayment Gateways do not provide a specific Subscription ID for Buy Now purchases. Since Lifetime &amp; Fixed-Term Subscriptions are NOT recurring ( i.e. there was only ONE payment ), using the Transaction ID as the Subscription ID is a graceful way to deal with this minor conflict.\'); return false;">?</a> ]</li>' . "\n";
473
  echo '<li><code>%%item_number%%</code> = The Item Number ( colon separated <em>level:custom_capabilities:fixed term</em> ) that the Subscription was for.</li>' . "\n";
474
  echo '<li><code>%%item_name%%</code> = The Item Name ( as provided by the <code>desc=""</code> attribute in your Shortcode, which briefly describes the Item Number ).</li>' . "\n";
475
  echo '<li><code>%%user_first_name%%</code> = The First Name listed on their User account. This might be different than what is on file with your Payment Gateway.</li>' . "\n";
@@ -543,9 +555,12 @@ if (!class_exists ("c_ws_plugin__s2member_menu_page_api_ops"))
543
  /**/
544
  echo '<div class="ws-menu-page-section ws-plugin--s2member-eot-deletion-notifications-section">' . "\n";
545
  echo '<h3>EOT/Deletion Notification URLs ( optional )</h3>' . "\n";
546
- echo '<p>If you use affiliate software, or have back-office routines that need to be notified whenever Subscriptions have ended <em>( and a Member is demoted to a Free Subscriber )</em>, or when an account is deleted from the system, you\'ll want to read this section. This is marked `EOT/Deletion`, because the URLs that you list below, will be notified in both cases. EOT = End Of Term. An EOT is triggered <em>immediately</em> when you refund a Customer, when a Customer forces a chargeback to occur, or when a paid Subscription ends naturally <em>( i.e. expires )</em>, and your Payment Gateway sends s2Member an EOT ( End Of Term ) response. Delayed EOTs occur after a Cancellation, either as a result of you cancelling a Customer\'s Subscription, or a Customer cancelling their own Subscription. A Cancellation usually results in a delayed EOT, because a Cancellation does NOT always warrant an immediate action; there could still be time left on their Subscription.</p>' . "\n";
547
- echo '<p>Manual Deletions will trigger an immediate Notification. If you delete an account manually from within your WordPress® Dashboard, your URLs can be notified automatically through this system. So the two events are an EOT and/or a Manual Deletion. Please note, this feature is not to be confused with the PayPal® IPN service. PayPal® IPN <em>( and other service integrations )</em> are already built into s2Member. They remain active at all times. These EOT/Deletion Notifications are an added layer of functionality, and they are completely optional.</p>' . "\n";
548
- echo '<p><em><strong>*Some Hairy Details*</strong> There might be times whenever you notice that a Member\'s Subscription has been cancelled through your Payment Gateway... but, s2Member continues allowing the User access to your site as a paid Member. Please don\'t be confused by this... in 99.9% of these cases, the reason for this is legitimate. s2Member will only remove the User\'s Membership privileges when an EOT ( End Of Term ) is processed, a refund occurs, a chargeback occurs, or when a cancellation occurs - which would later result in a delayed Auto-EOT by s2Member. s2Member will not process an EOT ( End Of Term ) 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";
 
 
 
549
  do_action ("ws_plugin__s2member_during_api_ops_page_during_left_sections_during_eot_deletion_notifications", get_defined_vars ());
550
  /**/
551
  echo '<table class="form-table">' . "\n";
@@ -568,7 +583,7 @@ if (!class_exists ("c_ws_plugin__s2member_menu_page_api_ops"))
568
  echo '<strong>You can also use these special Replacement Codes if you need them:</strong>' . "\n";
569
  echo '<ul>' . "\n";
570
  echo '<li><code>%%eot_del_type%%</code> = The type of event that triggered this Notification. [ <a href="#" onclick="alert(\'List of possible values:\\n\\nuser-removal-deletion ( i.e. manual removal/deletion )\\nauto-eot-cancellation-expiration-demotion\\nauto-eot-cancellation-expiration-deletion\\nipn-cancellation-expiration-demotion\\nipn-cancellation-expiration-deletion\\nipn-refund-reversal-demotion\\nipn-refund-reversal-deletion\'); return false;">list of possible values</a> ]</li>' . "\n";
571
- echo '<li><code>%%subscr_id%%</code> = The Paid Subscription ID, which remained constant throughout the lifetime of the Membership. [ <a href="#" onclick="alert(\'There is one exception. If you are selling Lifetime or Fixed-Term ( non-recurring ) access, using Buy Now functionality; the %%subscr_id%% is actually set to the original Transaction ID for the purchase.\\n\\nPayment Gateways do not provide a specific Subscription ID for Buy Now purchases. Since Lifetime &amp; Fixed-Term Subscriptions are NOT recurring ( i.e. there was only ONE payment ), using the Transaction ID as the Subscription ID is a graceful way to deal with this minor conflict.\'); return false;">?</a> ]</li>' . "\n";
572
  echo '<li><code>%%user_first_name%%</code> = The First Name listed on their User account. This might be different than what is on file with your Payment Gateway.</li>' . "\n";
573
  echo '<li><code>%%user_last_name%%</code> = The Last Name listed on their User account. This might be different than what is on file with your Payment Gateway.</li>' . "\n";
574
  echo '<li><code>%%user_full_name%%</code> = The Full Name listed on their User account. This might be different than what is on file with your Payment Gateway.</li>' . "\n";
@@ -640,8 +655,10 @@ if (!class_exists ("c_ws_plugin__s2member_menu_page_api_ops"))
640
  /**/
641
  echo '<div class="ws-menu-page-section ws-plugin--s2member-refund-reversal-notifications-section">' . "\n";
642
  echo '<h3>Refund/Reversal Notification URLs ( optional )</h3>' . "\n";
643
- echo '<p>If you use affiliate software, or have back-office routines that need to be notified whenever Subscriptions have been refunded or reversed <em>( i.e. charged back to you )</em>, you\'ll want to read this section. This is marked `Refund/Reversal`, because the URLs that you list below, will ONLY be notified in those specific cases, as opposed to the EOT Notifications, which are all-inclusive. This is very similar to the EOT/Deletion described above. But, there is an important distinction. EOT includes cancellations, expirations, failed payments, refunds, chargebacks, etc, etc. In other words, ANY time a deletion or End Of Term action takes place.</p>' . "\n";
644
- echo '<p>So the distinction is that Refund/Reversal Notifications are ONLY sent under two specific circumstances: 1. You log into your Payment Gateway and refund a payment that is associated with a Subscription. 2. The Customer complains to your Payment Gateway and a chargeback occurs, forcing a Reversal. In both of these cases, an EOT/Deletion Notification will be sent <em>( as described in the previous section )</em>, but since EOT/Deletion is a broader Notification, these Refund/Reversal Notifications are here so you can nail down specific back-office operations in these two specific scenarios. Please note, this feature is not to be confused with the PayPal® IPN service. PayPal® IPN <em>( and other service integrations )</em> are already built into s2Member. They remain active at all times. These Refund/Reversal Notifications are an added layer of functionality, and they are completely optional.</p>' . "\n";
 
 
645
  do_action ("ws_plugin__s2member_during_api_ops_page_during_left_sections_during_refund_reversal_notifications", get_defined_vars ());
646
  /**/
647
  echo '<table class="form-table">' . "\n";
@@ -663,7 +680,7 @@ if (!class_exists ("c_ws_plugin__s2member_menu_page_api_ops"))
663
  echo 'Refund/Reversal Notifications take place silently behind-the-scene, using an HTTP connection.<br /><br />' . "\n";
664
  echo '<strong>You can also use these special Replacement Codes if you need them:</strong>' . "\n";
665
  echo '<ul>' . "\n";
666
- echo '<li><code>%%subscr_id%%</code> = The Paid Subscription ID, which remained constant throughout the lifetime of the Membership. [ <a href="#" onclick="alert(\'There is one exception. If you are selling Lifetime or Fixed-Term ( non-recurring ) access, using Buy Now functionality; the %%subscr_id%% is actually set to the original Transaction ID for the purchase.\\n\\nPayment Gateways do not provide a specific Subscription ID for Buy Now purchases. Since Lifetime &amp; Fixed-Term Subscriptions are NOT recurring ( i.e. there was only ONE payment ), using the Transaction ID as the Subscription ID is a graceful way to deal with this minor conflict.\'); return false;">?</a> ]</li>' . "\n";
667
  echo '<li><code>%%parent_txn_id%%</code> = The Parent Transaction ID, associated with the original payment being refunded/reversed.</li>' . "\n";
668
  echo '<li><code>%%-amount%%</code> = The Negative Amount of the payment, that was refunded or reversed back to the Customer.</li>' . "\n";
669
  echo '<li><code>%%-fee%%</code> = The Negative Payment Gateway fee, that was refunded back to you as the Merchant/Seller.</li>' . "\n";
@@ -739,7 +756,9 @@ if (!class_exists ("c_ws_plugin__s2member_menu_page_api_ops"))
739
  /**/
740
  echo '<div class="ws-menu-page-section ws-plugin--s2member-sp-sale-notifications-section">' . "\n";
741
  echo '<h3>Specific Post/Page ~ Sale Notification URLs ( optional )</h3>' . "\n";
742
- echo '<p>If you use affiliate software, or have back-office routines that need to be notified whenever Specific Post/Page sales take place, you\'ll want to read this section. This is marked `Specific Post/Page`, because the URLs that you list below, will be notified each time a payment occurs, on a sale providing access to a Specific Post/Page. This is one of only TWO Notifications that are sent for Specific Post/Page Access <em>( i.e. this one, and another below - for Refunds/Reversals )</em>. All of the other API Notifications are designed for Membership Level Access. Please note, this feature is not to be confused with the PayPal® IPN service. PayPal® IPN <em>( and other service integrations )</em> are already built into s2Member. They remain active at all times. These Sale Notifications are an added layer of functionality, and they are completely optional.</p>' . "\n";
 
 
743
  do_action ("ws_plugin__s2member_during_api_ops_page_during_left_sections_during_sp_sale_notifications", get_defined_vars ());
744
  /**/
745
  echo '<table class="form-table">' . "\n";
@@ -828,7 +847,9 @@ if (!class_exists ("c_ws_plugin__s2member_menu_page_api_ops"))
828
  /**/
829
  echo '<div class="ws-menu-page-section ws-plugin--s2member-sp-refund-reversal-notifications-section">' . "\n";
830
  echo '<h3>Specific Post/Page ~ Refund/Reversal Notification URLs ( optional )</h3>' . "\n";
831
- echo '<p>If you use affiliate software, or have back-office routines that need to be notified whenever sales have been refunded or reversed <em>( i.e. charged back to you )</em>, you\'ll want to read this section. This is marked `Specific Post/Page`, because the URLs that you list below, will be notified each time a Refund or Reversal occurs, on a sale that provided access to a Specific Post/Page. This is one of ONLY two Notifications that are sent for Specific Post/Page Access <em>( i.e. this one, and another above - for Sales )</em>. All of the other API Notifications are designed for Membership Level Access. Please note, this feature is not to be confused with the PayPal® IPN service. PayPal® IPN <em>( and other service integrations )</em> are already built into s2Member. They remain active at all times. These Refund/Reversal Notifications are an added layer of functionality, and they are completely optional.</p>' . "\n";
 
 
832
  do_action ("ws_plugin__s2member_during_api_ops_page_during_left_sections_during_sp_refund_reversal_notifications", get_defined_vars ());
833
  /**/
834
  echo '<table class="form-table">' . "\n";
53
  /**/
54
  echo '<div class="ws-menu-page-section ws-plugin--s2member-signup-notifications-section">' . "\n";
55
  echo '<h3>Signup Notification URLs ( optional )</h3>' . "\n";
56
+ echo '<p>If you use affiliate software, or have back-office routines that need to be notified whenever a new Subscription is created, you\'ll want to read this section. This is marked `Signup`, because the URLs that you list below, will be notified each time a "new", "paying" Member, signs up. Depending on your fee structure, this may include a first Initial Payment that establishes their Subscription, or it may not. This Notification will only be triggered once for each Member. Signup Notifications are sent right after a "new", "paying" Member, signs up successfully through your Payment Gateway, regardless of whether any money has actually been transacted initially. In other words, this Notification is triggered anytime a "new", "paying" Member, signs up through your Payment Gateway, even if you provided them with a 100% Free Trial Period <em>( e.g. no money is being transacted intially )</em>.</p>' . "\n";
57
+ echo '<p>This Notification will NOT be processed for Free Subscribers that register without going through your Payment Gateway at all. This Notification will NOT be processed when an "existing" User/Member pays for a new Subscription <em>( see: Modification Notifications for that scenario )</em>.' . ((is_multisite () && c_ws_plugin__s2member_utils_conds::is_multisite_farm () && !is_main_site ()) ? '' : ' And, this Notification will NOT be processed on Buy Now transactions for Independent Custom Capabilities <em>( see: Payment Notifications for that scenario )</em>.') . '</p>' . "\n";
58
+ echo '<p>Please note, this feature is not to be confused with the PayPal® IPN service. PayPal® IPN <em>( and other service integrations )</em> are already built into s2Member. They remain active at all times. These Signup Notifications are an added layer of functionality, and they are completely optional.</p>' . "\n";
59
  do_action ("ws_plugin__s2member_during_api_ops_page_during_left_sections_during_signup_notifications", get_defined_vars ());
60
  /**/
61
  echo '<table class="form-table">' . "\n";
77
  echo 'Signup Notifications take place silently behind-the-scene, using an HTTP connection.<br /><br />' . "\n";
78
  echo '<strong>You can also use these special Replacement Codes if you need them:</strong>' . "\n";
79
  echo '<ul>' . "\n";
80
+ echo '<li><code>%%subscr_id%%</code> = The Paid Subscription ID, which remains constant throughout any &amp; all future payments. [ <a href="#" onclick="alert(\'There is one exception. If you are selling Lifetime or Fixed-Term ( non-recurring ) access, using Buy Now functionality; the %%subscr_id%% is actually set to the Transaction ID for the purchase. Payment Gateways do not provide a specific Subscription ID for Buy Now purchases. Since Lifetime &amp; Fixed-Term Subscriptions are NOT recurring ( i.e. there is only ONE payment ), using the Transaction ID as the Subscription ID is a graceful way to deal with this minor conflict.\'); return false;">?</a> ]</li>' . "\n";
81
  echo '<li><code>%%initial%%</code> = The Initial Fee charged during signup. If you offered a 100% Free Trial, this will be <code>0</code>. [ <a href="#" onclick="alert(\'This will always represent the amount of money the Customer spent, whenever they initially signed up, no matter what. Even if that amount is 0.\\n\\nIf a Customer signs up, under the terms of a 100% Free Trial Period, this will be 0. So be careful using %%initial%% when you offer a 100% Free Trial Period, because a $0.00 sale amount could cause havoc with affiliate programs.\\n\\nIf you\\\'re offering a 100% Free Trial Period, and you need to track sales through affiliate programs, you can either hard-code an amount; or use `Payment Notifications` instead.\'); return false;">?</a> ]</li>' . "\n";
82
  echo '<li><code>%%regular%%</code> = The Regular Amount of the Subscription. This value is <code>always > 0</code>, no matter what. [ <a href="#" onclick="alert(\'This is how much the Subscription costs after an Initial Period expires. The %%regular%% rate is always > 0. If you did NOT offer an Initial Period at a different price, %%initial%% and %%regular%% will be equal to the same thing.\'); return false;">?</a> ]</li>' . "\n";
83
  echo '<li><code>%%recurring%%</code> = This is the amount that will be charged on a recurring basis, or <code>0</code> if non-recurring. [ <a href="#" onclick="alert(\'If Recurring Payments have not been required, this will be equal to 0. That being said, %%regular%% &amp; %%recurring%% are usually the same value. This variable can be used in two different ways. You can use it to determine what the Regular Recurring Rate is, or to determine whether the Subscription will recur or not. If it is going to recur, %%recurring%% will be > 0.\'); return false;">?</a> ]</li>' . "\n";
144
  /**/
145
  echo '<div class="ws-menu-page-section ws-plugin--s2member-registration-notifications-section">' . "\n";
146
  echo '<h3>Registration Notification URLs ( optional )</h3>' . "\n";
147
+ echo '<p>If you use affiliate software, or have back-office routines that need to be notified whenever a "new" Member is created, you\'ll want to read this section. This is marked `Registration`, because the URLs that you list below, will be notified each time a "new" Member registers a Username. This is usually triggered right after a `Signup` Notification; at the point in which a "new" Member successfully completes the Registration form, and they are assigned a Username.</p>' . "\n";
148
+ echo '<p>This Notification is ALSO triggered whenever you create a "new" User inside your WordPress® Dashboard.</p>' . "\n";
149
+ echo '<p>Please note, this feature is not to be confused with the PayPal® IPN service. PayPal® IPN <em>( and other service integrations )</em> are already built into s2Member. They remain active at all times. These Registration Notifications are an added layer of functionality, and they are completely optional.</p>' . "\n";
150
  do_action ("ws_plugin__s2member_during_api_ops_page_during_left_sections_during_registration_notifications", get_defined_vars ());
151
  /**/
152
  echo '<table class="form-table">' . "\n";
244
  /**/
245
  echo '<div class="ws-menu-page-section ws-plugin--s2member-payment-notifications-section">' . "\n";
246
  echo '<h3>Payment Notification URLs ( optional )</h3>' . "\n";
247
+ echo '<p>If you use affiliate software, or have back-office routines that need to be notified whenever payment transactions <em>( including Recurring Payments )</em> take place, you\'ll want to read this section. This is marked `Payment`, because the URLs that you list below, will be notified each time an actual payment occurs. Depending on your fee structure, this may include a first Initial Payment that establishes a Subscription. But more importantly, this will be triggered on all future payments that are received for the lifetime of the Subscription.</p>' . "\n";
248
+ echo '<p>So, unlike the `Signup` Notification, `Payment` Notifications take place whenever actual payments are received, instead of just once after signup is completed. If a payment is required during signup <em>( i.e. no Free Trial is being offered )</em>, a Signup Notification will be triggered, and a Payment Notification will ALSO be triggered. In other words, a Payment Notification occurs anytime funds are received, no matter what.</p>' . "\n";
249
+ echo (!is_multisite () || !c_ws_plugin__s2member_utils_conds::is_multisite_farm () || is_main_site ()) ? '<p>Payment Notifications are also triggered whenever a Buy Now purchase for Independent Custom Capabilities takes place.</p>' . "\n" : '';
250
+ echo '<p>Please note, this feature is not to be confused with the PayPal® IPN service. PayPal® IPN <em>( and other service integrations )</em> are already built into s2Member. They remain active at all times. These Payment Notifications are an added layer of functionality, and they are completely optional.</p>' . "\n";
251
  do_action ("ws_plugin__s2member_during_api_ops_page_during_left_sections_during_payment_notifications", get_defined_vars ());
252
  /**/
253
  echo '<table class="form-table">' . "\n";
269
  echo 'Payment Notifications take place silently behind-the-scene, using an HTTP connection.<br /><br />' . "\n";
270
  echo '<strong>You can also use these special Replacement Codes if you need them:</strong>' . "\n";
271
  echo '<ul>' . "\n";
272
+ echo '<li><code>%%subscr_id%%</code> = The Paid Subscription ID, which remains constant throughout any &amp; all future payments. [ <a href="#" onclick="alert(\'There are some exceptions. If you are selling Lifetime or Fixed-Term ( non-recurring ) access, and/or Independent Custom Capabilities, using Buy Now functionality; the %%subscr_id%% is actually set to the Transaction ID for the payment.\\n\\nPayment Gateways do not provide a specific Subscription ID for Buy Now purchases. Since Lifetime &amp; Fixed-Term Subscriptions are NOT recurring ( i.e. there is only ONE payment ), which goes for Independent Custom Capability purchases too; using the Transaction ID as the Subscription ID is a graceful way to deal with this minor conflict.\'); return false;">?</a> ]</li>' . "\n";
273
  echo '<li><code>%%txn_id%%</code> = The Payment Transaction ID, which is always unique for each payment received.</li>' . "\n";
274
  echo '<li><code>%%amount%%</code> = The Amount of the payment. Most affiliate programs calculate commissions from this.</li>' . "\n";
275
+ echo '<li><code>%%first_name%%</code> = The First Name of the Customer who purchased the Membership Subscription' . ((is_multisite () && c_ws_plugin__s2member_utils_conds::is_multisite_farm () && !is_main_site ()) ? '' : ' or Capabilities.') . '</li>' . "\n";
276
+ echo '<li><code>%%last_name%%</code> = The Last Name of the Customer who purchased the Membership Subscription' . ((is_multisite () && c_ws_plugin__s2member_utils_conds::is_multisite_farm () && !is_main_site ()) ? '' : ' or Capabilities.') . '</li>' . "\n";
277
+ echo '<li><code>%%full_name%%</code> = The Full Name ( First &amp; Last ) of the Customer who purchased the Membership Subscription' . ((is_multisite () && c_ws_plugin__s2member_utils_conds::is_multisite_farm () && !is_main_site ()) ? '' : ' or Capabilities.') . '</li>' . "\n";
278
+ echo '<li><code>%%payer_email%%</code> = The Email Address of the Customer who purchased the Membership Subscription' . ((is_multisite () && c_ws_plugin__s2member_utils_conds::is_multisite_farm () && !is_main_site ()) ? '' : ' or Capabilities.') . '</li>' . "\n";
279
+ echo '<li><code>%%item_number%%</code> = The Item Number ( colon separated <code><em>level:custom_capabilities:fixed term</em></code> ) that the payment is for.' . ((is_multisite () && c_ws_plugin__s2member_utils_conds::is_multisite_farm () && !is_main_site ()) ? '' : ' [ <a href="#" onclick="alert(\'If the Payment Notification is for Independent Custom Capabilities, the `level` portion of this string will be an asterisk ( `*` ), since the Membership Level is irrelevant, and remains `as it was` in that scenario. In all other cases, the `level` portion will be a numeric value.\'); return false;">?</a> ]') . '</li>' . "\n";
280
  echo '<li><code>%%item_name%%</code> = The Item Name ( as provided by the <code>desc=""</code> attribute in your Shortcode, which briefly describes the Item Number ).</li>' . "\n";
281
  echo '<li><code>%%user_first_name%%</code> = The First Name listed on their User account. This might be different than what is on file with your Payment Gateway.</li>' . "\n";
282
  echo '<li><code>%%user_last_name%%</code> = The Last Name listed on their User account. This might be different than what is on file with your Payment Gateway.</li>' . "\n";
349
  /**/
350
  echo '<div class="ws-menu-page-section ws-plugin--s2member-modification-notifications-section">' . "\n";
351
  echo '<h3>Modification Notification URLs ( optional )</h3>' . "\n";
352
+ echo '<p>If you use affiliate software, or have back-office routines that need to be notified each time a new Subscription is created by an "existing" User/Member, or an "existing" Member modifies their paid Subscription terms, you\'ll want to read this section. This is marked `Modification`, because the URLs that you list below, will be notified each time an "existing" User/Member <em>( even if they are/were a Free Subscriber )</em> signs up for a paid Subscription <em>( i.e. a Modification takes place against an existing account within WordPress® )</em>, or an "existing" Member modifies their paid Subscription terms <em>( again, a Modification takes places against an existing account within WordPress® )</em>. Depending on your fee structure, this may include a first Initial Payment that establishes their Subscription, or it may not.</p>' . "\n";
353
+ echo '<p>Modification Notifications are sent right after a Member signs up and/or modifies billing terms successfully through your Payment Gateway, regardless of whether any money has actually been transacted initially. In other words, this Notification is triggered, even if you provided them with a 100% Free Trial Period <em>( e.g. no money is being transacted intially )</em>.</p>' . "\n";
354
+ echo '<p>This Notification will NOT be processed for Free Subscribers that register without going through your Payment Gateway at all. This Notification will NOT be processed for "new" Users/Members <em>( see: Signup Notifications for that scenario )</em>.' . ((is_multisite () && c_ws_plugin__s2member_utils_conds::is_multisite_farm () && !is_main_site ()) ? '' : ' And, this Notification will NOT be processed for Independent Custom Capability purchases <em>( see: Payment Notifications for that scenario )</em>.') . '</p>' . "\n";
355
+ echo '<p>Please note, this feature is not to be confused with the PayPal® IPN service. PayPal® IPN <em>( and other service integrations )</em> are already built into s2Member. They remain active at all times. These Modification Notifications are an added layer of functionality, and they are completely optional.</p>' . "\n";
356
  do_action ("ws_plugin__s2member_during_api_ops_page_during_left_sections_during_modification_notifications", get_defined_vars ());
357
  /**/
358
  echo '<table class="form-table">' . "\n";
374
  echo 'Modification Notifications take place silently behind-the-scene, using an HTTP connection.<br /><br />' . "\n";
375
  echo '<strong>You can also use these special Replacement Codes if you need them:</strong>' . "\n";
376
  echo '<ul>' . "\n";
377
+ echo '<li><code>%%subscr_id%%</code> = The Paid Subscription ID, which remains constant throughout any &amp; all future payments. [ <a href="#" onclick="alert(\'There is one exception. If you are selling Lifetime or Fixed-Term ( non-recurring ) access, using Buy Now functionality; the %%subscr_id%% is actually set to the Transaction ID for the purchase. Payment Gateways do not provide a specific Subscription ID for Buy Now purchases. Since Lifetime &amp; Fixed-Term Subscriptions are NOT recurring ( i.e. there is only ONE payment ), using the Transaction ID as the Subscription ID is a graceful way to deal with this minor conflict.\'); return false;">?</a> ]</li>' . "\n";
378
  echo '<li><code>%%initial%%</code> = The Initial Fee charged during signup. If you offered a 100% Free Trial, this will be <code>0</code>. [ <a href="#" onclick="alert(\'This will always represent the amount of money the Customer spent, whenever they initially signed up, no matter what. Even if that amount is 0.\\n\\nIf a Customer signs up, under the terms of a 100% Free Trial Period, this will be 0. So be careful using %%initial%% when you offer a 100% Free Trial Period, because a $0.00 sale amount could cause havoc with affiliate programs.\\n\\nIf you\\\'re offering a 100% Free Trial Period, and you need to track sales through affiliate programs, you can either hard-code an amount; or use `Payment Notifications` instead.\'); return false;">?</a> ]</li>' . "\n";
379
  echo '<li><code>%%regular%%</code> = The Regular Amount of the Subscription. This value is <code>always > 0</code>, no matter what. [ <a href="#" onclick="alert(\'This is how much the Subscription costs after an Initial Period expires. The %%regular%% rate is always > 0. If you did NOT offer an Initial Period at a different price, %%initial%% and %%regular%% will be equal to the same thing.\'); return false;">?</a> ]</li>' . "\n";
380
  echo '<li><code>%%recurring%%</code> = This is the amount that will be charged on a recurring basis, or <code>0</code> if non-recurring. [ <a href="#" onclick="alert(\'If Recurring Payments have not been required, this will be equal to 0. That being said, %%regular%% &amp; %%recurring%% are usually the same value. This variable can be used in two different ways. You can use it to determine what the Regular Recurring Rate is, or to determine whether the Subscription will recur or not. If it is going to recur, %%recurring%% will be > 0.\'); return false;">?</a> ]</li>' . "\n";
455
  /**/
456
  echo '<div class="ws-menu-page-section ws-plugin--s2member-cancellation-notifications-section">' . "\n";
457
  echo '<h3>Cancellation Notification URLs ( optional )</h3>' . "\n";
458
+ echo '<p>If you use affiliate software, or have back-office routines that need to be notified whenever Subscriptions are cancelled through your Payment Gateway, you\'ll want to read this section. This is marked `Cancellation`, because the URLs that you list below, will be notified each time a Subscription is cancelled. A Cancellation is triggered when you cancel a Customer\'s Subscription through your Payment Gateway, or when a Customer cancels their own Subscription.</p>' . "\n";
459
+ echo '<p>Please note, this feature is not to be confused with the PayPal® IPN service. PayPal® IPN <em>( and other service integrations )</em> are already built into s2Member. They remain active at all times. These Cancellation Notifications are an added layer of functionality, and they are completely optional.</p>' . "\n";
460
  echo '<p><em><strong>*Understanding Cancellations*</strong> It\'s important to realize that a Cancellation is not an EOT ( End Of Term ). All that happens during a Cancellation event, is that billing is stopped, and it\'s understood that the Customer is going to lose access, at some point in the future. This does NOT mean, that access will be revoked immediately. A separate EOT event will automatically handle a (demotion or deletion) later, at the appropriate time; which could be several days, or even a year after the Cancellation took place.</em></p>' . "\n";
461
+ echo '<p><em><strong>*Some Hairy Details*</strong> There might be times whenever you notice that a Member\'s Subscription has been cancelled through your Payment Gateway... but, s2Member continues allowing the User access to your site as a paid Member. Please don\'t be confused by this... in 99.9% of these cases, the reason for this is legitimate. s2Member will only remove the User\'s Membership privileges when an EOT ( End Of Term ) is processed, a refund occurs, a chargeback occurs, or when a cancellation occurs - which would later result in a delayed Auto-EOT by s2Member.</em></p>' . "\n";
462
+ echo '<p><em>s2Member will not process an EOT ( End Of Term ) 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";
463
  do_action ("ws_plugin__s2member_during_api_ops_page_during_left_sections_during_cancellation_notifications", get_defined_vars ());
464
  /**/
465
  echo '<table class="form-table">' . "\n";
481
  echo 'Cancellation Notifications take place silently behind-the-scene, using an HTTP connection.<br /><br />' . "\n";
482
  echo '<strong>You can also use these special Replacement Codes if you need them:</strong>' . "\n";
483
  echo '<ul>' . "\n";
484
+ echo '<li><code>%%subscr_id%%</code> = The Paid Subscription ID, which remained constant throughout the lifetime of the Membership. [ <a href="#" onclick="alert(\'There is one exception. If you are selling Lifetime or Fixed-Term ( non-recurring ) access, using Buy Now functionality; the %%subscr_id%% is actually set to the original Transaction ID for the purchase. Payment Gateways do not provide a specific Subscription ID for Buy Now purchases. Since Lifetime &amp; Fixed-Term Subscriptions are NOT recurring ( i.e. there was only ONE payment ), using the Transaction ID as the Subscription ID is a graceful way to deal with this minor conflict.\'); return false;">?</a> ]</li>' . "\n";
485
  echo '<li><code>%%item_number%%</code> = The Item Number ( colon separated <em>level:custom_capabilities:fixed term</em> ) that the Subscription was for.</li>' . "\n";
486
  echo '<li><code>%%item_name%%</code> = The Item Name ( as provided by the <code>desc=""</code> attribute in your Shortcode, which briefly describes the Item Number ).</li>' . "\n";
487
  echo '<li><code>%%user_first_name%%</code> = The First Name listed on their User account. This might be different than what is on file with your Payment Gateway.</li>' . "\n";
555
  /**/
556
  echo '<div class="ws-menu-page-section ws-plugin--s2member-eot-deletion-notifications-section">' . "\n";
557
  echo '<h3>EOT/Deletion Notification URLs ( optional )</h3>' . "\n";
558
+ echo '<p>If you use affiliate software, or have back-office routines that need to be notified whenever Subscriptions have ended <em>( and a Member is demoted to a Free Subscriber )</em>, or when an account is deleted from the system, you\'ll want to read this section. This is marked `EOT/Deletion`, because the URLs that you list below, will be notified in both cases.</p>' . "\n";
559
+ echo '<p><strong>EOT = End Of Term.</strong> An EOT is triggered <em>immediately</em> when you refund a Customer, when a Customer forces a chargeback to occur, or when a paid Subscription ends naturally <em>( i.e. expires )</em>, and your Payment Gateway sends s2Member an EOT ( End Of Term ) response. Delayed EOTs occur after a Cancellation, either as a result of you cancelling a Customer\'s Subscription, or a Customer cancelling their own Subscription. A Cancellation usually results in a delayed EOT, because a Cancellation does NOT always warrant an immediate action; there could still be time left on their Subscription.</p>' . "\n";
560
+ echo '<p>Manual Deletions will trigger this Notification too. If you delete an account manually from within your WordPress® Dashboard, your URLs can be notified automatically through this API Notification, and this scenario can be detected through the Replacement Code <code>%%eot_del_type%%</code>, which is documented below. So the two events are an EOT <em>( of any kind )</em> and/or a Manual Deletion.</p>' . "\n";
561
+ echo '<p>Please note, this feature is not to be confused with the PayPal® IPN service. PayPal® IPN <em>( and other service integrations )</em> are already built into s2Member. They remain active at all times. These EOT/Deletion Notifications are an added layer of functionality, and they are completely optional.</p>' . "\n";
562
+ echo '<p><em><strong>*Some Hairy Details*</strong> There might be times whenever you notice that a Member\'s Subscription has been cancelled through your Payment Gateway... but, s2Member continues allowing the User access to your site as a paid Member. Please don\'t be confused by this... in 99.9% of these cases, the reason for this is legitimate. s2Member will only remove the User\'s Membership privileges when an EOT ( End Of Term ) is processed, a refund occurs, a chargeback occurs, or when a cancellation occurs - which would later result in a delayed Auto-EOT by s2Member.</em></p>' . "\n";
563
+ echo '<p><em>s2Member will not process an EOT ( End Of Term ) 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";
564
  do_action ("ws_plugin__s2member_during_api_ops_page_during_left_sections_during_eot_deletion_notifications", get_defined_vars ());
565
  /**/
566
  echo '<table class="form-table">' . "\n";
583
  echo '<strong>You can also use these special Replacement Codes if you need them:</strong>' . "\n";
584
  echo '<ul>' . "\n";
585
  echo '<li><code>%%eot_del_type%%</code> = The type of event that triggered this Notification. [ <a href="#" onclick="alert(\'List of possible values:\\n\\nuser-removal-deletion ( i.e. manual removal/deletion )\\nauto-eot-cancellation-expiration-demotion\\nauto-eot-cancellation-expiration-deletion\\nipn-cancellation-expiration-demotion\\nipn-cancellation-expiration-deletion\\nipn-refund-reversal-demotion\\nipn-refund-reversal-deletion\'); return false;">list of possible values</a> ]</li>' . "\n";
586
+ echo '<li><code>%%subscr_id%%</code> = The Paid Subscription ID, which remained constant throughout the lifetime of the Membership. [ <a href="#" onclick="alert(\'There is one exception. If you are selling Lifetime or Fixed-Term ( non-recurring ) access, using Buy Now functionality; the %%subscr_id%% is actually set to the original Transaction ID for the purchase. Payment Gateways do not provide a specific Subscription ID for Buy Now purchases. Since Lifetime &amp; Fixed-Term Subscriptions are NOT recurring ( i.e. there was only ONE payment ), using the Transaction ID as the Subscription ID is a graceful way to deal with this minor conflict.\'); return false;">?</a> ]</li>' . "\n";
587
  echo '<li><code>%%user_first_name%%</code> = The First Name listed on their User account. This might be different than what is on file with your Payment Gateway.</li>' . "\n";
588
  echo '<li><code>%%user_last_name%%</code> = The Last Name listed on their User account. This might be different than what is on file with your Payment Gateway.</li>' . "\n";
589
  echo '<li><code>%%user_full_name%%</code> = The Full Name listed on their User account. This might be different than what is on file with your Payment Gateway.</li>' . "\n";
655
  /**/
656
  echo '<div class="ws-menu-page-section ws-plugin--s2member-refund-reversal-notifications-section">' . "\n";
657
  echo '<h3>Refund/Reversal Notification URLs ( optional )</h3>' . "\n";
658
+ echo '<p>If you use affiliate software, or have back-office routines that need to be notified whenever Subscriptions have been refunded or reversed <em>( i.e. charged back to you )</em>, you\'ll want to read this section. This is marked `Refund/Reversal`, because the URLs that you list below, will ONLY be notified in those specific cases, as opposed to EOT/Deletion Notifications, which are all-inclusive.</p>' . "\n";
659
+ echo '<p>This is very similar to the EOT/Deletion Notification described above. However, there is an important distinction. The all-inclusive EOT/Deletion Notification includes cancellations, expirations, failed payments, refunds, chargebacks, and even manual deletions by the Administrator from within the Dashboard. In other words, EOT/Deletion Notifications are processed ANY time a deletion or End Of Term action takes place. This API Notification, that is, Refund/Reversal Notifications, do NOT include all of those scenarios.</p>' . "\n";
660
+ echo '<p>So the distinction is that Refund/Reversal Notifications are ONLY sent under two specific circumstances: 1. You log into your Payment Gateway and refund a payment that is associated with a Subscription. 2. The Customer complains to your Payment Gateway and a chargeback occurs, forcing a Reversal. In both of these cases, an EOT/Deletion Notification will be sent <em>( as described in the previous section )</em>, but since EOT/Deletion is a broader Notification, these Refund/Reversal Notifications are here so you can nail down specific back-office operations in these two specific scenarios.</p>' . "\n";
661
+ echo '<p>Please note, this feature is not to be confused with the PayPal® IPN service. PayPal® IPN <em>( and other service integrations )</em> are already built into s2Member. They remain active at all times. These Refund/Reversal Notifications are an added layer of functionality, and they are completely optional.</p>' . "\n";
662
  do_action ("ws_plugin__s2member_during_api_ops_page_during_left_sections_during_refund_reversal_notifications", get_defined_vars ());
663
  /**/
664
  echo '<table class="form-table">' . "\n";
680
  echo 'Refund/Reversal Notifications take place silently behind-the-scene, using an HTTP connection.<br /><br />' . "\n";
681
  echo '<strong>You can also use these special Replacement Codes if you need them:</strong>' . "\n";
682
  echo '<ul>' . "\n";
683
+ echo '<li><code>%%subscr_id%%</code> = The Paid Subscription ID, which remained constant throughout the lifetime of the Membership. [ <a href="#" onclick="alert(\'There is one exception. If you are selling Lifetime or Fixed-Term ( non-recurring ) access, using Buy Now functionality; the %%subscr_id%% is actually set to the original Transaction ID for the purchase. Payment Gateways do not provide a specific Subscription ID for Buy Now purchases. Since Lifetime &amp; Fixed-Term Subscriptions are NOT recurring ( i.e. there was only ONE payment ), using the Transaction ID as the Subscription ID is a graceful way to deal with this minor conflict.\'); return false;">?</a> ]</li>' . "\n";
684
  echo '<li><code>%%parent_txn_id%%</code> = The Parent Transaction ID, associated with the original payment being refunded/reversed.</li>' . "\n";
685
  echo '<li><code>%%-amount%%</code> = The Negative Amount of the payment, that was refunded or reversed back to the Customer.</li>' . "\n";
686
  echo '<li><code>%%-fee%%</code> = The Negative Payment Gateway fee, that was refunded back to you as the Merchant/Seller.</li>' . "\n";
756
  /**/
757
  echo '<div class="ws-menu-page-section ws-plugin--s2member-sp-sale-notifications-section">' . "\n";
758
  echo '<h3>Specific Post/Page ~ Sale Notification URLs ( optional )</h3>' . "\n";
759
+ echo '<p>If you use affiliate software, or have back-office routines that need to be notified whenever Specific Post/Page sales take place, you\'ll want to read this section. This is marked `Specific Post/Page`, because the URLs that you list below, will be notified each time a payment occurs, on a sale providing access to a Specific Post/Page.</p>' . "\n";
760
+ echo '<p>This is one of only two API Notifications that are sent for Specific Post/Page Access <em>( i.e. this one, and another below, for Refunds/Reversals )</em>. All of the other API Notifications are designed for Membership Level Access' . ((is_multisite () && c_ws_plugin__s2member_utils_conds::is_multisite_farm () && !is_main_site ()) ? '' : ' and Independent Custom Capabilities') . '. None of the other API Notifications will ever be processed for Specific Post/Page Access. If you intend to respond to events related to Specific Post/Page Access, you MUST use one of the two API Notifications specifically geared to Post/Page Access.</p>' . "\n";
761
+ echo '<p>Please note, this feature is not to be confused with the PayPal® IPN service. PayPal® IPN <em>( and other service integrations )</em> are already built into s2Member. They remain active at all times. These Sale Notifications are an added layer of functionality, and they are completely optional.</p>' . "\n";
762
  do_action ("ws_plugin__s2member_during_api_ops_page_during_left_sections_during_sp_sale_notifications", get_defined_vars ());
763
  /**/
764
  echo '<table class="form-table">' . "\n";
847
  /**/
848
  echo '<div class="ws-menu-page-section ws-plugin--s2member-sp-refund-reversal-notifications-section">' . "\n";
849
  echo '<h3>Specific Post/Page ~ Refund/Reversal Notification URLs ( optional )</h3>' . "\n";
850
+ echo '<p>If you use affiliate software, or have back-office routines that need to be notified whenever sales have been refunded or reversed <em>( i.e. charged back to you )</em>, you\'ll want to read this section. This is marked `Specific Post/Page`, because the URLs that you list below, will be notified each time a Refund or Reversal occurs, on a sale that provided access to a Specific Post/Page.</p>' . "\n";
851
+ echo '<p>This is one of only two Notifications that are sent for Specific Post/Page Access <em>( i.e. this one, and another above, for Sales )</em>. All of the other API Notifications are designed for Membership Level Access' . ((is_multisite () && c_ws_plugin__s2member_utils_conds::is_multisite_farm () && !is_main_site ()) ? '' : ' and Independent Custom Capabilities') . '. None of the other API Notifications will ever be processed for Specific Post/Page Access. If you intend to respond to events related to Specific Post/Page Access, you MUST use one of the two API Notifications specifically geared to Post/Page Access.</p>' . "\n";
852
+ echo '<p>Please note, this feature is not to be confused with the PayPal® IPN service. PayPal® IPN <em>( and other service integrations )</em> are already built into s2Member. They remain active at all times. These Refund/Reversal Notifications are an added layer of functionality, and they are completely optional.</p>' . "\n";
853
  do_action ("ws_plugin__s2member_during_api_ops_page_during_left_sections_during_sp_refund_reversal_notifications", get_defined_vars ());
854
  /**/
855
  echo '<table class="form-table">' . "\n";
includes/menu-pages/code-samples/idev-ccap-tracking-code.php ADDED
@@ -0,0 +1,3 @@
 
 
 
1
+ <img
2
+ src="http://www.example.com/idevaffiliate/sale.php?profile=123&idev_saleamt=%%amount%%&idev_ordernum=%%txn_id%%"
3
+ width="1" height="1" border="0" />
includes/menu-pages/code-samples/idev-modification-tracking-code.php ADDED
@@ -0,0 +1,3 @@
 
 
 
1
+ <img
2
+ src="http://www.example.com/idevaffiliate/sale.php?profile=123&idev_saleamt=%%initial%%&idev_ordernum=%%subscr_id%%"
3
+ width="1" height="1" border="0" />
includes/menu-pages/code-samples/sas-ccap-tracking-code.php ADDED
@@ -0,0 +1,3 @@
 
 
 
1
+ <img
2
+ src="https://shareasale.com/sale.cfm?amount=%%amount%%&tracking=%%txn_id%%&transtype=SALE&merchantID=123"
3
+ width="1" height="1" border="0" />
includes/menu-pages/code-samples/sas-modification-tracking-code.php ADDED
@@ -0,0 +1,3 @@
 
 
 
1
+ <img
2
+ src="https://shareasale.com/sale.cfm?amount=%%initial%%&tracking=%%subscr_id%%&transtype=SALE&merchantID=123"
3
+ width="1" height="1" border="0" />
includes/menu-pages/gen-ops.inc.php CHANGED
@@ -15,7 +15,7 @@
15
  * @since 3.0
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_gen_ops"))
21
  {
@@ -52,8 +52,8 @@ if (!class_exists ("c_ws_plugin__s2member_menu_page_gen_ops"))
52
  echo '<div class="ws-menu-page-group" title="Deactivation Safeguards"' . (($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["run_deactivation_routines"]) ? ' default-state="open"' : '') . '>' . "\n";
53
  /**/
54
  echo '<div class="ws-menu-page-section ws-plugin--s2member-deactivation-section">' . "\n";
55
- echo '<h3>Deactivation Safeguards ( optional, recommended )</h3>' . "\n";
56
- echo (is_multisite () && c_ws_plugin__s2member_utils_conds::is_multisite_farm () && !is_main_site () && is_super_admin ()) ? '<p><em class="ws-menu-page-hilite">On a Multisite Blog Farm, this panel is ONLY visible to YOU, as a Super Administrator. s2Member automatically Safeguards everything on a Multisite Blog Farm. However, as the Super Administrator, you may turn this off; on a per-Blog basis. For example, if you\'re going to de-activate s2Member on this particular Blog, you can turn OFF the Safeguards below, so that s2Member will completely erase itself.</em></p>' . "\n" : '<p>By default, s2Member will cleanup ( erase ) all of it\'s Roles, Capabilities, and your Configuration Options when/if you deactivate it from the Plugins Menu in WordPress®. If you would like to Safeguard all of this information, in case s2Member is deactivated inadvertently, please choose Yes ( safeguard all s2Member data/options ).</p>' . "\n";
57
  do_action ("ws_plugin__s2member_during_gen_ops_page_during_left_sections_during_deactivation", get_defined_vars ());
58
  /**/
59
  echo '<table class="form-table">' . "\n";
@@ -71,8 +71,8 @@ if (!class_exists ("c_ws_plugin__s2member_menu_page_gen_ops"))
71
  /**/
72
  echo '<td>' . "\n";
73
  echo '<select name="ws_plugin__s2member_run_deactivation_routines" id="ws-plugin--s2member-run-deactivation-routines">' . "\n";
74
- echo '<option value="1"' . (($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["run_deactivation_routines"]) ? ' selected="selected"' : '') . '></option>' . "\n";
75
  echo '<option value="0"' . ((!$GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["run_deactivation_routines"]) ? ' selected="selected"' : '') . '>Yes ( safeguard all data/options )</option>' . "\n";
 
76
  echo '</select><br />' . "\n";
77
  echo 'Recommended setting: ( <code>Yes, safeguard all data/options</code> )' . "\n";
78
  echo '</td>' . "\n";
15
  * @since 3.0
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_gen_ops"))
21
  {
52
  echo '<div class="ws-menu-page-group" title="Deactivation Safeguards"' . (($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["run_deactivation_routines"]) ? ' default-state="open"' : '') . '>' . "\n";
53
  /**/
54
  echo '<div class="ws-menu-page-section ws-plugin--s2member-deactivation-section">' . "\n";
55
+ echo '<h3>Deactivation Safeguards ( highly recommended )</h3>' . "\n";
56
+ echo (is_multisite () && c_ws_plugin__s2member_utils_conds::is_multisite_farm () && !is_main_site () && is_super_admin ()) ? '<p><em class="ws-menu-page-hilite">On a Multisite Blog Farm, this panel is ONLY visible to YOU, as a Super Administrator. s2Member automatically Safeguards everything on a Multisite Blog Farm. However, as the Super Administrator, you may turn this off; on a per-Blog basis. For example, if you\'re going to de-activate s2Member on this particular Blog, you can turn OFF the Safeguards below, so that s2Member will completely erase itself.</em></p>' . "\n" : '<p>By default, s2Member will retain all of it\'s Roles, Capabilities, and your Configuration Options when/if you deactivate s2Member from the Plugins Menu in WordPress®. However, if you would like for s2Member to erase itself completely, please choose: <code>No ( upon deactivation, erase all data/options )</code>.</p>' . "\n";
57
  do_action ("ws_plugin__s2member_during_gen_ops_page_during_left_sections_during_deactivation", get_defined_vars ());
58
  /**/
59
  echo '<table class="form-table">' . "\n";
71
  /**/
72
  echo '<td>' . "\n";
73
  echo '<select name="ws_plugin__s2member_run_deactivation_routines" id="ws-plugin--s2member-run-deactivation-routines">' . "\n";
 
74
  echo '<option value="0"' . ((!$GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["run_deactivation_routines"]) ? ' selected="selected"' : '') . '>Yes ( safeguard all data/options )</option>' . "\n";
75
+ echo '<option value="1"' . (($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["run_deactivation_routines"]) ? ' selected="selected"' : '') . '>No ( upon deactivation, erase all data/options )</option>' . "\n";
76
  echo '</select><br />' . "\n";
77
  echo 'Recommended setting: ( <code>Yes, safeguard all data/options</code> )' . "\n";
78
  echo '</td>' . "\n";
includes/menu-pages/menu-pages-min.js CHANGED
@@ -1 +1 @@
1
- jQuery(document).ready(function(b){b("div#ws-mlist-div-header").click(function(){var c=b(this),d=b("div#ws-mlist-div-container");if(d.css("display")==="none"){b("ins",c).html("-"),c.addClass("open"),d.show()}else{b("ins",c).html("+"),c.removeClass("open");d.hide()}return false});b("form#ws-mlist-form").submit(function(){var c="";if(!b.trim(b("input#ws-mlist-fname").val())){c+="First Name missing, please try again.\n\n"}if(!b.trim(b("input#ws-mlist-lname").val())){c+="Last Name missing, please try again.\n\n"}if(!b.trim(b("input#ws-mlist-email").val())){c+="Email missing, please try again.\n\n"}else{if(!b("input#ws-mlist-email").val().match(/^([a-z_~0-9\+\-]+)(((\.?)([a-z_~0-9\+\-]+))*)(@)([a-z0-9]+)(((-*)([a-z0-9]+))*)(((\.)([a-z0-9]+)(((-*)([a-z0-9]+))*))*)(\.)([a-z]{2,6})$/i)){c+="Invalid email address, please try again.\n\n"}}if(c=b.trim(c)){alert("— Oops, you missed something: —\n\n"+c);return false}return true});var a=b("div.ws-menu-page-group");a.each(function(e){var g=b(this),d="<ins>+</ins>",f=g,h=b.trim(f.attr("title"));var c=b('<div class="ws-menu-page-group-header">'+d+h+"</div>");c.css({"z-index":100-e});c.insertBefore(f),f.hide(),c.click(function(){var k=b(this),j=b("ins",k),i=k.next();if(i.css("display")==="none"){k.addClass("open"),j.html("-"),i.show()}else{k.removeClass("open"),j.html("+"),i.hide()}return false});if(a.length>1&&e===0){b('<div class="ws-menu-page-groups-show">+</div>').insertBefore(c).click(function(){b("div.ws-menu-page-group-header").each(function(){var k=b(this),j=b("ins",k),i=k.next();k.addClass("open"),j.html("-"),i.show();return});return false});b('<div class="ws-menu-page-groups-hide">-</div>').insertBefore(c).click(function(){b("div.ws-menu-page-group-header").each(function(){var k=b(this),j=b("ins",k),i=k.next();k.removeClass("open"),j.html("+"),i.hide();return});return false})}if(f.attr("default-state")==="open"){c.trigger("click")}return});b("div.ws-menu-page-section:first > h3").css({"margin-top":"0"});b("div.ws-menu-page-group-header:first").css({"margin-top":"0"});b("div.ws-menu-page-hr:first").css({"margin-top":"10px","margin-bottom":"20px"});b("div.ws-menu-page-group > div.ws-menu-page-section:first-child > h3").css({"margin-top":"0"});if(a.length>1){b("div.ws-menu-page-group-header:first").css({"margin-right":"140px"});b("div.ws-menu-page-group:first").css({"margin-right":"145px"})}b("div.ws-menu-page-readme > div.readme > div.section:last-child").css({"border-bottom-width":"0"});b("input.ws-menu-page-media-btn").filter(function(){return(b(this).attr("rel"))?true:false}).click(function(){var c=b(this);window.send_to_editor=function(g){var h,f,d=b.trim(c.attr("rel"));if(d&&(h=b("input#"+d)).length>0){var e=h.css("background-color"),i=b.trim(b(g).attr("src"));i=(!i)?b.trim(b("img",g).attr("src")):i;h.val(i),h.css({"background-color":"#FFFFCC"}),setTimeout(function(){h.css({"background-color":e})},2000);tb_remove();return}else{if(d&&(f=b("textarea#"+d)).length>0){var e=f.css("background-color"),i=b.trim(b(g).attr("src"));i=(!i)?b.trim(b("img",g).attr("src")):i;f.val(b.trim(f.val())+"\n"+i),f.css({"background-color":"#FFFFCC"}),setTimeout(function(){f.css({"background-color":e})},2000);tb_remove();return}}};tb_show("","./media-upload.php?type=image&TB_iframe=true");return false})});
1
+ jQuery(document).ready(function(b){var a=b("div.ws-menu-page-group");a.each(function(e){var g=b(this),d="<ins>+</ins>",f=g,h=b.trim(f.attr("title"));var c=b('<div class="ws-menu-page-group-header">'+d+h+"</div>");c.css({"z-index":100-e});c.insertBefore(f),f.hide(),c.click(function(){var k=b(this),j=b("ins",k),i=k.next();if(i.css("display")==="none"){k.addClass("open"),j.html("-"),i.show()}else{k.removeClass("open"),j.html("+"),i.hide()}return false});if(a.length>1&&e===0){b('<div class="ws-menu-page-groups-show">+</div>').insertBefore(c).click(function(){b("div.ws-menu-page-group-header").each(function(){var k=b(this),j=b("ins",k),i=k.next();k.addClass("open"),j.html("-"),i.show();return});return false});b('<div class="ws-menu-page-groups-hide">-</div>').insertBefore(c).click(function(){b("div.ws-menu-page-group-header").each(function(){var k=b(this),j=b("ins",k),i=k.next();k.removeClass("open"),j.html("+"),i.hide();return});return false})}if(f.attr("default-state")==="open"){c.trigger("click")}return});if(a.length>1){b("div.ws-menu-page-group-header:first").css({"margin-right":"140px"});b("div.ws-menu-page-group:first").css({"margin-right":"145px"})}b("div.ws-menu-page-r-group-header").click(function(){var d=b(this),c=d.next("div.ws-menu-page-r-group");if(c.css("display")==="none"){b("ins",d).html("-"),d.addClass("open"),c.show()}else{b("ins",d).html("+"),d.removeClass("open");c.hide()}return false});b("div.ws-menu-page-group-header:first, div.ws-menu-page-r-group-header:first").css({"margin-top":"0"});b("div.ws-menu-page-group > div.ws-menu-page-section:first-child > h3").css({"margin-top":"0"});b("div.ws-menu-page-readme > div.readme > div.section:last-child").css({"border-bottom-width":"0"});b("input.ws-menu-page-media-btn").filter(function(){return(b(this).attr("rel"))?true:false}).click(function(){var c=b(this);window.send_to_editor=function(g){var h,f,d=b.trim(c.attr("rel"));if(d&&(h=b("input#"+d)).length>0){var e=h.css("background-color"),i=b.trim(b(g).attr("src"));i=(!i)?b.trim(b("img",g).attr("src")):i;h.val(i),h.css({"background-color":"#FFFFCC"}),setTimeout(function(){h.css({"background-color":e})},2000);tb_remove();return}else{if(d&&(f=b("textarea#"+d)).length>0){var e=f.css("background-color"),i=b.trim(b(g).attr("src"));i=(!i)?b.trim(b("img",g).attr("src")):i;f.val(b.trim(f.val())+"\n"+i),f.css({"background-color":"#FFFFCC"}),setTimeout(function(){f.css({"background-color":e})},2000);tb_remove();return}}};tb_show("","./media-upload.php?type=image&TB_iframe=true");return false});b("form#ws-mlist-form").submit(function(){var c="";if(!b.trim(b("input#ws-mlist-fname").val())){c+="First Name missing, please try again.\n\n"}if(!b.trim(b("input#ws-mlist-lname").val())){c+="Last Name missing, please try again.\n\n"}if(!b.trim(b("input#ws-mlist-email").val())){c+="Email missing, please try again.\n\n"}else{if(!b("input#ws-mlist-email").val().match(/^([a-z_~0-9\+\-]+)(((\.?)([a-z_~0-9\+\-]+))*)(@)([a-z0-9]+)(((-*)([a-z0-9]+))*)(((\.)([a-z0-9]+)(((-*)([a-z0-9]+))*))*)(\.)([a-z]{2,6})$/i)){c+="Invalid email address, please try again.\n\n"}}if(c=b.trim(c)){alert("— Oops, you missed something: —\n\n"+c);return false}return true})});
includes/menu-pages/menu-pages-s-min.js CHANGED
@@ -1 +1 @@
1
- jQuery(document).ready(function($){var esc_attr=esc_html=function(str){return String(str).replace(/"/g,"&quot;").replace(/\</g,"&lt;").replace(/\>/g,"&gt;")};if(location.href.match(/page\=ws-plugin--s2member/)){$("input.ws-plugin--s2member-update-roles-button").click(function(){var $this=$(this);$this.val("one moment please ...");$.post(ajaxurl,{action:"ws_plugin__s2member_update_roles_via_ajax",ws_plugin__s2member_update_roles_via_ajax:'<?php echo c_ws_plugin__s2member_utils_strings::esc_sq (wp_create_nonce ("ws-plugin--s2member-update-roles-via-ajax")); ?>'},function(response){if(response==="0"){alert("Sorry, your request failed.\ns2Member's Roles/Capabilities are locked by Filter:\nws_plugin__s2member_lock_roles_caps"),$this.val("Update Roles/Capabilities")}else{if(response==="1"){alert("s2Member's Roles/Capabilities updated successfully."),$this.val("Update Roles/Capabilities")}}});return false})}if(location.href.match(/page\=ws-plugin--s2member-mms-ops/)){$("select#ws-plugin--s2member-mms-registration-file").change(function(){if($(this).val()==="wp-signup"){var gv=$("select#ws-plugin--s2member-mms-registration-grants").val(),l0v=$("input#ws-plugin--s2member-mms-registration-blogs-level0").val();$("div#ws-plugin--s2member-mms-registration-support-package-details-wrapper").show(),$("div.ws-plugin--s2member-mms-registration-wp-login, table.ws-plugin--s2member-mms-registration-wp-login").hide(),$("div.ws-plugin--s2member-mms-registration-wp-signup, table.ws-plugin--s2member-mms-registration-wp-signup").show();$("div.ws-plugin--s2member-mms-registration-wp-signup-blogs-level0, table.ws-plugin--s2member-mms-registration-wp-signup-blogs-level0")[((gv==="all")?"show":"hide")]();$("input#ws-plugin--s2member-mms-registration-blogs-level0").val(((gv==="all")?((l0v>0)?l0v:"1"):"0"))}else{if($(this).val()==="wp-login"){var gv=$("select#ws-plugin--s2member-mms-registration-grants").val(),l0v=$("input#ws-plugin--s2member-mms-registration-blogs-level0").val();$("div#ws-plugin--s2member-mms-registration-support-package-details-wrapper").hide(),$("div.ws-plugin--s2member-mms-registration-wp-login, table.ws-plugin--s2member-mms-registration-wp-login").show(),$("div.ws-plugin--s2member-mms-registration-wp-signup, table.ws-plugin--s2member-mms-registration-wp-signup").hide();$("div.ws-plugin--s2member-mms-registration-wp-signup-blogs-level0, table.ws-plugin--s2member-mms-registration-wp-signup-blogs-level0").hide();$("input#ws-plugin--s2member-mms-registration-blogs-level0").val("0")}}}).trigger("change");$("select#ws-plugin--s2member-mms-registration-grants").change(function(){$("select#ws-plugin--s2member-mms-registration-file").trigger("change")})}else{if(location.href.match(/page\=ws-plugin--s2member-integrations/)){$("select#ws-plugin--s2member-bbpress-ovg").change(function(){if($(this).val()==="0"){$("span#ws-plugin--s2member-bbpress-ovg-off-note").css("display","inline");var l='form#ws-plugin--s2member-bridge-bbpress-form label[for="ws_plugin--s2member-bridge-bbpress-min-level"]';$(l).text($(l).text().replace(/to (read\/)?participate/i,"to read/participate")),$("select#ws-plugin--s2member-bbpress-min-level option").each(function(){$(this).text($(this).text().replace(/\( to( read and)? participate \)/i,"( to read and participate )"))})}else{if($(this).val()==="1"){$("span#ws-plugin--s2member-bbpress-ovg-off-note").css("display","none");var l='form#ws-plugin--s2member-bridge-bbpress-form label[for="ws_plugin--s2member-bridge-bbpress-min-level"]';$(l).text($(l).text().replace(/to (read\/)?participate/i,"to participate")),$("select#ws-plugin--s2member-bbpress-min-level option").each(function(){$(this).text($(this).text().replace(/\( to( read and)? participate \)/i,"( to participate )"))})}}}).trigger("change")}else{if(location.href.match(/page\=ws-plugin--s2member-gen-ops/)){ws_plugin__s2member_generateSecurityKey=function(){var mt_rand=function(min,max){min=(arguments.length<1)?0:min;max=(arguments.length<2)?2147483647:max;return Math.floor(Math.random()*(max-min+1))+min};var chars="ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()";for(var i=0,key="";i<64;i++){key+=chars.substr(mt_rand(0,chars.length-1),1)}$("input#ws-plugin--s2member-sec-encryption-key").val(key);return false};ws_plugin__s2member_enableSecurityKey=function(){if(confirm("Edit Key? Are you sure?\nThis could break your installation!\n\n*Note* If you've been testing s2Member, feel free to change this Key before you go live. Just don't go live, and then change it. You'll have some very unhappy Customers. Data corruption WILL occur!\n\nFor your safety, s2Member keeps a history of the last 10 Keys that you've used. If you get yourself into a real situation, s2Member will let you revert back to a previous Key.")){$("input#ws-plugin--s2member-sec-encryption-key").removeAttr("disabled")}return false};ws_plugin__s2member_securityKeyHistory=function(){$("div#ws-plugin--s2member-sec-encryption-key-history").toggle();return false};$("select#ws-plugin--s2member-new-user-emails-enabled").change(function(){var $pluggable=$("input#ws-plugin--s2member-pluggables-wp-new-user-notification"),$this=$(this),$newUserEmails=$("div#ws-plugin--s2member-new-user-emails");if($pluggable.val()==="0"||$this.val()==="0"){($pluggable.val()==="0")?$this.attr("disabled","disabled"):$this.removeAttr("disabled");$(":input",$newUserEmails).attr("disabled","disabled"),$newUserEmails.css("opacity","0.5")}else{$this.removeAttr("disabled"),$(":input",$newUserEmails).removeAttr("disabled"),$newUserEmails.css("opacity","")}}).trigger("change");if($("input#ws-plugin--s2member-custom-reg-fields").length&&$("div#ws-plugin--s2member-custom-reg-field-configuration").length){(function(){var i,fieldDefaults,tools,table,$tools,$table;var $fields=$("input#ws-plugin--s2member-custom-reg-fields");var $configuration=$("div#ws-plugin--s2member-custom-reg-field-configuration");var fields=($fields.val())?$.JSON.parse($fields.val()):[];fields=(fields instanceof Array)?fields:[];fieldDefaults={section:"no",sectitle:"",id:"",label:"",type:"text",deflt:"",options:"",expected:"",required:"yes",levels:"all",editable:"yes",classes:"",styles:"",attrs:""};for(i=0;i<fields.length;i++){fields[i]=$.extend(true,{},fieldDefaults,fields[i])}tools='<div id="ws-plugin--s2member-custom-reg-field-configuration-tools"></div>',table='<table id="ws-plugin--s2member-custom-reg-field-configuration-table"></table>';$configuration.html(tools+table);$tools=$("div#ws-plugin--s2member-custom-reg-field-configuration-tools"),$table=$("table#ws-plugin--s2member-custom-reg-field-configuration-table");ws_plugin__s2member_customRegFieldSectionChange=function(select){var section=$(select).val();var sectitle_trs="tr.ws-plugin--s2member-custom-reg-field-configuration-tools-form-sectitle";(section==="yes")?$(sectitle_trs).css("display",""):$(sectitle_trs).css("display","none")};ws_plugin__s2member_customRegFieldTypeChange=function(select){var type=$(select).val();var deflt_trs="tr.ws-plugin--s2member-custom-reg-field-configuration-tools-form-deflt",options_trs="tr.ws-plugin--s2member-custom-reg-field-configuration-tools-form-options",expected_trs="tr.ws-plugin--s2member-custom-reg-field-configuration-tools-form-expected";(type.match(/^(text|textarea)$/))?$(deflt_trs).css("display",""):$(deflt_trs).css("display","none");(type.match(/^(select|selects|checkboxes|radios)$/))?$(options_trs).css("display",""):$(options_trs).css("display","none");(type.match(/^(text|textarea)$/))?$(expected_trs).css("display",""):$(expected_trs).css("display","none")};ws_plugin__s2member_customRegFieldDelete=function(index){var newFields=new Array();for(var i=0;i<fields.length;i++){if(i!==index){newFields.push(fields[i])}}fields=newFields,updateFields(),buildTable()};ws_plugin__s2member_customRegFieldMoveUp=function(index){if(typeof fields[index]==="object"&&typeof fields[index-1]==="object"){var prevFieldObj=fields[index-1],thisFieldObj=fields[index];fields[index-1]=thisFieldObj,fields[index]=prevFieldObj;updateFields(),buildTable()}};ws_plugin__s2member_customRegFieldMoveDown=function(index){if(typeof fields[index]==="object"&&typeof fields[index+1]==="object"){var nextFieldObj=fields[index+1],thisFieldObj=fields[index];fields[index+1]=thisFieldObj,fields[index]=nextFieldObj;updateFields(),buildTable()}};ws_plugin__s2member_customRegFieldCreate=function(){var $table=$("table#ws-plugin--s2member-custom-reg-field-configuration-tools-form"),field={};$(":input[property]",$table).each(function(){var $this=$(this),property=$this.attr("property"),val=$.trim($this.val());field[property]=val});if((field=validateField(field))){fields.push(field),updateFields(),buildTools(),buildTable(),scrollReset();setTimeout(function(){var row="tr.ws-plugin--s2member-custom-reg-field-configuration-table-row-"+(fields.length-1);alert('Field created successfully.\n* Remember to "Save All Changes".');$(row).effect("highlight",1500)},500)}};ws_plugin__s2member_customRegFieldUpdate=function(index){var $table=$("table#ws-plugin--s2member-custom-reg-field-configuration-tools-form"),field={};$(":input[property]",$table).each(function(){var $this=$(this),property=$this.attr("property"),val=$.trim($this.val());field[property]=val});if((field=validateField(field,index))){fields[index]=field,updateFields(),buildTools(),buildTable(),scrollReset();setTimeout(function(){var row="tr.ws-plugin--s2member-custom-reg-field-configuration-table-row-"+index;alert('Field updated successfully.\n* Remember to "Save All Changes".');$(row).effect("highlight",1500)},500)}};ws_plugin__s2member_customRegFieldAdd=function(){buildTools(true)};ws_plugin__s2member_customRegFieldEdit=function(index){buildTools(false,index),scrollReset()};ws_plugin__s2member_customRegFieldCancel=function(){buildTools(),scrollReset()};var validateField=function(field,index){var editing=(typeof index==="number"&&typeof fields[index]==="object")?true:false,errors=[],options,i;if(typeof field!=="object"||typeof(field=$.extend(true,{},fieldDefaults,field))!=="object"){alert("Invalid field object. Please try again.");return false}field.sectitle=(field.section==="yes")?field.sectitle:"";field.deflt=(field.type.match(/^(text|textarea)$/))?field.deflt:"";field.deflt=(field.type.match(/^(text)$/))?field.deflt.replace(/[\r\n\t ]+/g," "):field.deflt;field.options=(field.type.match(/^(select|selects|checkboxes|radios)$/))?field.options:"";field.expected=(field.type.match(/^(text|textarea)$/))?field.expected:"";if(!field.id){errors.push("Unique Field ID:\nThis is required. Please try again.")}else{if(fieldIdExists(field.id)&&(!editing||field.id!==fields[index].id)){errors.push("Unique Field ID:\nThat Field ID already exists. Please try again.")}}if(!field.label){errors.push("Field Label/Description:\nThis is required. Please try again.")}if(field.type.match(/^(select|selects|checkboxes|radios)$/)&&!field.options){errors.push("Option Configuration File:\nThis is required. Please try again.")}else{if(field.type.match(/^(select|selects|checkboxes|radios)$/)){for(i=0;i<(options=field.options.split(/[\r\n]+/)).length;i++){if(!(options[i]=$.trim(options[i])).match(/^([^\|]*)(\|)([^\|]*)(\|default)?$/)){errors.push("Option Configuration File:\nInvalid configuration at line #"+(i+1)+".");break}}field.options=$.trim(options.join("\n"))}}if(!(field.levels=field.levels.replace(/ /g,""))){errors.push("Applicable Levels:\nThis is required. Please try again.")}else{if(!field.levels.match(/^(all|[0-9,]+)$/)){errors.push("Applicable Levels:\nShould be comma-delimited Levels, or just type: all.\n( examples: 0,1,2,3,4 or type the word: all )")}}if(field.classes&&field.classes.match(/[^a-z 0-9 _ \-]/i)){errors.push("CSS Classes:\nContains invalid characters. Please try again.\n( only: alphanumerics, underscores, hyphens, spaces )")}if(field.styles&&field.styles.match(/["\=\>\<]/)){errors.push('CSS Styles:\nContains invalid characters. Please try again.\n( do NOT use these characters: = " < > )')}if(field.attrs&&field.attrs.match(/[\>\<]/)){errors.push("Other Attributes:\nContains invalid characters. Please try again.\n( do NOT use these characters: < > )")}if(errors.length>0){alert(errors.join("\n\n"));return false}else{return field}};var updateFields=function(){$fields.val(((fields.length>0)?$.JSON.stringify(fields):""))};var fieldId2Var=function(fieldId){return(typeof fieldId==="string")?$.trim(fieldId).toLowerCase().replace(/[^a-z0-9]/g,"_"):""};var fieldTypeDesc=function(type){var types={text:"Text ( single line )",textarea:"Textarea ( multi-line )",select:"Select Menu ( drop-down )",selects:"Select Menu ( multi-option )",checkbox:"Checkbox ( single )",pre_checkbox:"Checkbox ( pre-checked )",checkboxes:"Checkboxes ( multi-option )",radios:"Radio Buttons ( multi-option )"};if(typeof types[type]==="string"){return types[type]}return""};var fieldIdExists=function(fieldId){for(var i=0;i<fields.length;i++){if(fields[i].id===fieldId){return true}}};var scrollReset=function(){scrollTo(0,$("div.ws-plugin--s2member-custom-reg-fields-section").offset()["top"]-100)};var buildTools=function(adding,index){var i=0,html="",form="",w=0,h=0,editing=(typeof index==="number"&&typeof fields[index]==="object")?true:false,displayForm=(adding||editing)?true:false,field=(editing)?$.extend(true,{},fieldDefaults,fields[index]):fieldDefaults;html+='<a href="#" onclick="ws_plugin__s2member_customRegFieldAdd(); return false;">Add New Field</a>';tb_remove(),$("div#ws-plugin--s2member-custom-reg-field-configuration-thickbox-tools-form").remove();if(displayForm){form+='<div id="ws-plugin--s2member-custom-reg-field-configuration-thickbox-tools-form">';form+='<table id="ws-plugin--s2member-custom-reg-field-configuration-tools-form">';form+="<tbody>";form+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-section">';form+='<td colspan="2">';form+='<label for="ws-plugin--s2member-custom-reg-field-configuration-tools-form-section">Starts A New Section?</label>';form+="</td>";form+="</tr>";form+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-section">';form+='<td colspan="2">';form+='<select property="section" onchange="ws_plugin__s2member_customRegFieldSectionChange(this);" id="ws-plugin--s2member-custom-reg-field-configuration-tools-form-section">';form+='<option value="no"'+((field.section==="no")?' selected="selected"':"")+'">No ( this Field flows normally )</option>';form+='<option value="yes"'+((field.section==="yes")?' selected="selected"':"")+'">Yes ( this Field begins a new section )</option>';form+="</select><br />";form+="<small>Optional. Allows Fields to be grouped into sections.</small>";form+="</td>";form+="</tr>";form+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-spacer ws-plugin--s2member-custom-reg-field-configuration-tools-form-sectitle ws-plugin--s2member-custom-reg-field-configuration-tools-form-section"'+((field.section==="yes")?"":' style="display:none;"')+'><td colspan="2"><hr /></td></tr>';form+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-sectitle ws-plugin--s2member-custom-reg-field-configuration-tools-form-section"'+((field.section==="yes")?"":' style="display:none;"')+">";form+='<td colspan="2">';form+="Title for this new section? ( optional )<br />";form+='<input type="text" property="sectitle" value="'+esc_attr(field.sectitle)+'" id="ws-plugin--s2member-custom-reg-field-configuration-tools-form-sectitle" /><br />';form+="<small>If empty, a simple divider will be used by default.</small>";form+="</td>";form+="</tr>";form+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-spacer ws-plugin--s2member-custom-reg-field-configuration-tools-form-type"><td colspan="2">&nbsp;</td></tr>';form+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-type">';form+='<td colspan="2">';form+='<label for="ws-plugin--s2member-custom-reg-field-configuration-tools-form-type">Form Field Type: *</label>';form+="</td>";form+="</tr>";form+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-type">';form+='<td colspan="2">';form+='<select property="type" onchange="ws_plugin__s2member_customRegFieldTypeChange(this);" id="ws-plugin--s2member-custom-reg-field-configuration-tools-form-type">';form+='<option value="text"'+((field.type==="text")?' selected="selected"':"")+'">'+esc_html(fieldTypeDesc("text"))+"</option>";form+='<option value="textarea"'+((field.type==="textarea")?' selected="selected"':"")+'">'+esc_html(fieldTypeDesc("textarea"))+"</option>";form+='<option value="select"'+((field.type==="select")?' selected="selected"':"")+'">'+esc_html(fieldTypeDesc("select"))+"</option>";form+='<option value="selects"'+((field.type==="selects")?' selected="selected"':"")+'">'+esc_html(fieldTypeDesc("selects"))+"</option>";form+='<option value="checkbox"'+((field.type==="checkbox")?' selected="selected"':"")+'">'+esc_html(fieldTypeDesc("checkbox"))+"</option>";form+='<option value="pre_checkbox"'+((field.type==="pre_checkbox")?' selected="selected"':"")+'">'+esc_html(fieldTypeDesc("pre_checkbox"))+"</option>";form+='<option value="checkboxes"'+((field.type==="checkboxes")?' selected="selected"':"")+'">'+esc_html(fieldTypeDesc("checkboxes"))+"</option>";form+='<option value="radios"'+((field.type==="radios")?' selected="selected"':"")+'">'+esc_html(fieldTypeDesc("radios"))+"</option>";form+="</select><br />";form+="<small>The options below may change, based on the Field Type you choose here.</small>";form+="</td>";form+="</tr>";form+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-spacer ws-plugin--s2member-custom-reg-field-configuration-tools-form-label"><td colspan="2">&nbsp;</td></tr>';form+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-label">';form+='<td colspan="2">';form+='<label for="ws-plugin--s2member-custom-reg-field-configuration-tools-form-label">Field Label/Desc: *</label>';form+="</td>";form+="</tr>";form+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-label">';form+='<td colspan="2">';form+='<input type="text" property="label" value="'+esc_attr(field.label)+'" id="ws-plugin--s2member-custom-reg-field-configuration-tools-form-label" /><br />';form+="<small>Examples: <code>Choose Country</code>, <code>Street Address</code></small>";form+="</td>";form+="</tr>";form+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-spacer ws-plugin--s2member-custom-reg-field-configuration-tools-form-id"><td colspan="2">&nbsp;</td></tr>';form+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-id">';form+='<td colspan="2">';form+='<label for="ws-plugin--s2member-custom-reg-field-configuration-tools-form-id">Unique Field ID: *</label></label>';form+="</td>";form+="</tr>";form+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-id">';form+='<td colspan="2">';form+='<input type="text" property="id" value="'+esc_attr(field.id)+'" maxlength="25" id="ws-plugin--s2member-custom-reg-field-configuration-tools-form-id" /><br />';form+="<small>Examples: <code>country_code</code>, <code>street_address</code></small><br />";form+='<small>e.g. <code>[s2Get user_field="country_code" /]</code></small>';form+="</td>";form+="</tr>";form+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-spacer ws-plugin--s2member-custom-reg-field-configuration-tools-form-required"><td colspan="2">&nbsp;</td></tr>';form+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-required">';form+='<td colspan="2">';form+='<label for="ws-plugin--s2member-custom-reg-field-configuration-tools-form-required">Field Required: *</label>';form+="</td>";form+="</tr>";form+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-required">';form+='<td colspan="2">';form+='<select property="required" id="ws-plugin--s2member-custom-reg-field-configuration-tools-form-required">';form+='<option value="yes"'+((field.required==="yes")?' selected="selected"':"")+'">Yes ( required )</option>';form+='<option value="no"'+((field.required==="no")?' selected="selected"':"")+'">No ( optional )</option>';form+="</select><br />";form+='<small>If <code>yes</code>, only Users/Members will be "required" to enter this field.</small><br />';form+="<small>* Administrators are exempt from this requirement.</small>";form+="</td>";form+="</tr>";form+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-spacer ws-plugin--s2member-custom-reg-field-configuration-tools-form-deflt"'+((field.type.match(/^(text|textarea)$/))?"":' style="display:none;"')+'><td colspan="2">&nbsp;</td></tr>';form+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-deflt"'+((field.type.match(/^(text|textarea)$/))?"":' style="display:none;"')+">";form+='<td colspan="2">';form+='<label for="ws-plugin--s2member-custom-reg-field-configuration-tools-form-deflt">Default Text Value: ( optional )</label>';form+="</td>";form+="</tr>";form+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-deflt"'+((field.type.match(/^(text|textarea)$/))?"":' style="display:none;"')+">";form+='<td colspan="2">';form+='<textarea property="deflt" rows="1" wrap="off" spellcheck="false" id="ws-plugin--s2member-custom-reg-field-configuration-tools-form-deflt">'+esc_html(field.deflt)+"</textarea><br />";form+="<small>Default value before user input is received.</small>";form+="</td>";form+="</tr>";form+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-spacer ws-plugin--s2member-custom-reg-field-configuration-tools-form-options"'+((field.type.match(/^(select|selects|checkboxes|radios)$/))?"":' style="display:none;"')+'><td colspan="2">&nbsp;</td></tr>';form+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-options"'+((field.type.match(/^(select|selects|checkboxes|radios)$/))?"":' style="display:none;"')+">";form+='<td colspan="2">';form+='<label for="ws-plugin--s2member-custom-reg-field-configuration-tools-form-options">Option Configuration File: * ( one option per line )</label><br />';form+="<small>Use a pipe <code>|</code> delimited format: <code>option value|option label</code></small>";form+="</td>";form+="</tr>";form+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-options"'+((field.type.match(/^(select|selects|checkboxes|radios)$/))?"":' style="display:none;"')+">";form+='<td colspan="2">';form+='<textarea property="options" rows="3" wrap="off" spellcheck="false" id="ws-plugin--s2member-custom-reg-field-configuration-tools-form-options">'+esc_html(field.options)+"</textarea><br />";form+="Here is a quick example:<br />";form+="<small>You can also specify a <em>default</em> option:</small><br />";form+="<code>US|United States|default</code><br />";form+="<code>CA|Canada</code><br />";form+="<code>VI|Virgin Islands (U.S.)</code>";form+="</td>";form+="</tr>";form+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-spacer ws-plugin--s2member-custom-reg-field-configuration-tools-form-expected"'+((field.type.match(/^(text|textarea)$/))?"":' style="display:none;"')+'><td colspan="2">&nbsp;</td></tr>';form+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-expected"'+((field.type.match(/^(text|textarea)$/))?"":' style="display:none;"')+">";form+='<td colspan="2">';form+='<label for="ws-plugin--s2member-custom-reg-field-configuration-tools-form-expected">Expected Format: *</label>';form+="</td>";form+="</tr>";form+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-expected"'+((field.type.match(/^(text|textarea)$/))?"":' style="display:none;"')+">";form+='<td colspan="2">';form+='<select property="expected" id="ws-plugin--s2member-custom-reg-field-configuration-tools-form-expected">';form+='<option value=""'+((field.expected==="")?' selected="selected"':"")+'">Anything Goes</option>';form+='<option disabled="disabled"></option>';form+='<optgroup label="Specific Input Types">';form+='<option value="numeric-wp-commas"'+((field.expected==="numeric-wp-commas")?' selected="selected"':"")+'">Numeric ( with or without decimals, commas allowed )</option>';form+='<option value="numeric"'+((field.expected==="numeric")?' selected="selected"':"")+'">Numeric ( with or without decimals, no commas )</option>';form+='<option value="integer"'+((field.expected==="integer")?' selected="selected"':"")+'">Integer ( whole number, without any decimals )</option>';form+='<option value="integer-gt-0"'+((field.expected==="integer-gt-0")?' selected="selected"':"")+'">Integer > 0 ( whole number, no decimals, greater than 0 )</option>';form+='<option value="float"'+((field.expected==="float")?' selected="selected"':"")+'">Float ( floating point number, decimals required )</option>';form+='<option value="float-gt-0"'+((field.expected==="float-gt-0")?' selected="selected"':"")+'">Float > 0 ( floating point number, decimals required, greater than 0 )</option>';form+='<option value="date"'+((field.expected==="date")?' selected="selected"':"")+'">Date ( required date format: dd/mm/yyyy )</option>';form+='<option value="email"'+((field.expected==="email")?' selected="selected"':"")+'">Email ( require valid email )</option>';form+='<option value="url"'+((field.expected==="url")?' selected="selected"':"")+'">Full URL ( starting with http or https )</option>';form+='<option value="domain"'+((field.expected==="domain")?' selected="selected"':"")+'">Domain Name ( domain name only, without http )</option>';form+='<option value="phone"'+((field.expected==="phone")?' selected="selected"':"")+'">Phone # ( 10 digits w/possible hyphens,spaces,brackets )</option>';form+='<option value="uszip"'+((field.expected==="uszip")?' selected="selected"':"")+'">US Zipcode ( 5-9 digits w/possible hyphen )</option>';form+='<option value="cazip"'+((field.expected==="cazip")?' selected="selected"':"")+'">Canadian Zipcode ( 6 alpha-numerics w/possible space )</option>';form+='<option value="uczip"'+((field.expected==="uczip")?' selected="selected"':"")+'">US/Canadian Zipcode ( either a US or Canadian zipcode )</option>';form+="</optgroup>";form+='<option disabled="disabled"></option>';form+='<optgroup label="Any Character Combination">';for(i=1;i<=25;i++){form+='<option value="any-'+i+'"'+((field.expected==="any-"+i)?' selected="selected"':"")+'">Any Character Combination ( '+i+" character minimum )</option>";form+='<option value="any-'+i+'-e"'+((field.expected==="any-"+i+"-e")?' selected="selected"':"")+'">Any Character Combination ( exactly '+i+" character"+((i>1)?"s":"")+" )</option>"}form+="</optgroup>";form+='<option disabled="disabled"></option>';form+='<optgroup label="Alphanumerics, Spaces &amp; Punctuation Only">';for(i=1;i<=25;i++){form+='<option value="alphanumerics-spaces-punctuation-'+i+'"'+((field.expected==="alphanumerics-spaces-punctuation-"+i)?' selected="selected"':"")+'">Alphanumerics, Spaces &amp; Punctuation ( '+i+" character minimum )</option>";form+='<option value="alphanumerics-spaces-punctuation-'+i+'-e"'+((field.expected==="alphanumerics-spaces-punctuation-"+i+"-e")?' selected="selected"':"")+'">Alphanumerics, Spaces &amp; Punctuation ( exactly '+i+" character"+((i>1)?"s":"")+" )</option>"}form+="</optgroup>";form+='<option disabled="disabled"></option>';form+='<optgroup label="Alphanumerics &amp; Spaces Only">';for(i=1;i<=25;i++){form+='<option value="alphanumerics-spaces-'+i+'"'+((field.expected==="alphanumerics-spaces-"+i)?' selected="selected"':"")+'">Alphanumerics &amp; Spaces ( '+i+" character minimum )</option>";form+='<option value="alphanumerics-spaces-'+i+'-e"'+((field.expected==="alphanumerics-spaces-"+i+"-e")?' selected="selected"':"")+'">Alphanumerics &amp; Spaces ( exactly '+i+" character"+((i>1)?"s":"")+" )</option>"}form+="</optgroup>";form+='<option disabled="disabled"></option>';form+='<optgroup label="Alphanumerics &amp; Punctuation Only">';for(i=1;i<=25;i++){form+='<option value="alphanumerics-punctuation-'+i+'"'+((field.expected==="alphanumerics-punctuation-"+i)?' selected="selected"':"")+'">Alphanumerics &amp; Punctuation ( '+i+" character minimum )</option>";form+='<option value="alphanumerics-punctuation-'+i+'-e"'+((field.expected==="alphanumerics-punctuation-"+i+"-e")?' selected="selected"':"")+'">Alphanumerics &amp; Punctuation ( exactly '+i+" character"+((i>1)?"s":"")+" )</option>"}form+="</optgroup>";form+='<option disabled="disabled"></option>';form+='<optgroup label="Alphanumerics Only">';for(i=1;i<=25;i++){form+='<option value="alphanumerics-'+i+'"'+((field.expected==="alphanumerics-"+i)?' selected="selected"':"")+'">Alphanumerics ( '+i+" character minimum )</option>";form+='<option value="alphanumerics-'+i+'-e"'+((field.expected==="alphanumerics-"+i+"-e")?' selected="selected"':"")+'">Alphanumerics ( exactly '+i+" character"+((i>1)?"s":"")+" )</option>"}form+="</optgroup>";form+='<option disabled="disabled"></option>';form+='<optgroup label="Alphabetics Only">';for(i=1;i<=25;i++){form+='<option value="alphabetics-'+i+'"'+((field.expected==="alphabetics-"+i)?' selected="selected"':"")+'">Alphabetics ( '+i+" character minimum )</option>";form+='<option value="alphabetics-'+i+'-e"'+((field.expected==="alphabetics-"+i+"-e")?' selected="selected"':"")+'">Alphabetics ( exactly '+i+" character"+((i>1)?"s":"")+" )</option>"}form+="</optgroup>";form+='<option disabled="disabled"></option>';form+='<optgroup label="Numeric Digits Only">';for(i=1;i<=25;i++){form+='<option value="numerics-'+i+'"'+((field.expected==="numerics-"+i)?' selected="selected"':"")+'">Numeric Digits ( '+i+" digit minimum )</option>";form+='<option value="numerics-'+i+'-e"'+((field.expected==="numerics-"+i+"-e")?' selected="selected"':"")+'">Numeric Digits ( exactly '+i+" digit"+((i>1)?"s":"")+" )</option>"}form+="</optgroup>";form+="</select><br />";form+="<small>Only Users/Members will be required to meet this criteria.</small><br />";form+="<small>* Administrators are exempt from this.</small>";form+="</td>";form+="</tr>";form+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-spacer ws-plugin--s2member-custom-reg-field-configuration-tools-form-levels"><td colspan="2">&nbsp;</td></tr>';form+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-levels">';form+='<td colspan="2">';form+='<label for="ws-plugin--s2member-custom-reg-field-configuration-tools-form-levels">Applicable Membership Levels: *</label>';form+="</td>";form+="</tr>";form+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-levels">';form+='<td colspan="2">';form+='<input type="text" property="levels" value="'+esc_attr(field.levels)+'" id="ws-plugin--s2member-custom-reg-field-configuration-tools-form-levels" /><br />';form+="<small>Please use comma-delimited Level #'s: <code>0,1,2,3,4</code> or type: <code>all</code>.</small><br />";form+="<small>This allows you to enable this field - only at specific Membership Levels.</small>";form+="</td>";form+="</tr>";form+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-spacer ws-plugin--s2member-custom-reg-field-configuration-tools-form-editable"><td colspan="2">&nbsp;</td></tr>';form+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-editable">';form+='<td colspan="2">';form+='<label for="ws-plugin--s2member-custom-reg-field-configuration-tools-form-editable">Allow Profile Edits: *</label>';form+="</td>";form+="</tr>";form+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-editable">';form+='<td colspan="2">';form+='<select property="editable" id="ws-plugin--s2member-custom-reg-field-configuration-tools-form-editable">';form+='<option value="yes"'+((field.editable==="yes")?' selected="selected"':"")+'">Yes ( editable )</option>';form+='<option value="no"'+((field.editable==="no")?' selected="selected"':"")+'">No ( uneditable after registration )</option>';form+='<option value="no-invisible"'+((field.editable==="no-invisible")?' selected="selected"':"")+'">No ( uneditable &amp; totally invisible after registration )</option>';form+='<option value="yes-invisible"'+((field.editable==="yes-invisible")?' selected="selected"':"")+'">Yes ( editable after registration / invisible during registration )</option>';form+="</select><br />";form+="<small>If <code>No</code>, this field will be un-editable after registration.</small><br />";form+="<small>* Administrators are exempt from this.</small>";form+="</td>";form+="</tr>";form+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-spacer ws-plugin--s2member-custom-reg-field-configuration-tools-form-classes"><td colspan="2">&nbsp;</td></tr>';form+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-classes">';form+='<td colspan="2">';form+='<label for="ws-plugin--s2member-custom-reg-field-configuration-tools-form-classes">CSS Classes: ( optional )</label>';form+="</td>";form+="</tr>";form+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-classes">';form+='<td colspan="2">';form+='<input type="text" property="classes" value="'+esc_attr(field.classes)+'" id="ws-plugin--s2member-custom-reg-field-configuration-tools-form-classes" /><br />';form+="<small>Example: <code>my-style-1 my-style-2</code></small>";form+="</td>";form+="</tr>";form+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-spacer ws-plugin--s2member-custom-reg-field-configuration-tools-form-styles"><td colspan="2">&nbsp;</td></tr>';form+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-styles">';form+='<td colspan="2">';form+='<label for="ws-plugin--s2member-custom-reg-field-configuration-tools-form-styles">CSS Styles: ( optional )</label>';form+="</td>";form+="</tr>";form+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-styles">';form+='<td colspan="2">';form+='<input type="text" property="styles" value="'+esc_attr(field.styles)+'" id="ws-plugin--s2member-custom-reg-field-configuration-tools-form-styles" /><br />';form+="<small>Example: <code>color:#000000; background:#FFFFFF;</code></small>";form+="</td>";form+="</tr>";form+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-spacer ws-plugin--s2member-custom-reg-field-configuration-tools-form-attrs"><td colspan="2">&nbsp;</td></tr>';form+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-attrs">';form+='<td colspan="2">';form+='<label for="ws-plugin--s2member-custom-reg-field-configuration-tools-form-attrs">Other Attributes: ( optional )</label>';form+="</td>";form+="</tr>";form+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-attrs">';form+='<td colspan="2">';form+='<input type="text" property="attrs" value="'+esc_attr(field.attrs)+'" id="ws-plugin--s2member-custom-reg-field-configuration-tools-form-attrs" /><br />';form+='<small>Example: <code>onkeyup="" onblur=""</code></small>';form+="</td>";form+="</tr>";form+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-spacer ws-plugin--s2member-custom-reg-field-configuration-tools-form-buttons"><td colspan="2">&nbsp;</td></tr>';form+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-buttons">';form+='<td align="left">';form+='<input type="button" value="Cancel" onclick="ws_plugin__s2member_customRegFieldCancel();" />';form+="</td>";form+='<td align="right">';form+='<input type="button" value="'+((editing)?"Update This Field":"Create Registration Field")+'" onclick="'+((editing)?"ws_plugin__s2member_customRegFieldUpdate("+index+");":"ws_plugin__s2member_customRegFieldCreate();")+'" />';form+="</td>";form+="</tr>";form+="</tbody>";form+="</table>";form+="<div>";$("body").append(form);tb_show(((editing)?"Editing Registration Field":"New Custom Registration Field"),"#TB_inline?inlineId=ws-plugin--s2member-custom-reg-field-configuration-thickbox-tools-form"),$(window).trigger("resize");$("table#ws-plugin--s2member-custom-reg-field-configuration-tools-form").show()}$tools.html(html)};var attachTBResizer=function(){$(window).resize(function(){var w,h;w=$(window).width(),h=$(window).height(),w=(w>720)?720:w;$("#TB_ajaxContent").css({width:w-50,height:h-75,margin:0,padding:0})})};var buildTable=function(){var l=fields.length,i=0,html="",eo="o";html+="<tbody>";html+="<tr>";html+="<th>Order</th>";html+="<th>Field Type</th>";html+="<th>Unique ID</th>";html+="<th>Required</th>";html+="<th>Levels</th>";html+="<th>- Tools -</th>";html+="</tr>";if(fields.length>0){for(i=0;i<fields.length;i++){html+='<tr class="'+esc_attr((eo=(eo==="o")?"e":"o"))+((fields[i].section==="yes")?" s":"")+" ws-plugin--s2member-custom-reg-field-configuration-table-row-"+i+'">';html+='<td nowrap="nowrap"><a class="ws-plugin--s2member-custom-reg-field-configuration-move-up" href="#" onclick="ws_plugin__s2member_customRegFieldMoveUp('+i+'); return false;"></a><a class="ws-plugin--s2member-custom-reg-field-configuration-move-down" href="#" onclick="ws_plugin__s2member_customRegFieldMoveDown('+i+'); return false;"></a></td>';html+='<td nowrap="nowrap">'+esc_html(fieldTypeDesc(fields[i].type))+"</td>";html+='<td nowrap="nowrap">'+esc_html(fields[i].id)+"</td>";html+='<td nowrap="nowrap">'+esc_html(fields[i].required)+"</td>";html+='<td nowrap="nowrap">'+esc_html(fields[i].levels)+"</td>";html+='<td nowrap="nowrap"><a class="ws-plugin--s2member-custom-reg-field-configuration-edit" href="#" onclick="ws_plugin__s2member_customRegFieldEdit('+i+'); return false;"></a><a class="ws-plugin--s2member-custom-reg-field-configuration-delete" href="#" onclick="ws_plugin__s2member_customRegFieldDelete('+i+'); return false;"></a></td>';html+="</tr>"}}else{html+="<tr>";html+='<td colspan="6">No Custom Fields are configured.</td>';html+="</tr>"}html+="</tbody>";$table.html(html)};buildTools(),attachTBResizer(),buildTable()})()}}else{if(location.href.match(/page\=ws-plugin--s2member-res-ops/)){$("input#ws-plugin--s2member-brute-force-restrictions-reset-button").click(function(){var $this=$(this);$this.val("one moment please ...");$.post(ajaxurl,{action:"ws_plugin__s2member_delete_reset_all_ip_restrictions_via_ajax",ws_plugin__s2member_delete_reset_all_ip_restrictions_via_ajax:'<?php echo c_ws_plugin__s2member_utils_strings::esc_sq (wp_create_nonce ("ws-plugin--s2member-delete-reset-all-ip-restrictions-via-ajax")); ?>'},function(response){alert("s2Member's Brute Force Restriction Logs have all been reset."),$this.val("Reset Brute Force Logs")});return false});$("input#ws-plugin--s2member-ip-restrictions-reset-button").click(function(){var $this=$(this);$this.val("one moment please ...");$.post(ajaxurl,{action:"ws_plugin__s2member_delete_reset_all_ip_restrictions_via_ajax",ws_plugin__s2member_delete_reset_all_ip_restrictions_via_ajax:'<?php echo c_ws_plugin__s2member_utils_strings::esc_sq (wp_create_nonce ("ws-plugin--s2member-delete-reset-all-ip-restrictions-via-ajax")); ?>'},function(response){alert("s2Member's IP Restriction Logs have all been reset."),$this.val("Reset IP Restriction Logs")});return false})}else{if(location.href.match(/page\=ws-plugin--s2member-paypal-ops/)){$("select#ws-plugin--s2member-auto-eot-system-enabled").change(function(){var $this=$(this),val=$this.val();var $viaCron=$("p#ws-plugin--s2member-auto-eot-system-enabled-via-cron");if(val==2){$viaCron.show()}else{$viaCron.hide()}})}else{if(location.href.match(/page\=ws-plugin--s2member-els-ops/)){$("select#ws-plugin--s2member-custom-reg-opt-in").change(function(){var $this=$(this),val=$this.val();var $rows=$("tr.ws-plugin--s2member-custom-reg-opt-in-label-row");var $prevImg=$("img.ws-plugin--s2member-custom-reg-opt-in-label-prev-img");if(val<=0){$rows.css("display","none"),$prevImg.attr("src",$prevImg.attr("src").replace(/\/checked\.png$/,"/unchecked.png"))}else{if(val==1){$rows.css("display",""),$prevImg.attr("src",$prevImg.attr("src").replace(/\/unchecked\.png$/,"/checked.png"))}else{if(val==2){$rows.css("display",""),$prevImg.attr("src",$prevImg.attr("src").replace(/\/checked\.png$/,"/unchecked.png"))}}}});$('div.ws-plugin--s2member-opt-out-section input[type="checkbox"][name="ws_plugin__s2member_custom_reg_auto_opt_outs[]"]').change(function(){var thisChange=$(this).val(),checkedIndexes=[];$('div.ws-plugin--s2member-opt-out-section input[type="checkbox"][name="ws_plugin__s2member_custom_reg_auto_opt_outs[]"]').each(function(){var $this=$(this),val=$this.val(),checkboxes='input[type="checkbox"]';if(val==="removal-deletion"&&this.checked){$this.nextAll(checkboxes).slice(0,2).attr({checked:"checked",disabled:"disabled"})}else{if(val==="removal-deletion"&&!this.checked){$this.nextAll(checkboxes).slice(0,2).removeAttr("disabled");(thisChange==="removal-deletion")?$this.nextAll(checkboxes).slice(0,2).removeAttr("checked"):null}else{if(val==="modification"&&this.checked){$this.nextAll(checkboxes).slice(0,3).attr({checked:"checked",disabled:"disabled"})}else{if(val==="modification"&&!this.checked){(thisChange==="modification")?$this.nextAll(checkboxes).slice(0,3).removeAttr("checked"):null;$this.nextAll(checkboxes).slice(0,3).removeAttr("disabled")}}}}}).each(function(index){(this.checked)?checkedIndexes.push(index):null});$("select#ws-plugin--s2member-custom-reg-auto-opt-out-transitions").removeAttr("disabled");if($.inArray(3,checkedIndexes)===-1&&$.inArray(4,checkedIndexes)===-1&&$.inArray(5,checkedIndexes)===-1&&$.inArray(6,checkedIndexes)===-1){$("select#ws-plugin--s2member-custom-reg-auto-opt-out-transitions").attr("disabled","disabled")}}).last().trigger("change")}else{if(location.href.match(/page\=ws-plugin--s2member-paypal-buttons/)){$("div.ws-menu-page select[id]").filter(function(){return this.id.match(/^ws-plugin--s2member-(level[1-9][0-9]*|modification)-term$/)}).change(function(){var button=this.id.replace(/^ws-plugin--s2member-(.+?)-term$/g,"$1");var trialDisabled=($(this).val().split("-")[2].replace(/[^0-1BN]/g,"")==="BN")?1:0;$("p#ws-plugin--s2member-"+button+"-trial-line").css("display",(trialDisabled?"none":""));$("span#ws-plugin--s2member-"+button+"-trial-then").css("display",(trialDisabled?"none":""));$("span#ws-plugin--s2member-"+button+"-20p-rule").css("display",(trialDisabled?"none":""));(trialDisabled)?$("input#ws-plugin--s2member-"+button+"-trial-period").val(0):null;(trialDisabled)?$("input#ws-plugin--s2member-"+button+"-trial-amount").val("0.00"):null});$("div.ws-menu-page input[id]").filter(function(){return this.id.match(/^ws-plugin--s2member-(level[1-9][0-9]*|modification)-ccaps$/)}).keyup(function(){var value=this.value.replace(/^\+/,""),plus=(this.value.match(/^\+/))?"+":"";if(value.match(/[^a-z_0-9,]/)){this.value=plus+$.trim($.trim(value).replace(/[ \-]/g,"_").replace(/[^A-Z_0-9,]/gi,"").toLowerCase())}});ws_plugin__s2member_paypalButtonGenerate=function(button){var shortCodeTemplate='[s2Member-PayPal-Button %%attrs%% image="default" output="button" /]',shortCodeTemplateAttrs="",labels={};eval("<?php echo c_ws_plugin__s2member_utils_strings::esc_dq($labels); ?>");var shortCode=$("input#ws-plugin--s2member-"+button+"-shortcode");var code=$("textarea#ws-plugin--s2member-"+button+"-button");var modLevel=$("select#ws-plugin--s2member-modification-level");var level=(button==="modification")?modLevel.val().split(":",2)[1]:button.replace(/^level/,"");var label=labels["level"+level].replace(/"/g,"");var desc=$.trim($("input#ws-plugin--s2member-"+button+"-desc").val().replace(/"/g,""));var trialAmount=$("input#ws-plugin--s2member-"+button+"-trial-amount").val().replace(/[^0-9\.]/g,"");var trialPeriod=$("input#ws-plugin--s2member-"+button+"-trial-period").val().replace(/[^0-9]/g,"");var trialTerm=$("select#ws-plugin--s2member-"+button+"-trial-term").val().replace(/[^A-Z]/g,"");var regAmount=$("input#ws-plugin--s2member-"+button+"-amount").val().replace(/[^0-9\.]/g,"");var regPeriod=$("select#ws-plugin--s2member-"+button+"-term").val().split("-")[0].replace(/[^0-9]/g,"");var regTerm=$("select#ws-plugin--s2member-"+button+"-term").val().split("-")[1].replace(/[^A-Z]/g,"");var regRecur=$("select#ws-plugin--s2member-"+button+"-term").val().split("-")[2].replace(/[^0-1BN]/g,"");var regRecurTimes="",regRecurRetry="1";var localeCode="",digital="0",noShipping="1";var pageStyle=$.trim($("input#ws-plugin--s2member-"+button+"-page-style").val().replace(/"/g,""));var currencyCode=$("select#ws-plugin--s2member-"+button+"-currency").val().replace(/[^A-Z]/g,"");var cCaps=$.trim($.trim($("input#ws-plugin--s2member-"+button+"-ccaps").val()).replace(/[ \-]/g,"_").replace(/[^A-Z_0-9,]/gi,"").toLowerCase());cCaps=($.trim($("input#ws-plugin--s2member-"+button+"-ccaps").val()).match(/^\+/))?"+"+cCaps.toLowerCase():cCaps.toLowerCase();trialPeriod=(regRecur==="BN")?"0":trialPeriod;trialAmount=(!trialAmount||isNaN(trialAmount)||trialAmount<0.01||trialPeriod<=0)?"0":trialAmount;var levelCcapsPer=(regRecur==="BN"&&regTerm!=="L")?level+":"+cCaps+":"+regPeriod+" "+regTerm:level+":"+cCaps;levelCcapsPer=levelCcapsPer.replace(/\:+$/g,"");if(trialAmount!=="0"&&(isNaN(trialAmount)||trialAmount<0)){alert("— Oops, a slight problem: —\n\nWhen provided, Trial Amount must be >= 0.00");return false}else{if(trialAmount!=="0"&&trialAmount>10000){alert("— Oops, a slight problem: —\n\nMaximum Trial Amount is: 10000.00");return false}else{if(trialTerm==="D"&&trialPeriod>7){alert("— Oops, a slight problem: —\n\nMaximum Trial Days is: 7.\nIf you want to offer more than 7 days, please choose Weeks or Months from the drop-down.");return false}else{if(trialTerm==="W"&&trialPeriod>52){alert("— Oops, a slight problem: —\n\nMaximum Trial Weeks is: 52.\nIf you want to offer more than 52 weeks, please choose Months from the drop-down.");return false}else{if(trialTerm==="M"&&trialPeriod>12){alert("— Oops, a slight problem: —\n\nMaximum Trial Months is: 12.\nIf you want to offer more than 12 months, please choose Years from the drop-down.");return false}else{if(trialTerm==="Y"&&trialPeriod>1){alert("— Oops, a slight problem: —\n\nMax Trial Period Years is: 1.");return false}else{if(!regAmount||isNaN(regAmount)||regAmount<0.01){alert("— Oops, a slight problem: —\n\nAmount must be >= 0.01");return false}else{if(regAmount>10000){alert("— Oops, a slight problem: —\n\nMaximum Amount is: 10000.00");return false}else{if(!desc){alert("— Oops, a slight problem: —\n\nPlease type a Description for this Button.");return false}}}}}}}}}code.html(code.val().replace(/ \<\!--(\<input type\="hidden" name\="(amount|src|srt|sra|a1|p1|t1|a3|p3|t3)" value\="(.*?)" \/\>)--\>/g," $1"));(parseInt(trialPeriod)<=0)?code.html(code.val().replace(/ (\<input type\="hidden" name\="(a1|p1|t1)" value\="(.*?)" \/\>)/g," <!--$1-->")):null;(regRecur==="BN")?code.html(code.val().replace(/ (\<input type\="hidden" name\="cmd" value\=")(.*?)(" \/\>)/g," $1_xclick$3")):null;(regRecur==="BN")?code.html(code.val().replace(/ (\<input type\="hidden" name\="(src|srt|sra|a1|p1|t1|a3|p3|t3)" value\="(.*?)" \/\>)/g," <!--$1-->")):null;(regRecur!=="BN")?code.html(code.val().replace(/ (\<input type\="hidden" name\="cmd" value\=")(.*?)(" \/\>)/g," $1_xclick-subscriptions$3")):null;(regRecur!=="BN")?code.html(code.val().replace(/ (\<input type\="hidden" name\="amount" value\="(.*?)" \/\>)/g," <!--$1-->")):null;shortCodeTemplateAttrs+=(button==="modification")?'modify="1" ':"";shortCodeTemplateAttrs+='level="'+esc_attr(level)+'" ccaps="'+esc_attr(cCaps)+'" desc="'+esc_attr(desc)+'" ps="'+esc_attr(pageStyle)+'" lc="'+esc_attr(localeCode)+'" cc="'+esc_attr(currencyCode)+'" dg="'+esc_attr(digital)+'" ns="'+esc_attr(noShipping)+'" custom="<?php echo c_ws_plugin__s2member_utils_strings::esc_sq (esc_attr ($_SERVER["HTTP_HOST"])); ?>"';shortCodeTemplateAttrs+=' ta="'+esc_attr(trialAmount)+'" tp="'+esc_attr(trialPeriod)+'" tt="'+esc_attr(trialTerm)+'" ra="'+esc_attr(regAmount)+'" rp="'+esc_attr(regPeriod)+'" rt="'+esc_attr(regTerm)+'" rr="'+esc_attr(regRecur)+'" rrt="'+esc_attr(regRecurTimes)+'" rra="'+esc_attr(regRecurRetry)+'"';shortCode.val(shortCodeTemplate.replace(/%%attrs%%/,shortCodeTemplateAttrs));code.html(code.val().replace(/ name\="lc" value\="(.*?)"/,' name="lc" value="'+esc_attr(localeCode)+'"'));code.html(code.val().replace(/ name\="no_shipping" value\="(.*?)"/,' name="no_shipping" value="'+esc_attr(noShipping)+'"'));code.html(code.val().replace(/ name\="item_name" value\="(.*?)"/,' name="item_name" value="'+esc_attr(desc)+'"'));code.html(code.val().replace(/ name\="item_number" value\="(.*?)"/,' name="item_number" value="'+esc_attr(levelCcapsPer)+'"'));code.html(code.val().replace(/ name\="page_style" value\="(.*?)"/,' name="page_style" value="'+esc_attr(pageStyle)+'"'));code.html(code.val().replace(/ name\="currency_code" value\="(.*?)"/,' name="currency_code" value="'+esc_attr(currencyCode)+'"'));code.html(code.val().replace(/ name\="custom" value\="(.*?)"/,' name="custom" value="<?php echo c_ws_plugin__s2member_utils_strings::esc_sq (esc_attr ($_SERVER["HTTP_HOST"])); ?>"'));code.html(code.val().replace(/ name\="modify" value\="(.*?)"/,' name="modify" value="'+((button==="modification")?"1":"0")+'"'));code.html(code.val().replace(/ name\="amount" value\="(.*?)"/,' name="amount" value="'+esc_attr(regAmount)+'"'));code.html(code.val().replace(/ name\="src" value\="(.*?)"/,' name="src" value="'+esc_attr(regRecur)+'"'));code.html(code.val().replace(/ name\="srt" value\="(.*?)"/,' name="srt" value="'+esc_attr(regRecurTimes)+'"'));code.html(code.val().replace(/ name\="sra" value\="(.*?)"/,' name="sra" value="'+esc_attr(regRecurRetry)+'"'));code.html(code.val().replace(/ name\="a1" value\="(.*?)"/,' name="a1" value="'+esc_attr(trialAmount)+'"'));code.html(code.val().replace(/ name\="p1" value\="(.*?)"/,' name="p1" value="'+esc_attr(trialPeriod)+'"'));code.html(code.val().replace(/ name\="t1" value\="(.*?)"/,' name="t1" value="'+esc_attr(trialTerm)+'"'));code.html(code.val().replace(/ name\="a3" value\="(.*?)"/,' name="a3" value="'+esc_attr(regAmount)+'"'));code.html(code.val().replace(/ name\="p3" value\="(.*?)"/,' name="p3" value="'+esc_attr(regPeriod)+'"'));code.html(code.val().replace(/ name\="t3" value\="(.*?)"/,' name="t3" value="'+esc_attr(regTerm)+'"'));$("div#ws-plugin--s2member-"+button+"-button-prev").html(code.val().replace(/\<form/,'<form target="_blank"').replace(/\<\?php echo S2MEMBER_VALUE_FOR_PP_INV\(\); \?\>/g,Math.round(new Date().getTime())+'~<?php echo c_ws_plugin__s2member_utils_strings::esc_sq (esc_attr ($_SERVER["REMOTE_ADDR"])); ?>').replace(/\<\?php echo S2MEMBER_CURRENT_USER_VALUE_FOR_PP_(ON0|OS0|ON1|OS1); \?\>/g,""));(button==="modification")?alert("Your Modification Button has been generated.\nPlease copy/paste the Shortcode Format into your Login Welcome Page, or wherever you feel it would be most appropriate."):alert("Your Button has been generated.\nPlease copy/paste the Shortcode Format into your Membership Options Page.");shortCode.each(function(){this.focus(),this.select()});return false};ws_plugin__s2member_paypalSpButtonGenerate=function(){var shortCodeTemplate='[s2Member-PayPal-Button %%attrs%% image="default" output="button" /]',shortCodeTemplateAttrs="";var shortCode=$("input#ws-plugin--s2member-sp-shortcode");var code=$("textarea#ws-plugin--s2member-sp-button");var leading=$("select#ws-plugin--s2member-sp-leading-id").val().replace(/[^0-9]/g,"");var additionals=$("select#ws-plugin--s2member-sp-additional-ids").val()||[];var hours=$("select#ws-plugin--s2member-sp-hours").val().replace(/[^0-9]/g,"");var regAmount=$("input#ws-plugin--s2member-sp-amount").val().replace(/[^0-9\.]/g,"");var desc=$.trim($("input#ws-plugin--s2member-sp-desc").val().replace(/"/g,""));var localeCode="",digital="0",noShipping="1";var pageStyle=$.trim($("input#ws-plugin--s2member-sp-page-style").val().replace(/"/g,""));var currencyCode=$("select#ws-plugin--s2member-sp-currency").val().replace(/[^A-Z]/g,"");if(!leading){alert("— Oops, a slight problem: —\n\nPlease select a Leading Post/Page.\n\n*Tip* If there are no Posts/Pages in the 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}else{if(!regAmount||isNaN(regAmount)||regAmount<0.01){alert("— Oops, a slight problem: —\n\nAmount must be >= 0.01");return false}else{if(regAmount>10000){alert("— Oops, a slight problem: —\n\nMaximum Amount is: 10000.00");return false}else{if(!desc){alert("— Oops, a slight problem: —\n\nPlease type a Description for this Button.");return false}}}}for(var i=0,ids=leading;i<additionals.length;i++){if(additionals[i]&&additionals[i]!==leading){ids+=","+additionals[i]}}var spIdsHours="sp:"+ids+":"+hours;shortCodeTemplateAttrs+='sp="1" ids="'+esc_attr(ids)+'" exp="'+esc_attr(hours)+'" desc="'+esc_attr(desc)+'" ps="'+esc_attr(pageStyle)+'" lc="'+esc_attr(localeCode)+'" cc="'+esc_attr(currencyCode)+'" dg="'+esc_attr(digital)+'" ns="'+esc_attr(noShipping)+'"';shortCodeTemplateAttrs+=' custom="<?php echo c_ws_plugin__s2member_utils_strings::esc_sq (esc_attr ($_SERVER["HTTP_HOST"])); ?>" ra="'+esc_attr(regAmount)+'"';shortCode.val(shortCodeTemplate.replace(/%%attrs%%/,shortCodeTemplateAttrs));code.html(code.val().replace(/ name\="lc" value\="(.*?)"/,' name="lc" value="'+esc_attr(localeCode)+'"'));code.html(code.val().replace(/ name\="no_shipping" value\="(.*?)"/,' name="no_shipping" value="'+esc_attr(noShipping)+'"'));code.html(code.val().replace(/ name\="item_name" value\="(.*?)"/,' name="item_name" value="'+esc_attr(desc)+'"'));code.html(code.val().replace(/ name\="item_number" value\="(.*?)"/,' name="item_number" value="'+esc_attr(spIdsHours)+'"'));code.html(code.val().replace(/ name\="page_style" value\="(.*?)"/,' name="page_style" value="'+esc_attr(pageStyle)+'"'));code.html(code.val().replace(/ name\="currency_code" value\="(.*?)"/,' name="currency_code" value="'+esc_attr(currencyCode)+'"'));code.html(code.val().replace(/ name\="custom" value\="(.*?)"/,' name="custom" value="<?php echo c_ws_plugin__s2member_utils_strings::esc_sq (esc_attr ($_SERVER["HTTP_HOST"])); ?>"'));code.html(code.val().replace(/ name\="amount" value\="(.*?)"/,' name="amount" value="'+esc_attr(regAmount)+'"'));$("div#ws-plugin--s2member-sp-button-prev").html(code.val().replace(/\<form/,'<form target="_blank"').replace(/\<\?php echo S2MEMBER_VALUE_FOR_PP_INV\(\); \?\>/g,Math.round(new Date().getTime())+'~<?php echo c_ws_plugin__s2member_utils_strings::esc_sq (esc_attr ($_SERVER["REMOTE_ADDR"])); ?>').replace(/\<\?php echo S2MEMBER_CURRENT_USER_VALUE_FOR_PP_(ON0|OS0|ON1|OS1); \?\>/g,""));alert("Your Button has been generated.\nPlease copy/paste the Shortcode Format into your Membership Options Page.");shortCode.each(function(){this.focus(),this.select()});return false};ws_plugin__s2member_paypalRegLinkGenerate=function(){var level=$("select#ws-plugin--s2member-reg-link-level").val().replace(/[^0-9]/g,"");var subscrID=$.trim($("input#ws-plugin--s2member-reg-link-subscr-id").val());var custom=$.trim($("input#ws-plugin--s2member-reg-link-custom").val());var cCaps=$.trim($.trim($("input#ws-plugin--s2member-reg-link-ccaps").val()).replace(/[ \-]/g,"_").replace(/[^A-Z_0-9,]/gi,"").toLowerCase());var fixedTerm=$.trim($("input#ws-plugin--s2member-reg-link-fixed-term").val().replace(/[^A-Z 0-9]/gi,"").toUpperCase());var $link=$("p#ws-plugin--s2member-reg-link"),$loading=$("img#ws-plugin--s2member-reg-link-loading");var levelCcapsPer=(fixedTerm&&!fixedTerm.match(/L$/))?level+":"+cCaps+":"+fixedTerm:level+":"+cCaps;levelCcapsPer=levelCcapsPer.replace(/\:+$/g,"");if(!subscrID){alert("— Oops, a slight problem: —\n\nPaid Subscr. ID is a required value.");return false}else{if(!custom||custom.indexOf('<?php echo c_ws_plugin__s2member_utils_strings::esc_sq ($_SERVER["HTTP_HOST"]); ?>')!==0){alert("— Oops, a slight problem: —\n\nThe Custom Value MUST start with your domain name.");return false}else{if(fixedTerm&&!fixedTerm.match(/^[1-9]+ (D|W|M|Y|L)$/)){alert("— Oops, a slight problem: —\n\nThe Fixed Term Length is not formatted properly.");return false}}}$link.hide(),$loading.show(),$.post(ajaxurl,{action:"ws_plugin__s2member_reg_access_link_via_ajax",ws_plugin__s2member_reg_access_link_via_ajax:'<?php echo c_ws_plugin__s2member_utils_strings::esc_sq (wp_create_nonce ("ws-plugin--s2member-reg-access-link-via-ajax")); ?>',s2member_reg_access_link_subscr_gateway:"paypal",s2member_reg_access_link_subscr_id:subscrID,s2member_reg_access_link_custom:custom,s2member_reg_access_link_item_number:levelCcapsPer},function(response){$link.show().html('<a href="'+esc_attr(response)+'" target="_blank" rel="external">'+esc_html(response)+"</a>"),$loading.hide()});return false};ws_plugin__s2member_paypalSpLinkGenerate=function(){var leading=$("select#ws-plugin--s2member-sp-link-leading-id").val().replace(/[^0-9]/g,"");var additionals=$("select#ws-plugin--s2member-sp-link-additional-ids").val()||[];var hours=$("select#ws-plugin--s2member-sp-link-hours").val().replace(/[^0-9]/g,"");var $link=$("p#ws-plugin--s2member-sp-link"),$loading=$("img#ws-plugin--s2member-sp-link-loading");if(!leading){alert("— Oops, a slight problem: —\n\nPlease select a Leading Post/Page.\n\n*Tip* If there are no Posts/Pages in the 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}for(var i=0,ids=leading;i<additionals.length;i++){if(additionals[i]&&additionals[i]!==leading){ids+=","+additionals[i]}}$link.hide(),$loading.show(),$.post(ajaxurl,{action:"ws_plugin__s2member_sp_access_link_via_ajax",ws_plugin__s2member_sp_access_link_via_ajax:'<?php echo c_ws_plugin__s2member_utils_strings::esc_sq (wp_create_nonce ("ws-plugin--s2member-sp-access-link-via-ajax")); ?>',s2member_sp_access_link_ids:ids,s2member_sp_access_link_hours:hours},function(response){$link.show().html('<a href="'+esc_attr(response)+'" target="_blank" rel="external">'+esc_html(response)+"</a>"),$loading.hide()});return false}}}}}}}}});
1
+ jQuery(document).ready(function($){var esc_attr=esc_html=function(str){return String(str).replace(/"/g,"&quot;").replace(/\</g,"&lt;").replace(/\>/g,"&gt;")};if(location.href.match(/page\=ws-plugin--s2member/)){$("input.ws-plugin--s2member-update-roles-button").click(function(){var $this=$(this);$this.val("one moment please ...");$.post(ajaxurl,{action:"ws_plugin__s2member_update_roles_via_ajax",ws_plugin__s2member_update_roles_via_ajax:'<?php echo c_ws_plugin__s2member_utils_strings::esc_sq (wp_create_nonce ("ws-plugin--s2member-update-roles-via-ajax")); ?>'},function(response){if(response==="0"){alert("Sorry, your request failed.\ns2Member's Roles/Capabilities are locked by Filter:\nws_plugin__s2member_lock_roles_caps"),$this.val("Update Roles/Capabilities")}else{if(response==="1"){alert("s2Member's Roles/Capabilities updated successfully."),$this.val("Update Roles/Capabilities")}}});return false})}if(location.href.match(/page\=ws-plugin--s2member-mms-ops/)){$("select#ws-plugin--s2member-mms-registration-file").change(function(){if($(this).val()==="wp-signup"){var gv=$("select#ws-plugin--s2member-mms-registration-grants").val(),l0v=$("input#ws-plugin--s2member-mms-registration-blogs-level0").val();$("div#ws-plugin--s2member-mms-registration-support-package-details-wrapper").show(),$("div.ws-plugin--s2member-mms-registration-wp-login, table.ws-plugin--s2member-mms-registration-wp-login").hide(),$("div.ws-plugin--s2member-mms-registration-wp-signup, table.ws-plugin--s2member-mms-registration-wp-signup").show();$("div.ws-plugin--s2member-mms-registration-wp-signup-blogs-level0, table.ws-plugin--s2member-mms-registration-wp-signup-blogs-level0")[((gv==="all")?"show":"hide")]();$("input#ws-plugin--s2member-mms-registration-blogs-level0").val(((gv==="all")?((l0v>0)?l0v:"1"):"0"))}else{if($(this).val()==="wp-login"){var gv=$("select#ws-plugin--s2member-mms-registration-grants").val(),l0v=$("input#ws-plugin--s2member-mms-registration-blogs-level0").val();$("div#ws-plugin--s2member-mms-registration-support-package-details-wrapper").hide(),$("div.ws-plugin--s2member-mms-registration-wp-login, table.ws-plugin--s2member-mms-registration-wp-login").show(),$("div.ws-plugin--s2member-mms-registration-wp-signup, table.ws-plugin--s2member-mms-registration-wp-signup").hide();$("div.ws-plugin--s2member-mms-registration-wp-signup-blogs-level0, table.ws-plugin--s2member-mms-registration-wp-signup-blogs-level0").hide();$("input#ws-plugin--s2member-mms-registration-blogs-level0").val("0")}}}).trigger("change");$("select#ws-plugin--s2member-mms-registration-grants").change(function(){$("select#ws-plugin--s2member-mms-registration-file").trigger("change")})}else{if(location.href.match(/page\=ws-plugin--s2member-integrations/)){$("select#ws-plugin--s2member-bbpress-ovg").change(function(){if($(this).val()==="0"){$("span#ws-plugin--s2member-bbpress-ovg-off-note").css("display","inline");var l='form#ws-plugin--s2member-bridge-bbpress-form label[for="ws_plugin--s2member-bridge-bbpress-min-level"]';$(l).text($(l).text().replace(/to (read\/)?participate/i,"to read/participate")),$("select#ws-plugin--s2member-bbpress-min-level option").each(function(){$(this).text($(this).text().replace(/\( to( read and)? participate \)/i,"( to read and participate )"))})}else{if($(this).val()==="1"){$("span#ws-plugin--s2member-bbpress-ovg-off-note").css("display","none");var l='form#ws-plugin--s2member-bridge-bbpress-form label[for="ws_plugin--s2member-bridge-bbpress-min-level"]';$(l).text($(l).text().replace(/to (read\/)?participate/i,"to participate")),$("select#ws-plugin--s2member-bbpress-min-level option").each(function(){$(this).text($(this).text().replace(/\( to( read and)? participate \)/i,"( to participate )"))})}}}).trigger("change")}else{if(location.href.match(/page\=ws-plugin--s2member-gen-ops/)){ws_plugin__s2member_generateSecurityKey=function(){var mt_rand=function(min,max){min=(arguments.length<1)?0:min;max=(arguments.length<2)?2147483647:max;return Math.floor(Math.random()*(max-min+1))+min};var chars="ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()";for(var i=0,key="";i<64;i++){key+=chars.substr(mt_rand(0,chars.length-1),1)}$("input#ws-plugin--s2member-sec-encryption-key").val(key);return false};ws_plugin__s2member_enableSecurityKey=function(){if(confirm("Edit Key? Are you sure?\nThis could break your installation!\n\n*Note* If you've been testing s2Member, feel free to change this Key before you go live. Just don't go live, and then change it. You'll have some very unhappy Customers. Data corruption WILL occur!\n\nFor your safety, s2Member keeps a history of the last 10 Keys that you've used. If you get yourself into a real situation, s2Member will let you revert back to a previous Key.")){$("input#ws-plugin--s2member-sec-encryption-key").removeAttr("disabled")}return false};ws_plugin__s2member_securityKeyHistory=function(){$("div#ws-plugin--s2member-sec-encryption-key-history").toggle();return false};$("select#ws-plugin--s2member-new-user-emails-enabled").change(function(){var $pluggable=$("input#ws-plugin--s2member-pluggables-wp-new-user-notification"),$this=$(this),$newUserEmails=$("div#ws-plugin--s2member-new-user-emails");if($pluggable.val()==="0"||$this.val()==="0"){($pluggable.val()==="0")?$this.attr("disabled","disabled"):$this.removeAttr("disabled");$(":input",$newUserEmails).attr("disabled","disabled"),$newUserEmails.css("opacity","0.5")}else{$this.removeAttr("disabled"),$(":input",$newUserEmails).removeAttr("disabled"),$newUserEmails.css("opacity","")}}).trigger("change");if($("input#ws-plugin--s2member-custom-reg-fields").length&&$("div#ws-plugin--s2member-custom-reg-field-configuration").length){(function(){var i,fieldDefaults,tools,table,$tools,$table;var $fields=$("input#ws-plugin--s2member-custom-reg-fields");var $configuration=$("div#ws-plugin--s2member-custom-reg-field-configuration");var fields=($fields.val())?$.JSON.parse($fields.val()):[];fields=(fields instanceof Array)?fields:[];fieldDefaults={section:"no",sectitle:"",id:"",label:"",type:"text",deflt:"",options:"",expected:"",required:"yes",levels:"all",editable:"yes",classes:"",styles:"",attrs:""};for(i=0;i<fields.length;i++){fields[i]=$.extend(true,{},fieldDefaults,fields[i])}tools='<div id="ws-plugin--s2member-custom-reg-field-configuration-tools"></div>',table='<table id="ws-plugin--s2member-custom-reg-field-configuration-table"></table>';$configuration.html(tools+table);$tools=$("div#ws-plugin--s2member-custom-reg-field-configuration-tools"),$table=$("table#ws-plugin--s2member-custom-reg-field-configuration-table");ws_plugin__s2member_customRegFieldSectionChange=function(select){var section=$(select).val();var sectitle_trs="tr.ws-plugin--s2member-custom-reg-field-configuration-tools-form-sectitle";(section==="yes")?$(sectitle_trs).css("display",""):$(sectitle_trs).css("display","none")};ws_plugin__s2member_customRegFieldTypeChange=function(select){var type=$(select).val();var deflt_trs="tr.ws-plugin--s2member-custom-reg-field-configuration-tools-form-deflt",options_trs="tr.ws-plugin--s2member-custom-reg-field-configuration-tools-form-options",expected_trs="tr.ws-plugin--s2member-custom-reg-field-configuration-tools-form-expected";(type.match(/^(text|textarea)$/))?$(deflt_trs).css("display",""):$(deflt_trs).css("display","none");(type.match(/^(select|selects|checkboxes|radios)$/))?$(options_trs).css("display",""):$(options_trs).css("display","none");(type.match(/^(text|textarea)$/))?$(expected_trs).css("display",""):$(expected_trs).css("display","none")};ws_plugin__s2member_customRegFieldDelete=function(index){var newFields=new Array();for(var i=0;i<fields.length;i++){if(i!==index){newFields.push(fields[i])}}fields=newFields,updateFields(),buildTable()};ws_plugin__s2member_customRegFieldMoveUp=function(index){if(typeof fields[index]==="object"&&typeof fields[index-1]==="object"){var prevFieldObj=fields[index-1],thisFieldObj=fields[index];fields[index-1]=thisFieldObj,fields[index]=prevFieldObj;updateFields(),buildTable()}};ws_plugin__s2member_customRegFieldMoveDown=function(index){if(typeof fields[index]==="object"&&typeof fields[index+1]==="object"){var nextFieldObj=fields[index+1],thisFieldObj=fields[index];fields[index+1]=thisFieldObj,fields[index]=nextFieldObj;updateFields(),buildTable()}};ws_plugin__s2member_customRegFieldCreate=function(){var $table=$("table#ws-plugin--s2member-custom-reg-field-configuration-tools-form"),field={};$(":input[property]",$table).each(function(){var $this=$(this),property=$this.attr("property"),val=$.trim($this.val());field[property]=val});if((field=validateField(field))){fields.push(field),updateFields(),buildTools(),buildTable(),scrollReset();setTimeout(function(){var row="tr.ws-plugin--s2member-custom-reg-field-configuration-table-row-"+(fields.length-1);alert('Field created successfully.\n* Remember to "Save All Changes".');$(row).effect("highlight",1500)},500)}};ws_plugin__s2member_customRegFieldUpdate=function(index){var $table=$("table#ws-plugin--s2member-custom-reg-field-configuration-tools-form"),field={};$(":input[property]",$table).each(function(){var $this=$(this),property=$this.attr("property"),val=$.trim($this.val());field[property]=val});if((field=validateField(field,index))){fields[index]=field,updateFields(),buildTools(),buildTable(),scrollReset();setTimeout(function(){var row="tr.ws-plugin--s2member-custom-reg-field-configuration-table-row-"+index;alert('Field updated successfully.\n* Remember to "Save All Changes".');$(row).effect("highlight",1500)},500)}};ws_plugin__s2member_customRegFieldAdd=function(){buildTools(true)};ws_plugin__s2member_customRegFieldEdit=function(index){buildTools(false,index),scrollReset()};ws_plugin__s2member_customRegFieldCancel=function(){buildTools(),scrollReset()};var validateField=function(field,index){var editing=(typeof index==="number"&&typeof fields[index]==="object")?true:false,errors=[],options,i;if(typeof field!=="object"||typeof(field=$.extend(true,{},fieldDefaults,field))!=="object"){alert("Invalid field object. Please try again.");return false}field.sectitle=(field.section==="yes")?field.sectitle:"";field.deflt=(field.type.match(/^(text|textarea)$/))?field.deflt:"";field.deflt=(field.type.match(/^(text)$/))?field.deflt.replace(/[\r\n\t ]+/g," "):field.deflt;field.options=(field.type.match(/^(select|selects|checkboxes|radios)$/))?field.options:"";field.expected=(field.type.match(/^(text|textarea)$/))?field.expected:"";if(!field.id){errors.push("Unique Field ID:\nThis is required. Please try again.")}else{if(fieldIdExists(field.id)&&(!editing||field.id!==fields[index].id)){errors.push("Unique Field ID:\nThat Field ID already exists. Please try again.")}}if(!field.label){errors.push("Field Label/Description:\nThis is required. Please try again.")}if(field.type.match(/^(select|selects|checkboxes|radios)$/)&&!field.options){errors.push("Option Configuration File:\nThis is required. Please try again.")}else{if(field.type.match(/^(select|selects|checkboxes|radios)$/)){for(i=0;i<(options=field.options.split(/[\r\n]+/)).length;i++){if(!(options[i]=$.trim(options[i])).match(/^([^\|]*)(\|)([^\|]*)(\|default)?$/)){errors.push("Option Configuration File:\nInvalid configuration at line #"+(i+1)+".");break}}field.options=$.trim(options.join("\n"))}}if(!(field.levels=field.levels.replace(/ /g,""))){errors.push("Applicable Levels:\nThis is required. Please try again.")}else{if(!field.levels.match(/^(all|[0-9,]+)$/)){errors.push("Applicable Levels:\nShould be comma-delimited Levels, or just type: all.\n( examples: 0,1,2,3,4 or type the word: all )")}}if(field.classes&&field.classes.match(/[^a-z 0-9 _ \-]/i)){errors.push("CSS Classes:\nContains invalid characters. Please try again.\n( only: alphanumerics, underscores, hyphens, spaces )")}if(field.styles&&field.styles.match(/["\=\>\<]/)){errors.push('CSS Styles:\nContains invalid characters. Please try again.\n( do NOT use these characters: = " < > )')}if(field.attrs&&field.attrs.match(/[\>\<]/)){errors.push("Other Attributes:\nContains invalid characters. Please try again.\n( do NOT use these characters: < > )")}if(errors.length>0){alert(errors.join("\n\n"));return false}else{return field}};var updateFields=function(){$fields.val(((fields.length>0)?$.JSON.stringify(fields):""))};var fieldId2Var=function(fieldId){return(typeof fieldId==="string")?$.trim(fieldId).toLowerCase().replace(/[^a-z0-9]/g,"_"):""};var fieldTypeDesc=function(type){var types={text:"Text ( single line )",textarea:"Textarea ( multi-line )",select:"Select Menu ( drop-down )",selects:"Select Menu ( multi-option )",checkbox:"Checkbox ( single )",pre_checkbox:"Checkbox ( pre-checked )",checkboxes:"Checkboxes ( multi-option )",radios:"Radio Buttons ( multi-option )"};if(typeof types[type]==="string"){return types[type]}return""};var fieldIdExists=function(fieldId){for(var i=0;i<fields.length;i++){if(fields[i].id===fieldId){return true}}};var scrollReset=function(){scrollTo(0,$("div.ws-plugin--s2member-custom-reg-fields-section").offset()["top"]-100)};var buildTools=function(adding,index){var i=0,html="",form="",w=0,h=0,editing=(typeof index==="number"&&typeof fields[index]==="object")?true:false,displayForm=(adding||editing)?true:false,field=(editing)?$.extend(true,{},fieldDefaults,fields[index]):fieldDefaults;html+='<a href="#" onclick="ws_plugin__s2member_customRegFieldAdd(); return false;">Add New Field</a>';tb_remove(),$("div#ws-plugin--s2member-custom-reg-field-configuration-thickbox-tools-form").remove();if(displayForm){form+='<div id="ws-plugin--s2member-custom-reg-field-configuration-thickbox-tools-form">';form+='<table id="ws-plugin--s2member-custom-reg-field-configuration-tools-form">';form+="<tbody>";form+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-section">';form+='<td colspan="2">';form+='<label for="ws-plugin--s2member-custom-reg-field-configuration-tools-form-section">Starts A New Section?</label>';form+="</td>";form+="</tr>";form+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-section">';form+='<td colspan="2">';form+='<select property="section" onchange="ws_plugin__s2member_customRegFieldSectionChange(this);" id="ws-plugin--s2member-custom-reg-field-configuration-tools-form-section">';form+='<option value="no"'+((field.section==="no")?' selected="selected"':"")+'">No ( this Field flows normally )</option>';form+='<option value="yes"'+((field.section==="yes")?' selected="selected"':"")+'">Yes ( this Field begins a new section )</option>';form+="</select><br />";form+="<small>Optional. Allows Fields to be grouped into sections.</small>";form+="</td>";form+="</tr>";form+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-spacer ws-plugin--s2member-custom-reg-field-configuration-tools-form-sectitle ws-plugin--s2member-custom-reg-field-configuration-tools-form-section"'+((field.section==="yes")?"":' style="display:none;"')+'><td colspan="2"><hr /></td></tr>';form+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-sectitle ws-plugin--s2member-custom-reg-field-configuration-tools-form-section"'+((field.section==="yes")?"":' style="display:none;"')+">";form+='<td colspan="2">';form+="Title for this new section? ( optional )<br />";form+='<input type="text" property="sectitle" value="'+esc_attr(field.sectitle)+'" id="ws-plugin--s2member-custom-reg-field-configuration-tools-form-sectitle" /><br />';form+="<small>If empty, a simple divider will be used by default.</small>";form+="</td>";form+="</tr>";form+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-spacer ws-plugin--s2member-custom-reg-field-configuration-tools-form-type"><td colspan="2">&nbsp;</td></tr>';form+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-type">';form+='<td colspan="2">';form+='<label for="ws-plugin--s2member-custom-reg-field-configuration-tools-form-type">Form Field Type: *</label>';form+="</td>";form+="</tr>";form+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-type">';form+='<td colspan="2">';form+='<select property="type" onchange="ws_plugin__s2member_customRegFieldTypeChange(this);" id="ws-plugin--s2member-custom-reg-field-configuration-tools-form-type">';form+='<option value="text"'+((field.type==="text")?' selected="selected"':"")+'">'+esc_html(fieldTypeDesc("text"))+"</option>";form+='<option value="textarea"'+((field.type==="textarea")?' selected="selected"':"")+'">'+esc_html(fieldTypeDesc("textarea"))+"</option>";form+='<option value="select"'+((field.type==="select")?' selected="selected"':"")+'">'+esc_html(fieldTypeDesc("select"))+"</option>";form+='<option value="selects"'+((field.type==="selects")?' selected="selected"':"")+'">'+esc_html(fieldTypeDesc("selects"))+"</option>";form+='<option value="checkbox"'+((field.type==="checkbox")?' selected="selected"':"")+'">'+esc_html(fieldTypeDesc("checkbox"))+"</option>";form+='<option value="pre_checkbox"'+((field.type==="pre_checkbox")?' selected="selected"':"")+'">'+esc_html(fieldTypeDesc("pre_checkbox"))+"</option>";form+='<option value="checkboxes"'+((field.type==="checkboxes")?' selected="selected"':"")+'">'+esc_html(fieldTypeDesc("checkboxes"))+"</option>";form+='<option value="radios"'+((field.type==="radios")?' selected="selected"':"")+'">'+esc_html(fieldTypeDesc("radios"))+"</option>";form+="</select><br />";form+="<small>The options below may change, based on the Field Type you choose here.</small>";form+="</td>";form+="</tr>";form+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-spacer ws-plugin--s2member-custom-reg-field-configuration-tools-form-label"><td colspan="2">&nbsp;</td></tr>';form+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-label">';form+='<td colspan="2">';form+='<label for="ws-plugin--s2member-custom-reg-field-configuration-tools-form-label">Field Label/Desc: *</label>';form+="</td>";form+="</tr>";form+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-label">';form+='<td colspan="2">';form+='<input type="text" property="label" value="'+esc_attr(field.label)+'" id="ws-plugin--s2member-custom-reg-field-configuration-tools-form-label" /><br />';form+="<small>Examples: <code>Choose Country</code>, <code>Street Address</code></small>";form+="</td>";form+="</tr>";form+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-spacer ws-plugin--s2member-custom-reg-field-configuration-tools-form-id"><td colspan="2">&nbsp;</td></tr>';form+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-id">';form+='<td colspan="2">';form+='<label for="ws-plugin--s2member-custom-reg-field-configuration-tools-form-id">Unique Field ID: *</label></label>';form+="</td>";form+="</tr>";form+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-id">';form+='<td colspan="2">';form+='<input type="text" property="id" value="'+esc_attr(field.id)+'" maxlength="25" id="ws-plugin--s2member-custom-reg-field-configuration-tools-form-id" /><br />';form+="<small>Examples: <code>country_code</code>, <code>street_address</code></small><br />";form+='<small>e.g. <code>[s2Get user_field="country_code" /]</code></small>';form+="</td>";form+="</tr>";form+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-spacer ws-plugin--s2member-custom-reg-field-configuration-tools-form-required"><td colspan="2">&nbsp;</td></tr>';form+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-required">';form+='<td colspan="2">';form+='<label for="ws-plugin--s2member-custom-reg-field-configuration-tools-form-required">Field Required: *</label>';form+="</td>";form+="</tr>";form+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-required">';form+='<td colspan="2">';form+='<select property="required" id="ws-plugin--s2member-custom-reg-field-configuration-tools-form-required">';form+='<option value="yes"'+((field.required==="yes")?' selected="selected"':"")+'">Yes ( required )</option>';form+='<option value="no"'+((field.required==="no")?' selected="selected"':"")+'">No ( optional )</option>';form+="</select><br />";form+='<small>If <code>yes</code>, only Users/Members will be "required" to enter this field.</small><br />';form+="<small>* Administrators are exempt from this requirement.</small>";form+="</td>";form+="</tr>";form+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-spacer ws-plugin--s2member-custom-reg-field-configuration-tools-form-deflt"'+((field.type.match(/^(text|textarea)$/))?"":' style="display:none;"')+'><td colspan="2">&nbsp;</td></tr>';form+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-deflt"'+((field.type.match(/^(text|textarea)$/))?"":' style="display:none;"')+">";form+='<td colspan="2">';form+='<label for="ws-plugin--s2member-custom-reg-field-configuration-tools-form-deflt">Default Text Value: ( optional )</label>';form+="</td>";form+="</tr>";form+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-deflt"'+((field.type.match(/^(text|textarea)$/))?"":' style="display:none;"')+">";form+='<td colspan="2">';form+='<textarea property="deflt" rows="1" wrap="off" spellcheck="false" id="ws-plugin--s2member-custom-reg-field-configuration-tools-form-deflt">'+esc_html(field.deflt)+"</textarea><br />";form+="<small>Default value before user input is received.</small>";form+="</td>";form+="</tr>";form+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-spacer ws-plugin--s2member-custom-reg-field-configuration-tools-form-options"'+((field.type.match(/^(select|selects|checkboxes|radios)$/))?"":' style="display:none;"')+'><td colspan="2">&nbsp;</td></tr>';form+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-options"'+((field.type.match(/^(select|selects|checkboxes|radios)$/))?"":' style="display:none;"')+">";form+='<td colspan="2">';form+='<label for="ws-plugin--s2member-custom-reg-field-configuration-tools-form-options">Option Configuration File: * ( one option per line )</label><br />';form+="<small>Use a pipe <code>|</code> delimited format: <code>option value|option label</code></small>";form+="</td>";form+="</tr>";form+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-options"'+((field.type.match(/^(select|selects|checkboxes|radios)$/))?"":' style="display:none;"')+">";form+='<td colspan="2">';form+='<textarea property="options" rows="3" wrap="off" spellcheck="false" id="ws-plugin--s2member-custom-reg-field-configuration-tools-form-options">'+esc_html(field.options)+"</textarea><br />";form+="Here is a quick example:<br />";form+="<small>You can also specify a <em>default</em> option:</small><br />";form+="<code>US|United States|default</code><br />";form+="<code>CA|Canada</code><br />";form+="<code>VI|Virgin Islands (U.S.)</code>";form+="</td>";form+="</tr>";form+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-spacer ws-plugin--s2member-custom-reg-field-configuration-tools-form-expected"'+((field.type.match(/^(text|textarea)$/))?"":' style="display:none;"')+'><td colspan="2">&nbsp;</td></tr>';form+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-expected"'+((field.type.match(/^(text|textarea)$/))?"":' style="display:none;"')+">";form+='<td colspan="2">';form+='<label for="ws-plugin--s2member-custom-reg-field-configuration-tools-form-expected">Expected Format: *</label>';form+="</td>";form+="</tr>";form+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-expected"'+((field.type.match(/^(text|textarea)$/))?"":' style="display:none;"')+">";form+='<td colspan="2">';form+='<select property="expected" id="ws-plugin--s2member-custom-reg-field-configuration-tools-form-expected">';form+='<option value=""'+((field.expected==="")?' selected="selected"':"")+'">Anything Goes</option>';form+='<option disabled="disabled"></option>';form+='<optgroup label="Specific Input Types">';form+='<option value="numeric-wp-commas"'+((field.expected==="numeric-wp-commas")?' selected="selected"':"")+'">Numeric ( with or without decimals, commas allowed )</option>';form+='<option value="numeric"'+((field.expected==="numeric")?' selected="selected"':"")+'">Numeric ( with or without decimals, no commas )</option>';form+='<option value="integer"'+((field.expected==="integer")?' selected="selected"':"")+'">Integer ( whole number, without any decimals )</option>';form+='<option value="integer-gt-0"'+((field.expected==="integer-gt-0")?' selected="selected"':"")+'">Integer > 0 ( whole number, no decimals, greater than 0 )</option>';form+='<option value="float"'+((field.expected==="float")?' selected="selected"':"")+'">Float ( floating point number, decimals required )</option>';form+='<option value="float-gt-0"'+((field.expected==="float-gt-0")?' selected="selected"':"")+'">Float > 0 ( floating point number, decimals required, greater than 0 )</option>';form+='<option value="date"'+((field.expected==="date")?' selected="selected"':"")+'">Date ( required date format: dd/mm/yyyy )</option>';form+='<option value="email"'+((field.expected==="email")?' selected="selected"':"")+'">Email ( require valid email )</option>';form+='<option value="url"'+((field.expected==="url")?' selected="selected"':"")+'">Full URL ( starting with http or https )</option>';form+='<option value="domain"'+((field.expected==="domain")?' selected="selected"':"")+'">Domain Name ( domain name only, without http )</option>';form+='<option value="phone"'+((field.expected==="phone")?' selected="selected"':"")+'">Phone # ( 10 digits w/possible hyphens,spaces,brackets )</option>';form+='<option value="uszip"'+((field.expected==="uszip")?' selected="selected"':"")+'">US Zipcode ( 5-9 digits w/possible hyphen )</option>';form+='<option value="cazip"'+((field.expected==="cazip")?' selected="selected"':"")+'">Canadian Zipcode ( 6 alpha-numerics w/possible space )</option>';form+='<option value="uczip"'+((field.expected==="uczip")?' selected="selected"':"")+'">US/Canadian Zipcode ( either a US or Canadian zipcode )</option>';form+="</optgroup>";form+='<option disabled="disabled"></option>';form+='<optgroup label="Any Character Combination">';for(i=1;i<=25;i++){form+='<option value="any-'+i+'"'+((field.expected==="any-"+i)?' selected="selected"':"")+'">Any Character Combination ( '+i+" character minimum )</option>";form+='<option value="any-'+i+'-e"'+((field.expected==="any-"+i+"-e")?' selected="selected"':"")+'">Any Character Combination ( exactly '+i+" character"+((i>1)?"s":"")+" )</option>"}form+="</optgroup>";form+='<option disabled="disabled"></option>';form+='<optgroup label="Alphanumerics, Spaces &amp; Punctuation Only">';for(i=1;i<=25;i++){form+='<option value="alphanumerics-spaces-punctuation-'+i+'"'+((field.expected==="alphanumerics-spaces-punctuation-"+i)?' selected="selected"':"")+'">Alphanumerics, Spaces &amp; Punctuation ( '+i+" character minimum )</option>";form+='<option value="alphanumerics-spaces-punctuation-'+i+'-e"'+((field.expected==="alphanumerics-spaces-punctuation-"+i+"-e")?' selected="selected"':"")+'">Alphanumerics, Spaces &amp; Punctuation ( exactly '+i+" character"+((i>1)?"s":"")+" )</option>"}form+="</optgroup>";form+='<option disabled="disabled"></option>';form+='<optgroup label="Alphanumerics &amp; Spaces Only">';for(i=1;i<=25;i++){form+='<option value="alphanumerics-spaces-'+i+'"'+((field.expected==="alphanumerics-spaces-"+i)?' selected="selected"':"")+'">Alphanumerics &amp; Spaces ( '+i+" character minimum )</option>";form+='<option value="alphanumerics-spaces-'+i+'-e"'+((field.expected==="alphanumerics-spaces-"+i+"-e")?' selected="selected"':"")+'">Alphanumerics &amp; Spaces ( exactly '+i+" character"+((i>1)?"s":"")+" )</option>"}form+="</optgroup>";form+='<option disabled="disabled"></option>';form+='<optgroup label="Alphanumerics &amp; Punctuation Only">';for(i=1;i<=25;i++){form+='<option value="alphanumerics-punctuation-'+i+'"'+((field.expected==="alphanumerics-punctuation-"+i)?' selected="selected"':"")+'">Alphanumerics &amp; Punctuation ( '+i+" character minimum )</option>";form+='<option value="alphanumerics-punctuation-'+i+'-e"'+((field.expected==="alphanumerics-punctuation-"+i+"-e")?' selected="selected"':"")+'">Alphanumerics &amp; Punctuation ( exactly '+i+" character"+((i>1)?"s":"")+" )</option>"}form+="</optgroup>";form+='<option disabled="disabled"></option>';form+='<optgroup label="Alphanumerics Only">';for(i=1;i<=25;i++){form+='<option value="alphanumerics-'+i+'"'+((field.expected==="alphanumerics-"+i)?' selected="selected"':"")+'">Alphanumerics ( '+i+" character minimum )</option>";form+='<option value="alphanumerics-'+i+'-e"'+((field.expected==="alphanumerics-"+i+"-e")?' selected="selected"':"")+'">Alphanumerics ( exactly '+i+" character"+((i>1)?"s":"")+" )</option>"}form+="</optgroup>";form+='<option disabled="disabled"></option>';form+='<optgroup label="Alphabetics Only">';for(i=1;i<=25;i++){form+='<option value="alphabetics-'+i+'"'+((field.expected==="alphabetics-"+i)?' selected="selected"':"")+'">Alphabetics ( '+i+" character minimum )</option>";form+='<option value="alphabetics-'+i+'-e"'+((field.expected==="alphabetics-"+i+"-e")?' selected="selected"':"")+'">Alphabetics ( exactly '+i+" character"+((i>1)?"s":"")+" )</option>"}form+="</optgroup>";form+='<option disabled="disabled"></option>';form+='<optgroup label="Numeric Digits Only">';for(i=1;i<=25;i++){form+='<option value="numerics-'+i+'"'+((field.expected==="numerics-"+i)?' selected="selected"':"")+'">Numeric Digits ( '+i+" digit minimum )</option>";form+='<option value="numerics-'+i+'-e"'+((field.expected==="numerics-"+i+"-e")?' selected="selected"':"")+'">Numeric Digits ( exactly '+i+" digit"+((i>1)?"s":"")+" )</option>"}form+="</optgroup>";form+="</select><br />";form+="<small>Only Users/Members will be required to meet this criteria.</small><br />";form+="<small>* Administrators are exempt from this.</small>";form+="</td>";form+="</tr>";form+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-spacer ws-plugin--s2member-custom-reg-field-configuration-tools-form-levels"><td colspan="2">&nbsp;</td></tr>';form+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-levels">';form+='<td colspan="2">';form+='<label for="ws-plugin--s2member-custom-reg-field-configuration-tools-form-levels">Applicable Membership Levels: *</label>';form+="</td>";form+="</tr>";form+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-levels">';form+='<td colspan="2">';form+='<input type="text" property="levels" value="'+esc_attr(field.levels)+'" id="ws-plugin--s2member-custom-reg-field-configuration-tools-form-levels" /><br />';form+="<small>Please use comma-delimited Level #'s: <code>0,1,2,3,4</code> or type: <code>all</code>.</small><br />";form+="<small>This allows you to enable this field - only at specific Membership Levels.</small>";form+="</td>";form+="</tr>";form+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-spacer ws-plugin--s2member-custom-reg-field-configuration-tools-form-editable"><td colspan="2">&nbsp;</td></tr>';form+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-editable">';form+='<td colspan="2">';form+='<label for="ws-plugin--s2member-custom-reg-field-configuration-tools-form-editable">Allow Profile Edits: *</label>';form+="</td>";form+="</tr>";form+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-editable">';form+='<td colspan="2">';form+='<select property="editable" id="ws-plugin--s2member-custom-reg-field-configuration-tools-form-editable">';form+='<option value="yes"'+((field.editable==="yes")?' selected="selected"':"")+'">Yes ( editable )</option>';form+='<option value="no"'+((field.editable==="no")?' selected="selected"':"")+'">No ( uneditable after registration )</option>';form+='<option value="no-invisible"'+((field.editable==="no-invisible")?' selected="selected"':"")+'">No ( uneditable &amp; totally invisible after registration )</option>';form+='<option value="yes-invisible"'+((field.editable==="yes-invisible")?' selected="selected"':"")+'">Yes ( editable after registration / invisible during registration )</option>';form+="</select><br />";form+="<small>If <code>No</code>, this field will be un-editable after registration.</small><br />";form+="<small>* Administrators are exempt from this.</small>";form+="</td>";form+="</tr>";form+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-spacer ws-plugin--s2member-custom-reg-field-configuration-tools-form-classes"><td colspan="2">&nbsp;</td></tr>';form+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-classes">';form+='<td colspan="2">';form+='<label for="ws-plugin--s2member-custom-reg-field-configuration-tools-form-classes">CSS Classes: ( optional )</label>';form+="</td>";form+="</tr>";form+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-classes">';form+='<td colspan="2">';form+='<input type="text" property="classes" value="'+esc_attr(field.classes)+'" id="ws-plugin--s2member-custom-reg-field-configuration-tools-form-classes" /><br />';form+="<small>Example: <code>my-style-1 my-style-2</code></small>";form+="</td>";form+="</tr>";form+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-spacer ws-plugin--s2member-custom-reg-field-configuration-tools-form-styles"><td colspan="2">&nbsp;</td></tr>';form+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-styles">';form+='<td colspan="2">';form+='<label for="ws-plugin--s2member-custom-reg-field-configuration-tools-form-styles">CSS Styles: ( optional )</label>';form+="</td>";form+="</tr>";form+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-styles">';form+='<td colspan="2">';form+='<input type="text" property="styles" value="'+esc_attr(field.styles)+'" id="ws-plugin--s2member-custom-reg-field-configuration-tools-form-styles" /><br />';form+="<small>Example: <code>color:#000000; background:#FFFFFF;</code></small>";form+="</td>";form+="</tr>";form+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-spacer ws-plugin--s2member-custom-reg-field-configuration-tools-form-attrs"><td colspan="2">&nbsp;</td></tr>';form+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-attrs">';form+='<td colspan="2">';form+='<label for="ws-plugin--s2member-custom-reg-field-configuration-tools-form-attrs">Other Attributes: ( optional )</label>';form+="</td>";form+="</tr>";form+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-attrs">';form+='<td colspan="2">';form+='<input type="text" property="attrs" value="'+esc_attr(field.attrs)+'" id="ws-plugin--s2member-custom-reg-field-configuration-tools-form-attrs" /><br />';form+='<small>Example: <code>onkeyup="" onblur=""</code></small>';form+="</td>";form+="</tr>";form+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-spacer ws-plugin--s2member-custom-reg-field-configuration-tools-form-buttons"><td colspan="2">&nbsp;</td></tr>';form+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-buttons">';form+='<td align="left">';form+='<input type="button" value="Cancel" onclick="ws_plugin__s2member_customRegFieldCancel();" />';form+="</td>";form+='<td align="right">';form+='<input type="button" value="'+((editing)?"Update This Field":"Create Registration Field")+'" onclick="'+((editing)?"ws_plugin__s2member_customRegFieldUpdate("+index+");":"ws_plugin__s2member_customRegFieldCreate();")+'" />';form+="</td>";form+="</tr>";form+="</tbody>";form+="</table>";form+="<div>";$("body").append(form);tb_show(((editing)?"Editing Registration Field":"New Custom Registration Field"),"#TB_inline?inlineId=ws-plugin--s2member-custom-reg-field-configuration-thickbox-tools-form"),$(window).trigger("resize");$("table#ws-plugin--s2member-custom-reg-field-configuration-tools-form").show()}$tools.html(html)};var attachTBResizer=function(){$(window).resize(function(){var w,h;w=$(window).width(),h=$(window).height(),w=(w>720)?720:w;$("#TB_ajaxContent").css({width:w-50,height:h-75,margin:0,padding:0})})};var buildTable=function(){var l=fields.length,i=0,html="",eo="o";html+="<tbody>";html+="<tr>";html+="<th>Order</th>";html+="<th>Field Type</th>";html+="<th>Unique ID</th>";html+="<th>Required</th>";html+="<th>Levels</th>";html+="<th>- Tools -</th>";html+="</tr>";if(fields.length>0){for(i=0;i<fields.length;i++){html+='<tr class="'+esc_attr((eo=(eo==="o")?"e":"o"))+((fields[i].section==="yes")?" s":"")+" ws-plugin--s2member-custom-reg-field-configuration-table-row-"+i+'">';html+='<td nowrap="nowrap"><a class="ws-plugin--s2member-custom-reg-field-configuration-move-up" href="#" onclick="ws_plugin__s2member_customRegFieldMoveUp('+i+'); return false;"></a><a class="ws-plugin--s2member-custom-reg-field-configuration-move-down" href="#" onclick="ws_plugin__s2member_customRegFieldMoveDown('+i+'); return false;"></a></td>';html+='<td nowrap="nowrap">'+esc_html(fieldTypeDesc(fields[i].type))+"</td>";html+='<td nowrap="nowrap">'+esc_html(fields[i].id)+"</td>";html+='<td nowrap="nowrap">'+esc_html(fields[i].required)+"</td>";html+='<td nowrap="nowrap">'+esc_html(fields[i].levels)+"</td>";html+='<td nowrap="nowrap"><a class="ws-plugin--s2member-custom-reg-field-configuration-edit" href="#" onclick="ws_plugin__s2member_customRegFieldEdit('+i+'); return false;"></a><a class="ws-plugin--s2member-custom-reg-field-configuration-delete" href="#" onclick="ws_plugin__s2member_customRegFieldDelete('+i+'); return false;"></a></td>';html+="</tr>"}}else{html+="<tr>";html+='<td colspan="6">No Custom Fields are configured.</td>';html+="</tr>"}html+="</tbody>";$table.html(html)};buildTools(),attachTBResizer(),buildTable()})()}}else{if(location.href.match(/page\=ws-plugin--s2member-res-ops/)){$("input#ws-plugin--s2member-brute-force-restrictions-reset-button").click(function(){var $this=$(this);$this.val("one moment please ...");$.post(ajaxurl,{action:"ws_plugin__s2member_delete_reset_all_ip_restrictions_via_ajax",ws_plugin__s2member_delete_reset_all_ip_restrictions_via_ajax:'<?php echo c_ws_plugin__s2member_utils_strings::esc_sq (wp_create_nonce ("ws-plugin--s2member-delete-reset-all-ip-restrictions-via-ajax")); ?>'},function(response){alert("s2Member's Brute Force Restriction Logs have all been reset."),$this.val("Reset Brute Force Logs")});return false});$("input#ws-plugin--s2member-ip-restrictions-reset-button").click(function(){var $this=$(this);$this.val("one moment please ...");$.post(ajaxurl,{action:"ws_plugin__s2member_delete_reset_all_ip_restrictions_via_ajax",ws_plugin__s2member_delete_reset_all_ip_restrictions_via_ajax:'<?php echo c_ws_plugin__s2member_utils_strings::esc_sq (wp_create_nonce ("ws-plugin--s2member-delete-reset-all-ip-restrictions-via-ajax")); ?>'},function(response){alert("s2Member's IP Restriction Logs have all been reset."),$this.val("Reset IP Restriction Logs")});return false})}else{if(location.href.match(/page\=ws-plugin--s2member-paypal-ops/)){$("select#ws-plugin--s2member-auto-eot-system-enabled").change(function(){var $this=$(this),val=$this.val();var $viaCron=$("p#ws-plugin--s2member-auto-eot-system-enabled-via-cron");if(val==2){$viaCron.show()}else{$viaCron.hide()}})}else{if(location.href.match(/page\=ws-plugin--s2member-els-ops/)){$("select#ws-plugin--s2member-custom-reg-opt-in").change(function(){var $this=$(this),val=$this.val();var $rows=$("tr.ws-plugin--s2member-custom-reg-opt-in-label-row");var $prevImg=$("img.ws-plugin--s2member-custom-reg-opt-in-label-prev-img");if(val<=0){$rows.css("display","none"),$prevImg.attr("src",$prevImg.attr("src").replace(/\/checked\.png$/,"/unchecked.png"))}else{if(val==1){$rows.css("display",""),$prevImg.attr("src",$prevImg.attr("src").replace(/\/unchecked\.png$/,"/checked.png"))}else{if(val==2){$rows.css("display",""),$prevImg.attr("src",$prevImg.attr("src").replace(/\/checked\.png$/,"/unchecked.png"))}}}});$('div.ws-plugin--s2member-opt-out-section input[type="checkbox"][name="ws_plugin__s2member_custom_reg_auto_opt_outs[]"]').change(function(){var thisChange=$(this).val(),checkedIndexes=[];$('div.ws-plugin--s2member-opt-out-section input[type="checkbox"][name="ws_plugin__s2member_custom_reg_auto_opt_outs[]"]').each(function(){var $this=$(this),val=$this.val(),checkboxes='input[type="checkbox"]';if(val==="removal-deletion"&&this.checked){$this.nextAll(checkboxes).slice(0,2).attr({checked:"checked",disabled:"disabled"})}else{if(val==="removal-deletion"&&!this.checked){$this.nextAll(checkboxes).slice(0,2).removeAttr("disabled");(thisChange==="removal-deletion")?$this.nextAll(checkboxes).slice(0,2).removeAttr("checked"):null}else{if(val==="modification"&&this.checked){$this.nextAll(checkboxes).slice(0,3).attr({checked:"checked",disabled:"disabled"})}else{if(val==="modification"&&!this.checked){(thisChange==="modification")?$this.nextAll(checkboxes).slice(0,3).removeAttr("checked"):null;$this.nextAll(checkboxes).slice(0,3).removeAttr("disabled")}}}}}).each(function(index){(this.checked)?checkedIndexes.push(index):null});$("select#ws-plugin--s2member-custom-reg-auto-opt-out-transitions").removeAttr("disabled");if($.inArray(3,checkedIndexes)===-1&&$.inArray(4,checkedIndexes)===-1&&$.inArray(5,checkedIndexes)===-1&&$.inArray(6,checkedIndexes)===-1){$("select#ws-plugin--s2member-custom-reg-auto-opt-out-transitions").attr("disabled","disabled")}}).last().trigger("change")}else{if(location.href.match(/page\=ws-plugin--s2member-paypal-buttons/)){$("div.ws-menu-page select[id]").filter(function(){return this.id.match(/^ws-plugin--s2member-(level[1-9][0-9]*|modification)-term$/)}).change(function(){var button=this.id.replace(/^ws-plugin--s2member-(.+?)-term$/g,"$1");var trialDisabled=($(this).val().split("-")[2].replace(/[^0-1BN]/g,"")==="BN")?1:0;$("p#ws-plugin--s2member-"+button+"-trial-line").css("display",(trialDisabled?"none":""));$("span#ws-plugin--s2member-"+button+"-trial-then").css("display",(trialDisabled?"none":""));$("span#ws-plugin--s2member-"+button+"-20p-rule").css("display",(trialDisabled?"none":""));(trialDisabled)?$("input#ws-plugin--s2member-"+button+"-trial-period").val(0):null;(trialDisabled)?$("input#ws-plugin--s2member-"+button+"-trial-amount").val("0.00"):null});$("div.ws-menu-page input[id]").filter(function(){return this.id.match(/^ws-plugin--s2member-(level[1-9][0-9]*|modification|ccap)-ccaps$/)}).keyup(function(){var value=this.value.replace(/^(-all|-al|-a|-)[;,]*/gi,""),_all=(this.value.match(/^(-all|-al|-a|-)[;,]*/i))?"-all,":"";if(value.match(/[^a-z_0-9,]/)){this.value=_all+$.trim($.trim(value).replace(/[ \-]/g,"_").replace(/[^a-z_0-9,]/gi,"").toLowerCase())}});ws_plugin__s2member_paypalButtonGenerate=function(button){var shortCodeTemplate='[s2Member-PayPal-Button %%attrs%% image="default" output="button" /]',shortCodeTemplateAttrs="",labels={};eval("<?php echo c_ws_plugin__s2member_utils_strings::esc_dq($labels); ?>");var shortCode=$("input#ws-plugin--s2member-"+button+"-shortcode");var code=$("textarea#ws-plugin--s2member-"+button+"-button");var modLevel=$("select#ws-plugin--s2member-modification-level");var level=(button==="modification")?modLevel.val().split(":",2)[1]:button.replace(/^level/,"");var label=labels["level"+level].replace(/"/g,"");var desc=$.trim($("input#ws-plugin--s2member-"+button+"-desc").val().replace(/"/g,""));var trialAmount=$("input#ws-plugin--s2member-"+button+"-trial-amount").val().replace(/[^0-9\.]/g,"");var trialPeriod=$("input#ws-plugin--s2member-"+button+"-trial-period").val().replace(/[^0-9]/g,"");var trialTerm=$("select#ws-plugin--s2member-"+button+"-trial-term").val().replace(/[^A-Z]/g,"");var regAmount=$("input#ws-plugin--s2member-"+button+"-amount").val().replace(/[^0-9\.]/g,"");var regPeriod=$("select#ws-plugin--s2member-"+button+"-term").val().split("-")[0].replace(/[^0-9]/g,"");var regTerm=$("select#ws-plugin--s2member-"+button+"-term").val().split("-")[1].replace(/[^A-Z]/g,"");var regRecur=$("select#ws-plugin--s2member-"+button+"-term").val().split("-")[2].replace(/[^0-1BN]/g,"");var regRecurTimes="",regRecurRetry="1";var localeCode="",digital="0",noShipping="1";var pageStyle=$.trim($("input#ws-plugin--s2member-"+button+"-page-style").val().replace(/"/g,""));var currencyCode=$("select#ws-plugin--s2member-"+button+"-currency").val().replace(/[^A-Z]/g,"");var cCaps=$.trim($.trim($("input#ws-plugin--s2member-"+button+"-ccaps").val()).replace(/^(-all|-al|-a|-)[;,]*/gi,"").replace(/[ \-]/g,"_").replace(/[^a-z_0-9,]/gi,"").toLowerCase());cCaps=($.trim($("input#ws-plugin--s2member-"+button+"-ccaps").val()).match(/^(-all|-al|-a|-)[;,]*/i))?((cCaps)?"-all,":"-all")+cCaps.toLowerCase():cCaps.toLowerCase();trialPeriod=(regRecur==="BN")?"0":trialPeriod;trialAmount=(!trialAmount||isNaN(trialAmount)||trialAmount<0.01||trialPeriod<=0)?"0":trialAmount;var levelCcapsPer=(regRecur==="BN"&&regTerm!=="L")?level+":"+cCaps+":"+regPeriod+" "+regTerm:level+":"+cCaps;levelCcapsPer=levelCcapsPer.replace(/\:+$/g,"");if(trialAmount!=="0"&&(isNaN(trialAmount)||trialAmount<0)){alert("— Oops, a slight problem: —\n\nWhen provided, Trial Amount must be >= 0.00");return false}else{if(trialAmount!=="0"&&trialAmount>10000){alert("— Oops, a slight problem: —\n\nMaximum Trial Amount is: 10000.00");return false}else{if(trialTerm==="D"&&trialPeriod>7){alert("— Oops, a slight problem: —\n\nMaximum Trial Days is: 7.\nIf you want to offer more than 7 days, please choose Weeks or Months from the drop-down.");return false}else{if(trialTerm==="W"&&trialPeriod>52){alert("— Oops, a slight problem: —\n\nMaximum Trial Weeks is: 52.\nIf you want to offer more than 52 weeks, please choose Months from the drop-down.");return false}else{if(trialTerm==="M"&&trialPeriod>12){alert("— Oops, a slight problem: —\n\nMaximum Trial Months is: 12.\nIf you want to offer more than 12 months, please choose Years from the drop-down.");return false}else{if(trialTerm==="Y"&&trialPeriod>1){alert("— Oops, a slight problem: —\n\nMax Trial Period Years is: 1.");return false}else{if(!regAmount||isNaN(regAmount)||regAmount<0.01){alert("— Oops, a slight problem: —\n\nAmount must be >= 0.01");return false}else{if(regAmount>10000){alert("— Oops, a slight problem: —\n\nMaximum Amount is: 10000.00");return false}else{if(!desc){alert("— Oops, a slight problem: —\n\nPlease type a Description for this Button.");return false}}}}}}}}}code.html(code.val().replace(/ \<\!--(\<input type\="hidden" name\="(amount|src|srt|sra|a1|p1|t1|a3|p3|t3)" value\="(.*?)" \/\>)--\>/g," $1"));(parseInt(trialPeriod)<=0)?code.html(code.val().replace(/ (\<input type\="hidden" name\="(a1|p1|t1)" value\="(.*?)" \/\>)/g," <!--$1-->")):null;(regRecur==="BN")?code.html(code.val().replace(/ (\<input type\="hidden" name\="cmd" value\=")(.*?)(" \/\>)/g," $1_xclick$3")):null;(regRecur==="BN")?code.html(code.val().replace(/ (\<input type\="hidden" name\="(src|srt|sra|a1|p1|t1|a3|p3|t3)" value\="(.*?)" \/\>)/g," <!--$1-->")):null;(regRecur!=="BN")?code.html(code.val().replace(/ (\<input type\="hidden" name\="cmd" value\=")(.*?)(" \/\>)/g," $1_xclick-subscriptions$3")):null;(regRecur!=="BN")?code.html(code.val().replace(/ (\<input type\="hidden" name\="amount" value\="(.*?)" \/\>)/g," <!--$1-->")):null;shortCodeTemplateAttrs+=(button==="modification")?'modify="1" ':"";shortCodeTemplateAttrs+='level="'+esc_attr(level)+'" ccaps="'+esc_attr(cCaps)+'" desc="'+esc_attr(desc)+'" ps="'+esc_attr(pageStyle)+'" lc="'+esc_attr(localeCode)+'" cc="'+esc_attr(currencyCode)+'" dg="'+esc_attr(digital)+'" ns="'+esc_attr(noShipping)+'" custom="<?php echo c_ws_plugin__s2member_utils_strings::esc_sq (esc_attr ($_SERVER["HTTP_HOST"])); ?>"';shortCodeTemplateAttrs+=' ta="'+esc_attr(trialAmount)+'" tp="'+esc_attr(trialPeriod)+'" tt="'+esc_attr(trialTerm)+'" ra="'+esc_attr(regAmount)+'" rp="'+esc_attr(regPeriod)+'" rt="'+esc_attr(regTerm)+'" rr="'+esc_attr(regRecur)+'" rrt="'+esc_attr(regRecurTimes)+'" rra="'+esc_attr(regRecurRetry)+'"';shortCode.val(shortCodeTemplate.replace(/%%attrs%%/,shortCodeTemplateAttrs));code.html(code.val().replace(/ name\="lc" value\="(.*?)"/,' name="lc" value="'+esc_attr(localeCode)+'"'));code.html(code.val().replace(/ name\="no_shipping" value\="(.*?)"/,' name="no_shipping" value="'+esc_attr(noShipping)+'"'));code.html(code.val().replace(/ name\="item_name" value\="(.*?)"/,' name="item_name" value="'+esc_attr(desc)+'"'));code.html(code.val().replace(/ name\="item_number" value\="(.*?)"/,' name="item_number" value="'+esc_attr(levelCcapsPer)+'"'));code.html(code.val().replace(/ name\="page_style" value\="(.*?)"/,' name="page_style" value="'+esc_attr(pageStyle)+'"'));code.html(code.val().replace(/ name\="currency_code" value\="(.*?)"/,' name="currency_code" value="'+esc_attr(currencyCode)+'"'));code.html(code.val().replace(/ name\="custom" value\="(.*?)"/,' name="custom" value="<?php echo c_ws_plugin__s2member_utils_strings::esc_sq (esc_attr ($_SERVER["HTTP_HOST"])); ?>"'));code.html(code.val().replace(/ name\="modify" value\="(.*?)"/,' name="modify" value="'+((button==="modification")?"1":"0")+'"'));code.html(code.val().replace(/ name\="amount" value\="(.*?)"/,' name="amount" value="'+esc_attr(regAmount)+'"'));code.html(code.val().replace(/ name\="src" value\="(.*?)"/,' name="src" value="'+esc_attr(regRecur)+'"'));code.html(code.val().replace(/ name\="srt" value\="(.*?)"/,' name="srt" value="'+esc_attr(regRecurTimes)+'"'));code.html(code.val().replace(/ name\="sra" value\="(.*?)"/,' name="sra" value="'+esc_attr(regRecurRetry)+'"'));code.html(code.val().replace(/ name\="a1" value\="(.*?)"/,' name="a1" value="'+esc_attr(trialAmount)+'"'));code.html(code.val().replace(/ name\="p1" value\="(.*?)"/,' name="p1" value="'+esc_attr(trialPeriod)+'"'));code.html(code.val().replace(/ name\="t1" value\="(.*?)"/,' name="t1" value="'+esc_attr(trialTerm)+'"'));code.html(code.val().replace(/ name\="a3" value\="(.*?)"/,' name="a3" value="'+esc_attr(regAmount)+'"'));code.html(code.val().replace(/ name\="p3" value\="(.*?)"/,' name="p3" value="'+esc_attr(regPeriod)+'"'));code.html(code.val().replace(/ name\="t3" value\="(.*?)"/,' name="t3" value="'+esc_attr(regTerm)+'"'));$("div#ws-plugin--s2member-"+button+"-button-prev").html(code.val().replace(/\<form/,'<form target="_blank"').replace(/\<\?php echo S2MEMBER_VALUE_FOR_PP_INV\(\); \?\>/g,Math.round(new Date().getTime())+'~<?php echo c_ws_plugin__s2member_utils_strings::esc_sq (esc_attr ($_SERVER["REMOTE_ADDR"])); ?>').replace(/\<\?php echo S2MEMBER_CURRENT_USER_VALUE_FOR_PP_(ON0|OS0|ON1|OS1); \?\>/g,""));(button==="modification")?alert("Your Modification Button has been generated.\nPlease copy/paste the Shortcode Format into your Login Welcome Page, or wherever you feel it would be most appropriate.\n\n* Remember, Modification Buttons should be displayed to existing Users/Members, and they should be logged-in, BEFORE clicking this Button."):alert("Your Button has been generated.\nPlease copy/paste the Shortcode Format into your Membership Options Page.");shortCode.each(function(){this.focus(),this.select()});return false};ws_plugin__s2member_paypalCcapButtonGenerate=function(){var shortCodeTemplate='[s2Member-PayPal-Button %%attrs%% image="default" output="button" /]',shortCodeTemplateAttrs="";var shortCode=$("input#ws-plugin--s2member-ccap-shortcode");var code=$("textarea#ws-plugin--s2member-ccap-button");var desc=$.trim($("input#ws-plugin--s2member-ccap-desc").val().replace(/"/g,""));var regAmount=$("input#ws-plugin--s2member-ccap-amount").val().replace(/[^0-9\.]/g,"");var regPeriod=$("select#ws-plugin--s2member-ccap-term").val().split("-")[0].replace(/[^0-9]/g,"");var regTerm=$("select#ws-plugin--s2member-ccap-term").val().split("-")[1].replace(/[^A-Z]/g,"");var regRecur=$("select#ws-plugin--s2member-ccap-term").val().split("-")[2].replace(/[^0-1BN]/g,"");var localeCode="",digital="0",noShipping="1";var pageStyle=$.trim($("input#ws-plugin--s2member-ccap-page-style").val().replace(/"/g,""));var currencyCode=$("select#ws-plugin--s2member-ccap-currency").val().replace(/[^A-Z]/g,"");var cCaps=$.trim($.trim($("input#ws-plugin--s2member-ccap-ccaps").val()).replace(/^(-all|-al|-a|-)[;,]*/gi,"").replace(/[ \-]/g,"_").replace(/[^a-z_0-9,]/gi,"").toLowerCase());cCaps=($.trim($("input#ws-plugin--s2member-ccap-ccaps").val()).match(/^(-all|-al|-a|-)[;,]*/i))?((cCaps)?"-all,":"-all")+cCaps.toLowerCase():cCaps.toLowerCase();var levelCcapsPer=(regRecur==="BN"&&regTerm!=="L")?"*:"+cCaps+":"+regPeriod+" "+regTerm:"*:"+cCaps;levelCcapsPer=levelCcapsPer.replace(/\:+$/g,"");if(!cCaps||cCaps==="-all"){alert("— Oops, a slight problem: —\n\nPlease provide at least one Custom Capability.");return false}else{if(!regAmount||isNaN(regAmount)||regAmount<0.01){alert("— Oops, a slight problem: —\n\nAmount must be >= 0.01");return false}else{if(regAmount>10000){alert("— Oops, a slight problem: —\n\nMaximum Amount is: 10000.00");return false}else{if(!desc){alert("— Oops, a slight problem: —\n\nPlease type a Description for this Button.");return false}}}}shortCodeTemplateAttrs+='level="*" ccaps="'+esc_attr(cCaps)+'" desc="'+esc_attr(desc)+'" ps="'+esc_attr(pageStyle)+'" lc="'+esc_attr(localeCode)+'" cc="'+esc_attr(currencyCode)+'" dg="'+esc_attr(digital)+'" ns="'+esc_attr(noShipping)+'"';shortCodeTemplateAttrs+=' custom="<?php echo c_ws_plugin__s2member_utils_strings::esc_sq (esc_attr ($_SERVER["HTTP_HOST"])); ?>" ra="'+esc_attr(regAmount)+'" rp="'+esc_attr(regPeriod)+'" rt="'+esc_attr(regTerm)+'" rr="'+esc_attr(regRecur)+'"';shortCode.val(shortCodeTemplate.replace(/%%attrs%%/,shortCodeTemplateAttrs));code.html(code.val().replace(/ name\="lc" value\="(.*?)"/,' name="lc" value="'+esc_attr(localeCode)+'"'));code.html(code.val().replace(/ name\="no_shipping" value\="(.*?)"/,' name="no_shipping" value="'+esc_attr(noShipping)+'"'));code.html(code.val().replace(/ name\="item_name" value\="(.*?)"/,' name="item_name" value="'+esc_attr(desc)+'"'));code.html(code.val().replace(/ name\="item_number" value\="(.*?)"/,' name="item_number" value="'+esc_attr(levelCcapsPer)+'"'));code.html(code.val().replace(/ name\="page_style" value\="(.*?)"/,' name="page_style" value="'+esc_attr(pageStyle)+'"'));code.html(code.val().replace(/ name\="currency_code" value\="(.*?)"/,' name="currency_code" value="'+esc_attr(currencyCode)+'"'));code.html(code.val().replace(/ name\="custom" value\="(.*?)"/,' name="custom" value="<?php echo c_ws_plugin__s2member_utils_strings::esc_sq (esc_attr ($_SERVER["HTTP_HOST"])); ?>"'));code.html(code.val().replace(/ name\="amount" value\="(.*?)"/,' name="amount" value="'+esc_attr(regAmount)+'"'));$("div#ws-plugin--s2member-ccap-button-prev").html(code.val().replace(/\<form/,'<form target="_blank"').replace(/\<\?php echo S2MEMBER_VALUE_FOR_PP_INV\(\); \?\>/g,Math.round(new Date().getTime())+'~<?php echo c_ws_plugin__s2member_utils_strings::esc_sq (esc_attr ($_SERVER["REMOTE_ADDR"])); ?>').replace(/\<\?php echo S2MEMBER_CURRENT_USER_VALUE_FOR_PP_(ON0|OS0|ON1|OS1); \?\>/g,""));alert("Your Button has been generated.\nPlease copy/paste the Shortcode Format into your Login Welcome Page, or wherever you feel it would be most appropriate.\n\n* Remember, Independent Custom Capability Buttons should ONLY be displayed to existing Users/Members, and they MUST be logged-in, BEFORE clicking this Button.");shortCode.each(function(){this.focus(),this.select()});return false};ws_plugin__s2member_paypalSpButtonGenerate=function(){var shortCodeTemplate='[s2Member-PayPal-Button %%attrs%% image="default" output="button" /]',shortCodeTemplateAttrs="";var shortCode=$("input#ws-plugin--s2member-sp-shortcode");var code=$("textarea#ws-plugin--s2member-sp-button");var leading=$("select#ws-plugin--s2member-sp-leading-id").val().replace(/[^0-9]/g,"");var additionals=$("select#ws-plugin--s2member-sp-additional-ids").val()||[];var hours=$("select#ws-plugin--s2member-sp-hours").val().replace(/[^0-9]/g,"");var regAmount=$("input#ws-plugin--s2member-sp-amount").val().replace(/[^0-9\.]/g,"");var desc=$.trim($("input#ws-plugin--s2member-sp-desc").val().replace(/"/g,""));var localeCode="",digital="0",noShipping="1";var pageStyle=$.trim($("input#ws-plugin--s2member-sp-page-style").val().replace(/"/g,""));var currencyCode=$("select#ws-plugin--s2member-sp-currency").val().replace(/[^A-Z]/g,"");if(!leading){alert("— Oops, a slight problem: —\n\nPlease select a Leading Post/Page.\n\n*Tip* If there are no Posts/Pages in the 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}else{if(!regAmount||isNaN(regAmount)||regAmount<0.01){alert("— Oops, a slight problem: —\n\nAmount must be >= 0.01");return false}else{if(regAmount>10000){alert("— Oops, a slight problem: —\n\nMaximum Amount is: 10000.00");return false}else{if(!desc){alert("— Oops, a slight problem: —\n\nPlease type a Description for this Button.");return false}}}}for(var i=0,ids=leading;i<additionals.length;i++){if(additionals[i]&&additionals[i]!==leading){ids+=","+additionals[i]}}var spIdsHours="sp:"+ids+":"+hours;shortCodeTemplateAttrs+='sp="1" ids="'+esc_attr(ids)+'" exp="'+esc_attr(hours)+'" desc="'+esc_attr(desc)+'" ps="'+esc_attr(pageStyle)+'" lc="'+esc_attr(localeCode)+'" cc="'+esc_attr(currencyCode)+'" dg="'+esc_attr(digital)+'" ns="'+esc_attr(noShipping)+'"';shortCodeTemplateAttrs+=' custom="<?php echo c_ws_plugin__s2member_utils_strings::esc_sq (esc_attr ($_SERVER["HTTP_HOST"])); ?>" ra="'+esc_attr(regAmount)+'"';shortCode.val(shortCodeTemplate.replace(/%%attrs%%/,shortCodeTemplateAttrs));code.html(code.val().replace(/ name\="lc" value\="(.*?)"/,' name="lc" value="'+esc_attr(localeCode)+'"'));code.html(code.val().replace(/ name\="no_shipping" value\="(.*?)"/,' name="no_shipping" value="'+esc_attr(noShipping)+'"'));code.html(code.val().replace(/ name\="item_name" value\="(.*?)"/,' name="item_name" value="'+esc_attr(desc)+'"'));code.html(code.val().replace(/ name\="item_number" value\="(.*?)"/,' name="item_number" value="'+esc_attr(spIdsHours)+'"'));code.html(code.val().replace(/ name\="page_style" value\="(.*?)"/,' name="page_style" value="'+esc_attr(pageStyle)+'"'));code.html(code.val().replace(/ name\="currency_code" value\="(.*?)"/,' name="currency_code" value="'+esc_attr(currencyCode)+'"'));code.html(code.val().replace(/ name\="custom" value\="(.*?)"/,' name="custom" value="<?php echo c_ws_plugin__s2member_utils_strings::esc_sq (esc_attr ($_SERVER["HTTP_HOST"])); ?>"'));code.html(code.val().replace(/ name\="amount" value\="(.*?)"/,' name="amount" value="'+esc_attr(regAmount)+'"'));$("div#ws-plugin--s2member-sp-button-prev").html(code.val().replace(/\<form/,'<form target="_blank"').replace(/\<\?php echo S2MEMBER_VALUE_FOR_PP_INV\(\); \?\>/g,Math.round(new Date().getTime())+'~<?php echo c_ws_plugin__s2member_utils_strings::esc_sq (esc_attr ($_SERVER["REMOTE_ADDR"])); ?>').replace(/\<\?php echo S2MEMBER_CURRENT_USER_VALUE_FOR_PP_(ON0|OS0|ON1|OS1); \?\>/g,""));alert("Your Button has been generated.\nPlease copy/paste the Shortcode Format into your WordPress® Editor.");shortCode.each(function(){this.focus(),this.select()});return false};ws_plugin__s2member_paypalRegLinkGenerate=function(){var level=$("select#ws-plugin--s2member-reg-link-level").val().replace(/[^0-9]/g,"");var subscrID=$.trim($("input#ws-plugin--s2member-reg-link-subscr-id").val());var custom=$.trim($("input#ws-plugin--s2member-reg-link-custom").val());var cCaps=$.trim($.trim($("input#ws-plugin--s2member-reg-link-ccaps").val()).replace(/[ \-]/g,"_").replace(/[^a-z_0-9,]/gi,"").toLowerCase());var fixedTerm=$.trim($("input#ws-plugin--s2member-reg-link-fixed-term").val().replace(/[^A-Z 0-9]/gi,"").toUpperCase());var $link=$("p#ws-plugin--s2member-reg-link"),$loading=$("img#ws-plugin--s2member-reg-link-loading");var levelCcapsPer=(fixedTerm&&!fixedTerm.match(/L$/))?level+":"+cCaps+":"+fixedTerm:level+":"+cCaps;levelCcapsPer=levelCcapsPer.replace(/\:+$/g,"");if(!subscrID){alert("— Oops, a slight problem: —\n\nPaid Subscr. ID is a required value.");return false}else{if(!custom||custom.indexOf('<?php echo c_ws_plugin__s2member_utils_strings::esc_sq ($_SERVER["HTTP_HOST"]); ?>')!==0){alert("— Oops, a slight problem: —\n\nThe Custom Value MUST start with your domain name.");return false}else{if(fixedTerm&&!fixedTerm.match(/^[1-9]+ (D|W|M|Y|L)$/)){alert("— Oops, a slight problem: —\n\nThe Fixed Term Length is not formatted properly.");return false}}}$link.hide(),$loading.show(),$.post(ajaxurl,{action:"ws_plugin__s2member_reg_access_link_via_ajax",ws_plugin__s2member_reg_access_link_via_ajax:'<?php echo c_ws_plugin__s2member_utils_strings::esc_sq (wp_create_nonce ("ws-plugin--s2member-reg-access-link-via-ajax")); ?>',s2member_reg_access_link_subscr_gateway:"paypal",s2member_reg_access_link_subscr_id:subscrID,s2member_reg_access_link_custom:custom,s2member_reg_access_link_item_number:levelCcapsPer},function(response){$link.show().html('<a href="'+esc_attr(response)+'" target="_blank" rel="external">'+esc_html(response)+"</a>"),$loading.hide()});return false};ws_plugin__s2member_paypalSpLinkGenerate=function(){var leading=$("select#ws-plugin--s2member-sp-link-leading-id").val().replace(/[^0-9]/g,"");var additionals=$("select#ws-plugin--s2member-sp-link-additional-ids").val()||[];var hours=$("select#ws-plugin--s2member-sp-link-hours").val().replace(/[^0-9]/g,"");var $link=$("p#ws-plugin--s2member-sp-link"),$loading=$("img#ws-plugin--s2member-sp-link-loading");if(!leading){alert("— Oops, a slight problem: —\n\nPlease select a Leading Post/Page.\n\n*Tip* If there are no Posts/Pages in the 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}for(var i=0,ids=leading;i<additionals.length;i++){if(additionals[i]&&additionals[i]!==leading){ids+=","+additionals[i]}}$link.hide(),$loading.show(),$.post(ajaxurl,{action:"ws_plugin__s2member_sp_access_link_via_ajax",ws_plugin__s2member_sp_access_link_via_ajax:'<?php echo c_ws_plugin__s2member_utils_strings::esc_sq (wp_create_nonce ("ws-plugin--s2member-sp-access-link-via-ajax")); ?>',s2member_sp_access_link_ids:ids,s2member_sp_access_link_hours:hours},function(response){$link.show().html('<a href="'+esc_attr(response)+'" target="_blank" rel="external">'+esc_html(response)+"</a>"),$loading.hide()});return false}}}}}}}}});
includes/menu-pages/menu-pages-s.js CHANGED
@@ -945,12 +945,12 @@ jQuery(document).ready (function($)
945
  /**/
946
  $('div.ws-menu-page input[id]').filter (function() /* Filter all input elements with an id. */
947
  {
948
- return this.id.match (/^ws-plugin--s2member-(level[1-9][0-9]*|modification)-ccaps$/);
949
  }).keyup (function()
950
  {
951
- var value = this.value.replace (/^\+/, ''), plus = (this.value.match (/^\+/)) ? '+' : '';
952
- if (value.match (/[^a-z_0-9,]/)) /* Only if there is a problem; because this causes interruptions. */
953
- this.value = plus + $.trim ($.trim (value).replace (/[ \-]/g, '_').replace (/[^A-Z_0-9,]/gi, '').toLowerCase ());
954
  });
955
  /**/
956
  ws_plugin__s2member_paypalButtonGenerate = function(button) /* Handles PayPal® Button Generation. */
@@ -980,8 +980,9 @@ jQuery(document).ready (function($)
980
  var localeCode = '', digital = '0', noShipping = '1'; /* NOT yet configurable. */
981
  var pageStyle = $.trim ($('input#ws-plugin--s2member-' + button + '-page-style').val ().replace (/"/g, ''));
982
  var currencyCode = $('select#ws-plugin--s2member-' + button + '-currency').val ().replace (/[^A-Z]/g, '');
983
- var cCaps = $.trim ($.trim ($('input#ws-plugin--s2member-' + button + '-ccaps').val ()).replace (/[ \-]/g, '_').replace (/[^A-Z_0-9,]/gi, '').toLowerCase ());
984
- cCaps = ($.trim ($('input#ws-plugin--s2member-' + button + '-ccaps').val ()).match (/^\+/)) ? '+' + cCaps.toLowerCase () : cCaps.toLowerCase ();
 
985
  /**/
986
  trialPeriod = (regRecur === 'BN') ? '0' : trialPeriod; /* Lifetime ( 1-L-BN ) and Buy Now ( BN ) access is absolutely NOT compatible w/ Trial Periods. */
987
  trialAmount = (!trialAmount || isNaN(trialAmount) || trialAmount < 0.01 || trialPeriod <= 0) ? '0' : trialAmount; /* Validate Trial Amount. */
@@ -1072,7 +1073,78 @@ jQuery(document).ready (function($)
1072
  /**/
1073
  $('div#ws-plugin--s2member-' + button + '-button-prev').html (code.val ().replace (/\<form/, '<form target="_blank"').replace (/\<\?php echo S2MEMBER_VALUE_FOR_PP_INV\(\); \?\>/g, Math.round (new Date ().getTime ()) + '~<?php echo c_ws_plugin__s2member_utils_strings::esc_sq (esc_attr ($_SERVER["REMOTE_ADDR"])); ?>').replace (/\<\?php echo S2MEMBER_CURRENT_USER_VALUE_FOR_PP_(ON0|OS0|ON1|OS1); \?\>/g, ''));
1074
  /**/
1075
- (button === 'modification') ? alert('Your Modification Button has been generated.\nPlease copy/paste the Shortcode Format into your Login Welcome Page, or wherever you feel it would be most appropriate.') : alert('Your Button has been generated.\nPlease copy/paste the Shortcode Format into your Membership Options Page.');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1076
  /**/
1077
  shortCode.each (function() /* Focus and select the recommended Shortcode. */
1078
  {
@@ -1143,7 +1215,7 @@ jQuery(document).ready (function($)
1143
  /**/
1144
  $('div#ws-plugin--s2member-sp-button-prev').html (code.val ().replace (/\<form/, '<form target="_blank"').replace (/\<\?php echo S2MEMBER_VALUE_FOR_PP_INV\(\); \?\>/g, Math.round (new Date ().getTime ()) + '~<?php echo c_ws_plugin__s2member_utils_strings::esc_sq (esc_attr ($_SERVER["REMOTE_ADDR"])); ?>').replace (/\<\?php echo S2MEMBER_CURRENT_USER_VALUE_FOR_PP_(ON0|OS0|ON1|OS1); \?\>/g, ''));
1145
  /**/
1146
- alert('Your Button has been generated.\nPlease copy/paste the Shortcode Format into your Membership Options Page.');
1147
  /**/
1148
  shortCode.each (function() /* Focus and select the recommended Shortcode. */
1149
  {
@@ -1158,7 +1230,7 @@ jQuery(document).ready (function($)
1158
  var level = $('select#ws-plugin--s2member-reg-link-level').val ().replace (/[^0-9]/g, '');
1159
  var subscrID = $.trim ($('input#ws-plugin--s2member-reg-link-subscr-id').val ());
1160
  var custom = $.trim ($('input#ws-plugin--s2member-reg-link-custom').val ());
1161
- var cCaps = $.trim ($.trim ($('input#ws-plugin--s2member-reg-link-ccaps').val ()).replace (/[ \-]/g, '_').replace (/[^A-Z_0-9,]/gi, '').toLowerCase ());
1162
  var fixedTerm = $.trim ($('input#ws-plugin--s2member-reg-link-fixed-term').val ().replace (/[^A-Z 0-9]/gi, '').toUpperCase ());
1163
  var $link = $('p#ws-plugin--s2member-reg-link'), $loading = $('img#ws-plugin--s2member-reg-link-loading');
1164
  /**/
945
  /**/
946
  $('div.ws-menu-page input[id]').filter (function() /* Filter all input elements with an id. */
947
  {
948
+ return this.id.match (/^ws-plugin--s2member-(level[1-9][0-9]*|modification|ccap)-ccaps$/);
949
  }).keyup (function()
950
  {
951
+ var value = this.value.replace (/^(-all|-al|-a|-)[;,]*/gi, ''), _all = (this.value.match (/^(-all|-al|-a|-)[;,]*/i)) ? '-all,' : '';
952
+ if (value.match (/[^a-z_0-9,]/)) /* Only if there is a problem with the actual values; because this causes interruptions. */
953
+ this.value = _all + $.trim ($.trim (value).replace (/[ \-]/g, '_').replace (/[^a-z_0-9,]/gi, '').toLowerCase ());
954
  });
955
  /**/
956
  ws_plugin__s2member_paypalButtonGenerate = function(button) /* Handles PayPal® Button Generation. */
980
  var localeCode = '', digital = '0', noShipping = '1'; /* NOT yet configurable. */
981
  var pageStyle = $.trim ($('input#ws-plugin--s2member-' + button + '-page-style').val ().replace (/"/g, ''));
982
  var currencyCode = $('select#ws-plugin--s2member-' + button + '-currency').val ().replace (/[^A-Z]/g, '');
983
+ /**/
984
+ var cCaps = $.trim ($.trim ($('input#ws-plugin--s2member-' + button + '-ccaps').val ()).replace (/^(-all|-al|-a|-)[;,]*/gi, '').replace (/[ \-]/g, '_').replace (/[^a-z_0-9,]/gi, '').toLowerCase ());
985
+ cCaps = ($.trim ($('input#ws-plugin--s2member-' + button + '-ccaps').val ()).match (/^(-all|-al|-a|-)[;,]*/i)) ? ((cCaps) ? '-all,' : '-all') + cCaps.toLowerCase () : cCaps.toLowerCase ();
986
  /**/
987
  trialPeriod = (regRecur === 'BN') ? '0' : trialPeriod; /* Lifetime ( 1-L-BN ) and Buy Now ( BN ) access is absolutely NOT compatible w/ Trial Periods. */
988
  trialAmount = (!trialAmount || isNaN(trialAmount) || trialAmount < 0.01 || trialPeriod <= 0) ? '0' : trialAmount; /* Validate Trial Amount. */
1073
  /**/
1074
  $('div#ws-plugin--s2member-' + button + '-button-prev').html (code.val ().replace (/\<form/, '<form target="_blank"').replace (/\<\?php echo S2MEMBER_VALUE_FOR_PP_INV\(\); \?\>/g, Math.round (new Date ().getTime ()) + '~<?php echo c_ws_plugin__s2member_utils_strings::esc_sq (esc_attr ($_SERVER["REMOTE_ADDR"])); ?>').replace (/\<\?php echo S2MEMBER_CURRENT_USER_VALUE_FOR_PP_(ON0|OS0|ON1|OS1); \?\>/g, ''));
1075
  /**/
1076
+ (button === 'modification') ? alert('Your Modification Button has been generated.\nPlease copy/paste the Shortcode Format into your Login Welcome Page, or wherever you feel it would be most appropriate.\n\n* Remember, Modification Buttons should be displayed to existing Users/Members, and they should be logged-in, BEFORE clicking this Button.') : alert('Your Button has been generated.\nPlease copy/paste the Shortcode Format into your Membership Options Page.');
1077
+ /**/
1078
+ shortCode.each (function() /* Focus and select the recommended Shortcode. */
1079
+ {
1080
+ this.focus (), this.select ();
1081
+ });
1082
+ /**/
1083
+ return false;
1084
+ };
1085
+ /**/
1086
+ ws_plugin__s2member_paypalCcapButtonGenerate = function() /* Handles PayPal® Button Generation for Independent Capabilities. */
1087
+ {
1088
+ var shortCodeTemplate = '[s2Member-PayPal-Button %%attrs%% image="default" output="button" /]', shortCodeTemplateAttrs = '';
1089
+ /**/
1090
+ var shortCode = $('input#ws-plugin--s2member-ccap-shortcode');
1091
+ var code = $('textarea#ws-plugin--s2member-ccap-button');
1092
+ /**/
1093
+ var desc = $.trim ($('input#ws-plugin--s2member-ccap-desc').val ().replace (/"/g, ''));
1094
+ /**/
1095
+ var regAmount = $('input#ws-plugin--s2member-ccap-amount').val ().replace (/[^0-9\.]/g, '');
1096
+ var regPeriod = $('select#ws-plugin--s2member-ccap-term').val ().split ('-')[0].replace (/[^0-9]/g, '');
1097
+ var regTerm = $('select#ws-plugin--s2member-ccap-term').val ().split ('-')[1].replace (/[^A-Z]/g, '');
1098
+ var regRecur = $('select#ws-plugin--s2member-ccap-term').val ().split ('-')[2].replace (/[^0-1BN]/g, '');
1099
+ /**/
1100
+ var localeCode = '', digital = '0', noShipping = '1'; /* NOT yet configurable. */
1101
+ var pageStyle = $.trim ($('input#ws-plugin--s2member-ccap-page-style').val ().replace (/"/g, ''));
1102
+ var currencyCode = $('select#ws-plugin--s2member-ccap-currency').val ().replace (/[^A-Z]/g, '');
1103
+ /**/
1104
+ var cCaps = $.trim ($.trim ($('input#ws-plugin--s2member-ccap-ccaps').val ()).replace (/^(-all|-al|-a|-)[;,]*/gi, '').replace (/[ \-]/g, '_').replace (/[^a-z_0-9,]/gi, '').toLowerCase ());
1105
+ cCaps = ($.trim ($('input#ws-plugin--s2member-ccap-ccaps').val ()).match (/^(-all|-al|-a|-)[;,]*/i)) ? ((cCaps) ? '-all,' : '-all') + cCaps.toLowerCase () : cCaps.toLowerCase ();
1106
+ /**/
1107
+ var levelCcapsPer = (regRecur === 'BN' && regTerm !== 'L') ? '*:' + cCaps + ':' + regPeriod + ' ' + regTerm : '*:' + cCaps;
1108
+ levelCcapsPer = levelCcapsPer.replace (/\:+$/g, ''); /* Clean any trailing separators from this string. */
1109
+ /**/
1110
+ if (!cCaps || cCaps === '-all') /* Must have some Independent Custom Capabilities. */
1111
+ {
1112
+ alert('— Oops, a slight problem: —\n\nPlease provide at least one Custom Capability.');
1113
+ return false;
1114
+ }
1115
+ else if (!regAmount || isNaN(regAmount) || regAmount < 0.01)
1116
+ {
1117
+ alert('— Oops, a slight problem: —\n\nAmount must be >= 0.01');
1118
+ return false;
1119
+ }
1120
+ else if (regAmount > 10000.00) /* $10,000.00 maximum. */
1121
+ {
1122
+ alert('— Oops, a slight problem: —\n\nMaximum Amount is: 10000.00');
1123
+ return false;
1124
+ }
1125
+ else if (!desc) /* Each Button should have a Description. */
1126
+ {
1127
+ alert('— Oops, a slight problem: —\n\nPlease type a Description for this Button.');
1128
+ return false;
1129
+ }
1130
+ /**/
1131
+ shortCodeTemplateAttrs += 'level="*" ccaps="' + esc_attr(cCaps) + '" desc="' + esc_attr(desc) + '" ps="' + esc_attr(pageStyle) + '" lc="' + esc_attr(localeCode) + '" cc="' + esc_attr(currencyCode) + '" dg="' + esc_attr(digital) + '" ns="' + esc_attr(noShipping) + '"';
1132
+ shortCodeTemplateAttrs += ' custom="<?php echo c_ws_plugin__s2member_utils_strings::esc_sq (esc_attr ($_SERVER["HTTP_HOST"])); ?>" ra="' + esc_attr(regAmount) + '" rp="' + esc_attr(regPeriod) + '" rt="' + esc_attr(regTerm) + '" rr="' + esc_attr(regRecur) + '"';
1133
+ shortCode.val (shortCodeTemplate.replace (/%%attrs%%/, shortCodeTemplateAttrs));
1134
+ /**/
1135
+ code.html (code.val ().replace (/ name\="lc" value\="(.*?)"/, ' name="lc" value="' + esc_attr(localeCode) + '"'));
1136
+ code.html (code.val ().replace (/ name\="no_shipping" value\="(.*?)"/, ' name="no_shipping" value="' + esc_attr(noShipping) + '"'));
1137
+ code.html (code.val ().replace (/ name\="item_name" value\="(.*?)"/, ' name="item_name" value="' + esc_attr(desc) + '"'));
1138
+ code.html (code.val ().replace (/ name\="item_number" value\="(.*?)"/, ' name="item_number" value="' + esc_attr(levelCcapsPer) + '"'));
1139
+ code.html (code.val ().replace (/ name\="page_style" value\="(.*?)"/, ' name="page_style" value="' + esc_attr(pageStyle) + '"'));
1140
+ code.html (code.val ().replace (/ name\="currency_code" value\="(.*?)"/, ' name="currency_code" value="' + esc_attr(currencyCode) + '"'));
1141
+ code.html (code.val ().replace (/ name\="custom" value\="(.*?)"/, ' name="custom" value="<?php echo c_ws_plugin__s2member_utils_strings::esc_sq (esc_attr ($_SERVER["HTTP_HOST"])); ?>"'));
1142
+ /**/
1143
+ code.html (code.val ().replace (/ name\="amount" value\="(.*?)"/, ' name="amount" value="' + esc_attr(regAmount) + '"'));
1144
+ /**/
1145
+ $('div#ws-plugin--s2member-ccap-button-prev').html (code.val ().replace (/\<form/, '<form target="_blank"').replace (/\<\?php echo S2MEMBER_VALUE_FOR_PP_INV\(\); \?\>/g, Math.round (new Date ().getTime ()) + '~<?php echo c_ws_plugin__s2member_utils_strings::esc_sq (esc_attr ($_SERVER["REMOTE_ADDR"])); ?>').replace (/\<\?php echo S2MEMBER_CURRENT_USER_VALUE_FOR_PP_(ON0|OS0|ON1|OS1); \?\>/g, ''));
1146
+ /**/
1147
+ alert('Your Button has been generated.\nPlease copy/paste the Shortcode Format into your Login Welcome Page, or wherever you feel it would be most appropriate.\n\n* Remember, Independent Custom Capability Buttons should ONLY be displayed to existing Users/Members, and they MUST be logged-in, BEFORE clicking this Button.');
1148
  /**/
1149
  shortCode.each (function() /* Focus and select the recommended Shortcode. */
1150
  {
1215
  /**/
1216
  $('div#ws-plugin--s2member-sp-button-prev').html (code.val ().replace (/\<form/, '<form target="_blank"').replace (/\<\?php echo S2MEMBER_VALUE_FOR_PP_INV\(\); \?\>/g, Math.round (new Date ().getTime ()) + '~<?php echo c_ws_plugin__s2member_utils_strings::esc_sq (esc_attr ($_SERVER["REMOTE_ADDR"])); ?>').replace (/\<\?php echo S2MEMBER_CURRENT_USER_VALUE_FOR_PP_(ON0|OS0|ON1|OS1); \?\>/g, ''));
1217
  /**/
1218
+ alert('Your Button has been generated.\nPlease copy/paste the Shortcode Format into your WordPress® Editor.');
1219
  /**/
1220
  shortCode.each (function() /* Focus and select the recommended Shortcode. */
1221
  {
1230
  var level = $('select#ws-plugin--s2member-reg-link-level').val ().replace (/[^0-9]/g, '');
1231
  var subscrID = $.trim ($('input#ws-plugin--s2member-reg-link-subscr-id').val ());
1232
  var custom = $.trim ($('input#ws-plugin--s2member-reg-link-custom').val ());
1233
+ var cCaps = $.trim ($.trim ($('input#ws-plugin--s2member-reg-link-ccaps').val ()).replace (/[ \-]/g, '_').replace (/[^a-z_0-9,]/gi, '').toLowerCase ());
1234
  var fixedTerm = $.trim ($('input#ws-plugin--s2member-reg-link-fixed-term').val ().replace (/[^A-Z 0-9]/gi, '').toUpperCase ());
1235
  var $link = $('p#ws-plugin--s2member-reg-link'), $loading = $('img#ws-plugin--s2member-reg-link-loading');
1236
  /**/
includes/menu-pages/menu-pages.css CHANGED
@@ -143,16 +143,17 @@ table.ws-menu-page-table > tbody > tr
143
  {
144
  vertical-align: top;
145
  }
146
- /*
147
- Specifically for the main content area on the left side.
148
- These CSS selectors address common layout styles.
149
- */
150
  table.ws-menu-page-table td.ws-menu-page-table-l
151
  {
152
  padding: 0;
153
  width: 100%;
154
  }
155
- table.ws-menu-page-table td.ws-menu-page-table-l img.ws-menu-page-brand-icon
 
 
 
 
 
156
  {
157
  border: 0px;
158
  float: right;
@@ -161,7 +162,7 @@ table.ws-menu-page-table td.ws-menu-page-table-l img.ws-menu-page-brand-icon
161
  margin: 0 0 0 25px;
162
  vertical-align: middle;
163
  }
164
- table.ws-menu-page-table td.ws-menu-page-table-l img.ws-menu-page-brand-updates
165
  {
166
  border: 0px;
167
  float: right;
@@ -170,18 +171,18 @@ table.ws-menu-page-table td.ws-menu-page-table-l img.ws-menu-page-brand-updates
170
  margin: 0 -153px 0 25px;
171
  vertical-align: middle;
172
  }
173
- table.ws-menu-page-table td.ws-menu-page-table-l p.submit
174
  {
175
  margin: 0;
176
  padding: 0;
177
  }
178
- table.ws-menu-page-table td.ws-menu-page-table-l a[rel ~= "external"]
179
  {
180
  padding-right: 18px;
181
  background: url('<?php echo $i; ?>/brand-xlink.png') no-repeat center right;
182
  }
183
- table.ws-menu-page-table td.ws-menu-page-table-l div.ws-menu-page-groups-show,
184
- table.ws-menu-page-table td.ws-menu-page-table-l div.ws-menu-page-groups-hide
185
  {
186
  float: right;
187
  color: #333333;
@@ -200,12 +201,13 @@ table.ws-menu-page-table td.ws-menu-page-table-l div.ws-menu-page-groups-hide
200
  -webkit-user-select: none;
201
  user-select: none;
202
  }
203
- table.ws-menu-page-table td.ws-menu-page-table-l div.ws-menu-page-groups-hide
204
  {
205
  color: #999999;
206
  border-color: #999999;
207
  }
208
- table.ws-menu-page-table td.ws-menu-page-table-l div.ws-menu-page-group-header
 
209
  {
210
  color: #666666;
211
  padding: 10px;
@@ -224,7 +226,8 @@ table.ws-menu-page-table td.ws-menu-page-table-l div.ws-menu-page-group-header
224
  -webkit-user-select: none;
225
  user-select: none;
226
  }
227
- table.ws-menu-page-table td.ws-menu-page-table-l div.ws-menu-page-group-header > ins
 
228
  {
229
  width: 22px;
230
  height: 22px;
@@ -247,19 +250,24 @@ table.ws-menu-page-table td.ws-menu-page-table-l div.ws-menu-page-group-header >
247
  display: inline !ie<8;
248
  margin-top: 0 !ie<8;
249
  }
250
- table.ws-menu-page-table td.ws-menu-page-table-l div.ws-menu-page-group-header:hover,
251
- table.ws-menu-page-table td.ws-menu-page-table-l div.ws-menu-page-group-header.open
 
 
252
  {
253
  color: #164A61;
254
  border-color: #666666;
255
  }
256
- table.ws-menu-page-table td.ws-menu-page-table-l div.ws-menu-page-group-header:hover > ins,
257
- table.ws-menu-page-table td.ws-menu-page-table-l div.ws-menu-page-group-header.open > ins
 
 
258
  {
259
  color: #FFFFFF;
260
  background: #164A61;
261
  }
262
- table.ws-menu-page-table td.ws-menu-page-table-l div.ws-menu-page-group
 
263
  {
264
  display: none;
265
  margin: -35px 5px 0 5px;
@@ -270,41 +278,37 @@ table.ws-menu-page-table td.ws-menu-page-table-l div.ws-menu-page-group
270
  border-radius: 5px;
271
  background: #FFFFFF url('<?php echo $i; ?>/brand-gradient-bg.png') repeat-x;
272
  }
273
- table.ws-menu-page-table td.ws-menu-page-table-l div.ws-menu-page-group > div.ws-menu-page-hr
 
274
  {
275
  background: #666666;
276
  margin: 15px 0 15px 0;
277
  }
278
- table.ws-menu-page-table td.ws-menu-page-table-l div.ws-menu-page-section table.form-table > tbody > tr
279
  {
280
  vertical-align: top;
281
  }
282
- table.ws-menu-page-table td.ws-menu-page-table-l div.ws-menu-page-section table.form-table > tbody > tr > th
283
  {
284
  width: auto;
285
  color: #164A61;
286
- padding-bottom: 0;
287
- }
288
- table.ws-menu-page-table td.ws-menu-page-table-l div.ws-menu-page-group > div.ws-menu-page-section table.form-table > tbody > tr > th
289
- {
290
- padding-left: 0;
291
  }
292
- table.ws-menu-page-table td.ws-menu-page-table-l div.ws-menu-page-section table.form-table > tbody > tr > th.ws-menu-page-th-side
293
  {
294
  width: 200px;
295
  }
296
- table.ws-menu-page-table td.ws-menu-page-table-l div.ws-menu-page-section table.form-table > tbody > tr > td
297
  {
298
  width: auto;
 
299
  }
300
- table.ws-menu-page-table td.ws-menu-page-table-l div.ws-menu-page-group > div.ws-menu-page-section table.form-table > tbody > tr > td
301
- {
302
- padding-left: 0;
303
- }
304
- table.ws-menu-page-table td.ws-menu-page-table-l div.ws-menu-page-section table.form-table > tbody > tr > td > input[type = "text"],
305
- table.ws-menu-page-table td.ws-menu-page-table-l div.ws-menu-page-section table.form-table > tbody > tr > td > input[type = "password"],
306
- table.ws-menu-page-table td.ws-menu-page-table-l div.ws-menu-page-section table.form-table > tbody > tr > td > textarea,
307
- table.ws-menu-page-table td.ws-menu-page-table-l div.ws-menu-page-section table.form-table > tbody > tr > td > select
308
  {
309
  width: 100%; /* 100% does not work across all browsers. */
310
  width: 98% !ie<8; /* 100% does not work in IE browsers < 8. */
@@ -313,36 +317,36 @@ table.ws-menu-page-table td.ws-menu-page-table-l div.ws-menu-page-section table.
313
  -moz-box-sizing: border-box;
314
  -webkit-box-sizing: border-box;
315
  }
316
- table.ws-menu-page-table td.ws-menu-page-table-l div.ws-menu-page-section table.form-table > tbody > tr > td > input[type = "checkbox"],
317
- table.ws-menu-page-table td.ws-menu-page-table-l div.ws-menu-page-section table.form-table > tbody > tr > td > input[type = "radio"]
318
  {
319
  margin-right: 3px;
320
  vertical-align: middle;
321
  }
322
- table.ws-menu-page-table td.ws-menu-page-table-l div.ws-menu-page-section table.form-table > tbody > tr > td > input[type = "button"].ws-menu-page-media-btn
323
  {
324
  float: left;
325
  margin: 5px 25px 0 0;
326
  }
327
- table.ws-menu-page-table td.ws-menu-page-table-l div.ws-menu-page-section table.form-table > tbody > tr > td > textarea
328
  {
329
  font-family: 'Courier New', monospace;
330
  }
331
- table.ws-menu-page-table td.ws-menu-page-table-l div.ws-menu-page-section table.form-table > tbody > tr > td > select
332
  {
333
  width: 99.5% !ie<8; /* Required in IE < 8. */
334
  }
335
- table.ws-menu-page-table td.ws-menu-page-table-l div.ws-menu-page-section table.form-table > tbody > tr > td > ol
336
  {
337
  margin: 10px 0 10px 20px;
338
- list-style: decimal outside;
339
  }
340
- table.ws-menu-page-table td.ws-menu-page-table-l div.ws-menu-page-section table.form-table > tbody > tr > td > ul
341
  {
342
  margin: 10px 0 10px 20px;
343
- list-style: disc outside;
344
  }
345
- table.ws-menu-page-table td.ws-menu-page-table-l div.ws-menu-page-section table.form-table > tbody > tr > td > div.ws-menu-page-scrollbox
346
  {
347
  margin: 1px;
348
  padding: 5px;
@@ -356,103 +360,55 @@ table.ws-menu-page-table td.ws-menu-page-table-l div.ws-menu-page-section table.
356
  border-radius: 4px;
357
  }
358
  /*
359
- Specifically for the main content area on the left side.
360
- - Specifically for info pages with readme files.
361
  These CSS selectors address common layout styles.
362
  */
363
- table.ws-menu-page-table td.ws-menu-page-table-l div.ws-menu-page-readme > div.readme > div.section
364
  {
365
  margin: 0 0 20px 0;
366
  padding: 0 0 20px 0;
367
  border: 0 solid #DDDDDD;
368
  border-width: 0 0 1px 0;
369
  }
370
- table.ws-menu-page-table td.ws-menu-page-table-l div.ws-menu-page-readme > div.readme > div.section > h2
371
  {
372
  margin-top: 0;
373
  padding-top: 0;
374
  font-size: 150%;
375
  }
376
- table.ws-menu-page-table td.ws-menu-page-table-l div.ws-menu-page-readme > div.readme > div.section > div.content ul
377
  {
378
  padding: 0;
379
  margin: 10px 0 0 25px;
380
  list-style: disc outside;
381
  }
382
- table.ws-menu-page-table td.ws-menu-page-table-l div.ws-menu-page-readme > div.readme > div.section > div.content ol
383
  {
384
  padding: 0;
385
  margin: 10px 0 0 25px;
386
  list-style: decimal outside;
387
  }
388
  /*
389
- Specifically for the main content area on the left side.
390
- - Specifically for pages with a FeedBurner block.
391
- These CSS selectors address common layout styles.
392
- */
393
- table.ws-menu-page-table td.ws-menu-page-table-l div.feedburnerFeedBlock
394
- {
395
- margin: 0 0 20px 0;
396
- }
397
- table.ws-menu-page-table td.ws-menu-page-table-l div.feedburnerFeedBlock > ul > li
398
- {
399
- margin: 25px 0 0 0;
400
- padding: 0 0 20px 0;
401
- border: 0 solid #DDDDDD;
402
- border-width: 0 0 1px 0;
403
- }
404
- table.ws-menu-page-table td.ws-menu-page-table-l div.feedburnerFeedBlock > ul > li:first-child
405
- {
406
- margin-top: 0;
407
- }
408
- table.ws-menu-page-table td.ws-menu-page-table-l div.feedburnerFeedBlock > ul > li > span.headline
409
- {
410
- font-size: 150%;
411
- font-family: 'Georgia', serif;
412
- }
413
- table.ws-menu-page-table td.ws-menu-page-table-l div.feedburnerFeedBlock > ul > li > p.date
414
- {
415
- font-size: 130%;
416
- font-family: 'Georgia', serif;
417
- }
418
- table.ws-menu-page-table td.ws-menu-page-table-l div.feedburnerFeedBlock > ul > li > div > div.feedflare
419
- {
420
- margin: 10px 0 0 0;
421
- }
422
- table.ws-menu-page-table td.ws-menu-page-table-l div.feedburnerFeedBlock > p.fbsubscribelink
423
- {
424
- margin: 25px 0 0 0;
425
- }
426
- /*
427
  Specifically for the right sidebar panel.
428
  These CSS selectors address common layout styles.
429
  */
430
- table.ws-menu-page-table td.ws-menu-page-table-r
431
- {
432
- padding: 0;
433
- text-align: right;
434
- }
435
- table.ws-menu-page-table td.ws-menu-page-table-r a[rel ~= "external"]
436
- {
437
- padding-right: 18px;
438
- background: url('<?php echo $i; ?>/brand-xlink.png') no-repeat center right;
439
- }
440
- table.ws-menu-page-table td.ws-menu-page-table-r div.ws-menu-page-mlist,
441
- table.ws-menu-page-table td.ws-menu-page-table-r div.ws-menu-page-installation,
442
- table.ws-menu-page-table td.ws-menu-page-table-r div.ws-menu-page-tools,
443
- table.ws-menu-page-table td.ws-menu-page-table-r div.ws-menu-page-videos,
444
- table.ws-menu-page-table td.ws-menu-page-table-r div.ws-menu-page-support,
445
- table.ws-menu-page-table td.ws-menu-page-table-r div.ws-menu-page-donations,
446
- table.ws-menu-page-table td.ws-menu-page-table-r div.ws-menu-page-others
447
  {
 
448
  margin: 0 0 25px 25px;
449
  }
450
- table.ws-menu-page-table td.ws-menu-page-table-r div.ws-menu-page-installation img,
451
- table.ws-menu-page-table td.ws-menu-page-table-r div.ws-menu-page-tools img,
452
- table.ws-menu-page-table td.ws-menu-page-table-r div.ws-menu-page-videos img,
453
- table.ws-menu-page-table td.ws-menu-page-table-r div.ws-menu-page-support img,
454
- table.ws-menu-page-table td.ws-menu-page-table-r div.ws-menu-page-donations img,
455
- table.ws-menu-page-table td.ws-menu-page-table-r div.ws-menu-page-others img
456
  {
457
  border: 0;
458
  width: 200px;
@@ -463,101 +419,51 @@ Specifically for the right sidebar panel.
463
  - Specifically for the mailing list box.
464
  These CSS selectors address common layout styles.
465
  */
466
- td.ws-menu-page-table-r div.ws-menu-page-mlist
467
- {
468
- text-align: left;
469
- }
470
- td.ws-menu-page-table-r div.ws-menu-page-mlist div#ws-mlist-div-feed-animator,
471
- td.ws-menu-page-table-r div.ws-menu-page-mlist div#ws-mlist-div-header,
472
- td.ws-menu-page-table-r div.ws-menu-page-mlist div#ws-mlist-div-container
473
  {
474
- background: #FFFFFF;
475
- margin: 0 auto 0 auto;
476
- border: 1px solid #CCCCCC;
477
- -moz-border-radius: 5px;
478
- -webkit-border-radius: 5px;
479
- border-radius: 5px;
480
  }
481
- td.ws-menu-page-table-r div.ws-menu-page-mlist div#ws-mlist-div-feed-animator,
482
- td.ws-menu-page-table-r div.ws-menu-page-mlist div#ws-mlist-div-header
483
  {
484
- padding: 10px;
485
- color: #666666;
486
- cursor: pointer;
487
- font-size: 145%;
488
- margin-bottom: -7px;
489
- position: relative;
490
- font-family: 'Georgia', serif;
491
- vertical-align: middle;
492
  -moz-user-select: none;
493
  -webkit-user-select: none;
494
  user-select: none;
495
  }
496
- td.ws-menu-page-table-r div.ws-menu-page-mlist div#ws-mlist-div-feed-animator
497
- {
498
- margin: 0 0 15px 0;
499
- }
500
- td.ws-menu-page-table-r div.ws-menu-page-mlist div#ws-mlist-div-header > ins
501
- {
502
- width: 22px;
503
- height: 22px;
504
- color: #CCCCCC;
505
- font-size: 17px;
506
- line-height: 22px;
507
- font-weight: bold;
508
- text-align: center;
509
- margin: -2px 13px 0 0;
510
- background: #666666;
511
- text-decoration: none;
512
- font-family: monospace;
513
- vertical-align: middle;
514
- border: 1px solid transparent;
515
- -moz-border-radius: 5px;
516
- -webkit-border-radius: 5px;
517
- border-radius: 5px;
518
- display: inline-block;
519
- zoom: 1 !ie<8;
520
- display: inline !ie<8;
521
- margin-top: 0 !ie<8;
522
- }
523
- td.ws-menu-page-table-r div.ws-menu-page-mlist div#ws-mlist-div-header:hover,
524
- td.ws-menu-page-table-r div.ws-menu-page-mlist div#ws-mlist-div-header.open
525
  {
526
- color: #164A61;
527
- border-color: #666666;
528
  }
529
- td.ws-menu-page-table-r div.ws-menu-page-mlist div#ws-mlist-div-header:hover > ins,
530
- td.ws-menu-page-table-r div.ws-menu-page-mlist div#ws-mlist-div-header.open > ins
531
  {
532
- color: #FFFFFF;
533
- background: #164A61;
534
  }
535
- td.ws-menu-page-table-r div.ws-menu-page-mlist div#ws-mlist-div-container
536
  {
537
- width: 178px;
538
  display: none;
539
- margin: 0 auto 0 auto;
540
- padding: 20px 10px 10px 10px;
541
- background: #FFFFFF url('<?php echo $i; ?>/brand-gradient-bg.png') repeat-x;
542
  }
543
- td.ws-menu-page-table-r div.ws-menu-page-mlist div#ws-mlist-div-container div#ws-mlist-div-fname,
544
- td.ws-menu-page-table-r div.ws-menu-page-mlist div#ws-mlist-div-container div#ws-mlist-div-lname,
545
- td.ws-menu-page-table-r div.ws-menu-page-mlist div#ws-mlist-div-container div#ws-mlist-div-email,
546
- td.ws-menu-page-table-r div.ws-menu-page-mlist div#ws-mlist-div-container div#ws-mlist-div-groups,
547
- td.ws-menu-page-table-r div.ws-menu-page-mlist div#ws-mlist-div-container div#ws-mlist-div-subs
548
- td.ws-menu-page-table-r div.ws-menu-page-mlist div#ws-mlist-div-container div#ws-mlist-div-priv
549
  {
550
  margin: 0 0 10px 0;
551
  }
552
- td.ws-menu-page-table-r div.ws-menu-page-mlist div#ws-mlist-div-container div#ws-mlist-div-subs
553
  {
554
  margin: 15px 0 0 0;
555
  }
556
- td.ws-menu-page-table-r div.ws-menu-page-mlist div#ws-mlist-div-container input[type = "text"],
557
- td.ws-menu-page-table-r div.ws-menu-page-mlist div#ws-mlist-div-container input[type = "password"],
558
- td.ws-menu-page-table-r div.ws-menu-page-mlist div#ws-mlist-div-container input[type = "submit"],
559
- td.ws-menu-page-table-r div.ws-menu-page-mlist div#ws-mlist-div-container textarea,
560
- td.ws-menu-page-table-r div.ws-menu-page-mlist div#ws-mlist-div-container select
561
  {
562
  width: 100%; /* 100% does not work across all browsers. */
563
  width: 98% !ie<8; /* 100% does not work in IE browsers < 8. */
@@ -566,33 +472,28 @@ td.ws-menu-page-table-r div.ws-menu-page-mlist div#ws-mlist-div-container select
566
  -moz-box-sizing: border-box;
567
  -webkit-box-sizing: border-box;
568
  }
569
- td.ws-menu-page-table-r div.ws-menu-page-mlist div#ws-mlist-div-container input[type = "checkbox"],
570
- td.ws-menu-page-table-r div.ws-menu-page-mlist div#ws-mlist-div-container input[type = "radio"]
571
  {
572
  margin-right: 3px;
573
  vertical-align: middle;
574
  }
575
- td.ws-menu-page-table-r div.ws-menu-page-mlist div#ws-mlist-div-container input[type = "submit"]
576
  {
577
  width: 100% !ie<8; /* This width required in IE < 8. */
578
  }
579
- td.ws-menu-page-table-r div.ws-menu-page-mlist div#ws-mlist-div-container select
580
  {
581
  width: 99.5% !ie<8; /* Required in IE < 8. */
582
  }
583
- td.ws-menu-page-table-r div.ws-menu-page-mlist div#ws-mlist-div-container div#ws-mlist-div-groups > ul > li
 
584
  {
585
  margin: 0;
586
  font-size: 90%;
587
- -moz-user-select: none;
588
- -webkit-user-select: none;
589
- user-select: none;
590
- }
591
- td.ws-menu-page-table-r div.ws-menu-page-mlist div#ws-mlist-div-container div#ws-mlist-div-subs > ul
592
- {
593
- margin: 0 auto 0 auto;
594
  }
595
- td.ws-menu-page-table-r div.ws-menu-page-mlist div#ws-mlist-div-container div#ws-mlist-div-priv
596
  {
597
  font-size: 80%;
598
  margin: 0 0 5px 0;
143
  {
144
  vertical-align: top;
145
  }
 
 
 
 
146
  table.ws-menu-page-table td.ws-menu-page-table-l
147
  {
148
  padding: 0;
149
  width: 100%;
150
  }
151
+ table.ws-menu-page-table td.ws-menu-page-table-r
152
+ {
153
+ padding: 0;
154
+ width: auto;
155
+ }
156
+ table.ws-menu-page-table img.ws-menu-page-brand-icon
157
  {
158
  border: 0px;
159
  float: right;
162
  margin: 0 0 0 25px;
163
  vertical-align: middle;
164
  }
165
+ table.ws-menu-page-table img.ws-menu-page-brand-updates
166
  {
167
  border: 0px;
168
  float: right;
171
  margin: 0 -153px 0 25px;
172
  vertical-align: middle;
173
  }
174
+ table.ws-menu-page-table p.submit
175
  {
176
  margin: 0;
177
  padding: 0;
178
  }
179
+ table.ws-menu-page-table a[rel ~= "external"]
180
  {
181
  padding-right: 18px;
182
  background: url('<?php echo $i; ?>/brand-xlink.png') no-repeat center right;
183
  }
184
+ table.ws-menu-page-table div.ws-menu-page-groups-show,
185
+ table.ws-menu-page-table div.ws-menu-page-groups-hide
186
  {
187
  float: right;
188
  color: #333333;
201
  -webkit-user-select: none;
202
  user-select: none;
203
  }
204
+ table.ws-menu-page-table div.ws-menu-page-groups-hide
205
  {
206
  color: #999999;
207
  border-color: #999999;
208
  }
209
+ table.ws-menu-page-table div.ws-menu-page-group-header,
210
+ table.ws-menu-page-table div.ws-menu-page-r-group-header
211
  {
212
  color: #666666;
213
  padding: 10px;
226
  -webkit-user-select: none;
227
  user-select: none;
228
  }
229
+ table.ws-menu-page-table div.ws-menu-page-group-header > ins,
230
+ table.ws-menu-page-table div.ws-menu-page-r-group-header > ins
231
  {
232
  width: 22px;
233
  height: 22px;
250
  display: inline !ie<8;
251
  margin-top: 0 !ie<8;
252
  }
253
+ table.ws-menu-page-table div.ws-menu-page-group-header:hover,
254
+ table.ws-menu-page-table div.ws-menu-page-group-header.open,
255
+ table.ws-menu-page-table div.ws-menu-page-r-group-header:hover,
256
+ table.ws-menu-page-table div.ws-menu-page-r-group-header.open
257
  {
258
  color: #164A61;
259
  border-color: #666666;
260
  }
261
+ table.ws-menu-page-table div.ws-menu-page-group-header:hover > ins,
262
+ table.ws-menu-page-table div.ws-menu-page-group-header.open > ins,
263
+ table.ws-menu-page-table div.ws-menu-page-r-group-header:hover > ins,
264
+ table.ws-menu-page-table div.ws-menu-page-r-group-header.open > ins
265
  {
266
  color: #FFFFFF;
267
  background: #164A61;
268
  }
269
+ table.ws-menu-page-table div.ws-menu-page-group,
270
+ table.ws-menu-page-table div.ws-menu-page-r-group
271
  {
272
  display: none;
273
  margin: -35px 5px 0 5px;
278
  border-radius: 5px;
279
  background: #FFFFFF url('<?php echo $i; ?>/brand-gradient-bg.png') repeat-x;
280
  }
281
+ table.ws-menu-page-table div.ws-menu-page-group > div.ws-menu-page-hr,
282
+ table.ws-menu-page-table div.ws-menu-page-r-group > div.ws-menu-page-hr
283
  {
284
  background: #666666;
285
  margin: 15px 0 15px 0;
286
  }
287
+ table.ws-menu-page-table div.ws-menu-page-group table.form-table > tbody > tr
288
  {
289
  vertical-align: top;
290
  }
291
+ table.ws-menu-page-table div.ws-menu-page-group table.form-table > tbody > tr > th
292
  {
293
  width: auto;
294
  color: #164A61;
295
+ font-size: 115%;
296
+ padding: 10px 10px 0 0;
297
+ font-family: 'Georgia', serif;
 
 
298
  }
299
+ table.ws-menu-page-table div.ws-menu-page-group table.form-table > tbody > tr > th.ws-menu-page-th-side
300
  {
301
  width: 200px;
302
  }
303
+ table.ws-menu-page-table div.ws-menu-page-group table.form-table > tbody > tr > td
304
  {
305
  width: auto;
306
+ padding: 8px 10px 8px 0;
307
  }
308
+ table.ws-menu-page-table div.ws-menu-page-group table.form-table > tbody > tr > td > input[type = "text"],
309
+ table.ws-menu-page-table div.ws-menu-page-group table.form-table > tbody > tr > td > input[type = "password"],
310
+ table.ws-menu-page-table div.ws-menu-page-group table.form-table > tbody > tr > td > textarea,
311
+ table.ws-menu-page-table div.ws-menu-page-group table.form-table > tbody > tr > td > select
 
 
 
 
312
  {
313
  width: 100%; /* 100% does not work across all browsers. */
314
  width: 98% !ie<8; /* 100% does not work in IE browsers < 8. */
317
  -moz-box-sizing: border-box;
318
  -webkit-box-sizing: border-box;
319
  }
320
+ table.ws-menu-page-table div.ws-menu-page-group table.form-table > tbody > tr > td > input[type = "checkbox"],
321
+ table.ws-menu-page-table div.ws-menu-page-group table.form-table > tbody > tr > td > input[type = "radio"]
322
  {
323
  margin-right: 3px;
324
  vertical-align: middle;
325
  }
326
+ table.ws-menu-page-table div.ws-menu-page-group table.form-table > tbody > tr > td > input[type = "button"].ws-menu-page-media-btn
327
  {
328
  float: left;
329
  margin: 5px 25px 0 0;
330
  }
331
+ table.ws-menu-page-table div.ws-menu-page-group table.form-table > tbody > tr > td > textarea
332
  {
333
  font-family: 'Courier New', monospace;
334
  }
335
+ table.ws-menu-page-table div.ws-menu-page-group table.form-table > tbody > tr > td > select
336
  {
337
  width: 99.5% !ie<8; /* Required in IE < 8. */
338
  }
339
+ table.ws-menu-page-table div.ws-menu-page-group table.form-table > tbody > tr > td > ul
340
  {
341
  margin: 10px 0 10px 20px;
342
+ list-style: disc outside;
343
  }
344
+ table.ws-menu-page-table div.ws-menu-page-group table.form-table > tbody > tr > td > ol
345
  {
346
  margin: 10px 0 10px 20px;
347
+ list-style: decimal outside;
348
  }
349
+ table.ws-menu-page-table div.ws-menu-page-group table.form-table > tbody > tr > td > div.ws-menu-page-scrollbox
350
  {
351
  margin: 1px;
352
  padding: 5px;
360
  border-radius: 4px;
361
  }
362
  /*
363
+ Specifically for info pages with readme files.
 
364
  These CSS selectors address common layout styles.
365
  */
366
+ div.ws-menu-page-readme > div.readme > div.section
367
  {
368
  margin: 0 0 20px 0;
369
  padding: 0 0 20px 0;
370
  border: 0 solid #DDDDDD;
371
  border-width: 0 0 1px 0;
372
  }
373
+ div.ws-menu-page-readme > div.readme > div.section > h2
374
  {
375
  margin-top: 0;
376
  padding-top: 0;
377
  font-size: 150%;
378
  }
379
+ div.ws-menu-page-readme > div.readme > div.section > div.content ul
380
  {
381
  padding: 0;
382
  margin: 10px 0 0 25px;
383
  list-style: disc outside;
384
  }
385
+ div.ws-menu-page-readme > div.readme > div.section > div.content ol
386
  {
387
  padding: 0;
388
  margin: 10px 0 0 25px;
389
  list-style: decimal outside;
390
  }
391
  /*
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
392
  Specifically for the right sidebar panel.
393
  These CSS selectors address common layout styles.
394
  */
395
+ td.ws-menu-page-table-r div.ws-menu-page-mlist,
396
+ td.ws-menu-page-table-r div.ws-menu-page-installation,
397
+ td.ws-menu-page-table-r div.ws-menu-page-tools,
398
+ td.ws-menu-page-table-r div.ws-menu-page-videos,
399
+ td.ws-menu-page-table-r div.ws-menu-page-support,
400
+ td.ws-menu-page-table-r div.ws-menu-page-donations,
401
+ td.ws-menu-page-table-r div.ws-menu-page-others
 
 
 
 
 
 
 
 
 
 
402
  {
403
+ width: 200px;
404
  margin: 0 0 25px 25px;
405
  }
406
+ td.ws-menu-page-table-r div.ws-menu-page-installation img,
407
+ td.ws-menu-page-table-r div.ws-menu-page-tools img,
408
+ td.ws-menu-page-table-r div.ws-menu-page-videos img,
409
+ td.ws-menu-page-table-r div.ws-menu-page-support img,
410
+ td.ws-menu-page-table-r div.ws-menu-page-donations img,
411
+ td.ws-menu-page-table-r div.ws-menu-page-others img
412
  {
413
  border: 0;
414
  width: 200px;
419
  - Specifically for the mailing list box.
420
  These CSS selectors address common layout styles.
421
  */
422
+ div.ws-menu-page-mlist ul
 
 
 
 
 
 
423
  {
424
+ padding: 0;
425
+ margin: 0 0 0 12px;
426
+ list-style: square outside;
 
 
 
427
  }
428
+ div.ws-menu-page-mlist ul > li
 
429
  {
430
+ padding: 0;
431
+ margin: 5px 0 5px 0;
 
 
 
 
 
 
432
  -moz-user-select: none;
433
  -webkit-user-select: none;
434
  user-select: none;
435
  }
436
+ div.ws-menu-page-mlist ul > li:first-child
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
437
  {
438
+ margin-top: 0;
 
439
  }
440
+ div.ws-menu-page-mlist a[target = "_blank"]
 
441
  {
442
+ padding-right: 18px;
443
+ background: url('<?php echo $i; ?>/brand-xlink.png') no-repeat center right;
444
  }
445
+ div.ws-menu-page-mlist div#creditfooter
446
  {
 
447
  display: none;
 
 
 
448
  }
449
+ div.ws-menu-page-mlist div#ws-mlist-div-fname,
450
+ div.ws-menu-page-mlist div#ws-mlist-div-lname,
451
+ div.ws-menu-page-mlist div#ws-mlist-div-email,
452
+ div.ws-menu-page-mlist div#ws-mlist-div-groups,
453
+ div.ws-menu-page-mlist div#ws-mlist-div-subs,
454
+ div.ws-menu-page-mlist div#ws-mlist-div-priv
455
  {
456
  margin: 0 0 10px 0;
457
  }
458
+ div.ws-menu-page-mlist div#ws-mlist-div-subs
459
  {
460
  margin: 15px 0 0 0;
461
  }
462
+ div.ws-menu-page-mlist input[type = "text"],
463
+ div.ws-menu-page-mlist input[type = "password"],
464
+ div.ws-menu-page-mlist input[type = "submit"],
465
+ div.ws-menu-page-mlist textarea,
466
+ div.ws-menu-page-mlist select
467
  {
468
  width: 100%; /* 100% does not work across all browsers. */
469
  width: 98% !ie<8; /* 100% does not work in IE browsers < 8. */
472
  -moz-box-sizing: border-box;
473
  -webkit-box-sizing: border-box;
474
  }
475
+ div.ws-menu-page-mlist input[type = "checkbox"],
476
+ div.ws-menu-page-mlist input[type = "radio"]
477
  {
478
  margin-right: 3px;
479
  vertical-align: middle;
480
  }
481
+ div.ws-menu-page-mlist input[type = "submit"]
482
  {
483
  width: 100% !ie<8; /* This width required in IE < 8. */
484
  }
485
+ div.ws-menu-page-mlist select
486
  {
487
  width: 99.5% !ie<8; /* Required in IE < 8. */
488
  }
489
+ div.ws-menu-page-mlist div#ws-mlist-div-groups > ul,
490
+ div.ws-menu-page-mlist div#ws-mlist-div-groups > ul > li
491
  {
492
  margin: 0;
493
  font-size: 90%;
494
+ list-style: none;
 
 
 
 
 
 
495
  }
496
+ div.ws-menu-page-mlist div#ws-mlist-div-priv
497
  {
498
  font-size: 80%;
499
  margin: 0 0 5px 0;
includes/menu-pages/menu-pages.js CHANGED
@@ -23,48 +23,6 @@ These routines address common layout styles for menu pages.
23
  */
24
  jQuery(document).ready (function($)
25
  {
26
- $('div#ws-mlist-div-header').click (function()
27
- {
28
- var $this = $(this), $container = $('div#ws-mlist-div-container');
29
- /**/
30
- if ($container.css ('display') === 'none')
31
- $('ins', $this).html ('-'), $this.addClass ('open'), $container.show ();
32
- /**/
33
- else /* Otherwise, we hide it. */
34
- {
35
- $('ins', $this).html ('+'), $this.removeClass ('open');
36
- $container.hide ();
37
- }
38
- /**/
39
- return false;
40
- });
41
- /**/
42
- $('form#ws-mlist-form').submit (function()
43
- {
44
- var errors = ''; /* Intialize string of errors. */
45
- /**/
46
- if (!$.trim ($('input#ws-mlist-fname').val ()))
47
- errors += 'First Name missing, please try again.\n\n';
48
- /**/
49
- if (!$.trim ($('input#ws-mlist-lname').val ()))
50
- errors += 'Last Name missing, please try again.\n\n';
51
- /**/
52
- if (!$.trim ($('input#ws-mlist-email').val ()))
53
- errors += 'Email missing, please try again.\n\n';
54
- /**/
55
- else if (!$('input#ws-mlist-email').val ().match (/^([a-z_~0-9\+\-]+)(((\.?)([a-z_~0-9\+\-]+))*)(@)([a-z0-9]+)(((-*)([a-z0-9]+))*)(((\.)([a-z0-9]+)(((-*)([a-z0-9]+))*))*)(\.)([a-z]{2,6})$/i))
56
- errors += 'Invalid email address, please try again.\n\n';
57
- /**/
58
- if (errors = $.trim (errors))
59
- {
60
- alert('— Oops, you missed something: —\n\n' + errors);
61
- /**/
62
- return false;
63
- }
64
- /**/
65
- return true;
66
- });
67
- /**/
68
  var $groups = $('div.ws-menu-page-group'); /* Query groups. */
69
  $groups.each (function(index) /* Go through each group, one at a time. */
70
  {
@@ -124,22 +82,35 @@ jQuery(document).ready (function($)
124
  return; /* Return for uniformity. */
125
  });
126
  /**/
127
- $('div.ws-menu-page-section:first > h3').css ({'margin-top': '0'});
128
- $('div.ws-menu-page-group-header:first').css ({'margin-top': '0'});
129
- $('div.ws-menu-page-hr:first').css ({'margin-top': '10px', 'margin-bottom': '20px'});
130
- $('div.ws-menu-page-group > div.ws-menu-page-section:first-child > h3').css ({'margin-top': '0'});
131
- /**/
132
  if ($groups.length > 1) /* We only apply these special margins when there are multiple groups. */
133
  {
134
  $('div.ws-menu-page-group-header:first').css ({'margin-right': '140px'});
135
  $('div.ws-menu-page-group:first').css ({'margin-right': '145px'});
136
  }
137
  /**/
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
138
  $('div.ws-menu-page-readme > div.readme > div.section:last-child').css ({'border-bottom-width': '0'});
139
  /**/
140
  $('input.ws-menu-page-media-btn').filter (function() /* Only those that have a rel attribute. */
141
  {
142
- return($(this).attr ('rel')) ? true : false; /* Must have rel targeting an input id. */
143
  })/**/
144
  .click (function() /* Attach click events to media buttons with send_to_editor(). */
145
  {
@@ -183,4 +154,30 @@ jQuery(document).ready (function($)
183
  /**/
184
  return false;
185
  });
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
186
  });
23
  */
24
  jQuery(document).ready (function($)
25
  {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
26
  var $groups = $('div.ws-menu-page-group'); /* Query groups. */
27
  $groups.each (function(index) /* Go through each group, one at a time. */
28
  {
82
  return; /* Return for uniformity. */
83
  });
84
  /**/
 
 
 
 
 
85
  if ($groups.length > 1) /* We only apply these special margins when there are multiple groups. */
86
  {
87
  $('div.ws-menu-page-group-header:first').css ({'margin-right': '140px'});
88
  $('div.ws-menu-page-group:first').css ({'margin-right': '145px'});
89
  }
90
  /**/
91
+ $('div.ws-menu-page-r-group-header').click (function()
92
+ {
93
+ var $this = $(this), $group = $this.next ('div.ws-menu-page-r-group');
94
+ /**/
95
+ if ($group.css ('display') === 'none')
96
+ $('ins', $this).html ('-'), $this.addClass ('open'), $group.show ();
97
+ /**/
98
+ else /* Otherwise, we hide it. */
99
+ {
100
+ $('ins', $this).html ('+'), $this.removeClass ('open');
101
+ $group.hide ();
102
+ }
103
+ /**/
104
+ return false;
105
+ });
106
+ /**/
107
+ $('div.ws-menu-page-group-header:first, div.ws-menu-page-r-group-header:first').css ({'margin-top': '0'});
108
+ $('div.ws-menu-page-group > div.ws-menu-page-section:first-child > h3').css ({'margin-top': '0'});
109
  $('div.ws-menu-page-readme > div.readme > div.section:last-child').css ({'border-bottom-width': '0'});
110
  /**/
111
  $('input.ws-menu-page-media-btn').filter (function() /* Only those that have a rel attribute. */
112
  {
113
+ return ($(this).attr ('rel')) ? true : false; /* Must have rel targeting an input id. */
114
  })/**/
115
  .click (function() /* Attach click events to media buttons with send_to_editor(). */
116
  {
154
  /**/
155
  return false;
156
  });
157
+ /**/
158
+ $('form#ws-mlist-form').submit (function()
159
+ {
160
+ var errors = ''; /* Intialize string of errors. */
161
+ /**/
162
+ if (!$.trim ($('input#ws-mlist-fname').val ()))
163
+ errors += 'First Name missing, please try again.\n\n';
164
+ /**/
165
+ if (!$.trim ($('input#ws-mlist-lname').val ()))
166
+ errors += 'Last Name missing, please try again.\n\n';
167
+ /**/
168
+ if (!$.trim ($('input#ws-mlist-email').val ()))
169
+ errors += 'Email missing, please try again.\n\n';
170
+ /**/
171
+ else if (!$('input#ws-mlist-email').val ().match (/^([a-z_~0-9\+\-]+)(((\.?)([a-z_~0-9\+\-]+))*)(@)([a-z0-9]+)(((-*)([a-z0-9]+))*)(((\.)([a-z0-9]+)(((-*)([a-z0-9]+))*))*)(\.)([a-z]{2,6})$/i))
172
+ errors += 'Invalid email address, please try again.\n\n';
173
+ /**/
174
+ if (errors = $.trim (errors))
175
+ {
176
+ alert('— Oops, you missed something: —\n\n' + errors);
177
+ /**/
178
+ return false;
179
+ }
180
+ /**/
181
+ return true;
182
+ });
183
  });
includes/menu-pages/mms-ops.inc.php CHANGED
@@ -79,7 +79,7 @@ if (!class_exists ("c_ws_plugin__s2member_menu_page_mms_ops"))
79
  echo '<select name="ws_plugin__s2member_mms_auto_patch" id="ws-plugin--s2member-mms-auto-patch" disabled="disabled">' . "\n";
80
  echo '<option value="0" selected="selected">No ( I\'ll patch WordPress® myself )</option>' . "\n";
81
  echo '</select><br />' . "\n";
82
- echo '<em class="ws-menu-page-hilite">This is now locked. Your /wp-config.php file says: <code>DISALLOW_FILE_MODS = true</em></code>.' . "\n";
83
  }
84
  else /* Otherwise we can display these options. */
85
  {
79
  echo '<select name="ws_plugin__s2member_mms_auto_patch" id="ws-plugin--s2member-mms-auto-patch" disabled="disabled">' . "\n";
80
  echo '<option value="0" selected="selected">No ( I\'ll patch WordPress® myself )</option>' . "\n";
81
  echo '</select><br />' . "\n";
82
+ echo '<em class="ws-menu-page-hilite">This is now locked. Your /wp-config.php file says: <code>DISALLOW_FILE_MODS = true</code></em>.' . "\n";
83
  }
84
  else /* Otherwise we can display these options. */
85
  {
includes/menu-pages/paypal-buttons.inc.php CHANGED
@@ -75,7 +75,7 @@ if (!class_exists ("c_ws_plugin__s2member_menu_page_paypal_buttons"))
75
  echo '<p><span id="ws-plugin--s2member-level' . $n . '-trial-then">Then, </span>I want to charge: $<input type="text" id="ws-plugin--s2member-level' . $n . '-amount" value="0.01" size="4" /> / <select id="ws-plugin--s2member-level' . $n . '-term">' . file_get_contents (dirname (dirname (__FILE__)) . "/templates/options/paypal-membership-regular-terms.html") . '</select></p>' . "\n";
76
  echo '<p>Checkout Page Style <a href="#" onclick="alert(\'Optional. This can be configured inside your PayPal® account. PayPal® allows you to create Custom Page Styles, and assign a unique name to them. You can add your own header image and color selection to the checkout form. Once you\\\'ve created a Custom Page Style at PayPal®, you can enter that Page Style here.\\n\\nIn addition. The Shortcode below, provided by s2Member; supports an image attribute: image=\\\'\\\'default\\\'\\\'. This can be changed to a full URL, pointing to a custom image of your own; instead of the default PayPal® Button image.\'); return false;" tabindex="-1">[?]</a>: <input type="text" id="ws-plugin--s2member-level' . $n . '-page-style" value="paypal" size="18" /> <select id="ws-plugin--s2member-level' . $n . '-currency">' . file_get_contents (dirname (dirname (__FILE__)) . "/templates/options/paypal-currencies.html") . '</select> <input type="button" value="Generate Button Code" onclick="ws_plugin__s2member_paypalButtonGenerate(\'level' . $n . '\');" class="button-primary" /></p>' . "\n";
77
  echo '<p>Description: <input type="text" id="ws-plugin--s2member-level' . $n . '-desc" value="' . format_to_edit ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["level" . $n . "_label"]) . ' / description and pricing details here." size="73" /></p>' . "\n";
78
- 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.\\n\\n*ADVANCED TIP: You can specifiy a list of Custom Capabilities that come with this purchase. Or, you could tell s2Member to (ADD) Custom Capabilities to any that already exist for a particular Member. Just start your list of Custom Capabilities with a (+) sign.\\n\\nSo instead of setting a Member\\\'s full set of Custom Capabilities to:\\nmusic,videos,archives,gifts\\n\\nYou could (ADD) new ones to any that already exist:\\n+calendar,forums,tools\\n\\nOr to prevent any changes, (ADD) nothing:\\n+\'); return false;" tabindex="-1">[?]</a> <input type="text" id="ws-plugin--s2member-level' . $n . '-ccaps" size="40" maxlength="125" /></p>' . "\n";
79
  echo '</form>' . "\n";
80
  echo '</td>' . "\n";
81
  /**/
@@ -139,10 +139,12 @@ if (!class_exists ("c_ws_plugin__s2member_menu_page_paypal_buttons"))
139
  echo '<div class="ws-menu-page-section ws-plugin--s2member-modification-buttons-section">' . "\n";
140
  echo '<h3>Button Code Generator For Subscription Modifications</h3>' . "\n";
141
  echo '<p>If you\'d like to give your Members <em>( and/or your Free Subscribers )</em> the ability to modify their billing plan, by switching to a more expensive option, or a less expensive option; generate a new PayPal® Modification Button here. Configure the updated Level, pricing, terms, etc. Then, make that new Modification Button available to Members who are logged into their existing account with you. For example, you might want to insert a "Level #2" Upgrade Button into your Login Welcome Page, which would up-sell existing Level #1 Members to a more expensive plan that you offer.</p>' . "\n";
142
- echo '<p><em><strong>*Modification Process*</strong> When you send a Member to PayPal® using a Subscription Modification Button, PayPal® will ask them to login. Once they\'re logged in, instead of being able to signup for a new Membership, PayPal® will provide them with the ability to upgrade and/or downgrade their existing Membership with you, by allowing them to switch to the Membership Plan that was specified in the Subscription Modification Button. PayPal® handles this nicely, and you\'ll be happy to know that s2Member has been pre-configured to deal with this scenario as well, so that everything remains automated. Their Membership Access Level will either be promoted, or demoted, based on the actions they took at PayPal® during the modification process. Once an existing Member completes their Subscription Modification at PayPal®, they\'ll be brought back to their Login Welcome Page, instead of the registration screen.</em></p>' . "\n";
 
143
  echo '<p><em><strong>*Also Works For Free Subscribers*</strong> Although a Free Subscriber does not have an existing PayPal® Subscription, s2Member is capable of adapting to this scenario gracefully. Just make sure that your existing Free Subscribers <em>( the ones who wish to upgrade )</em> pay for their Membership through a Modification Button generated by s2Member. That will allow them to continue using their existing account with you. In other words, they can keep their existing Username <em>( and anything already associated with that Username )</em>, rather than being forced to re-register after checkout.</em></p>' . "\n";
144
  echo '<p><em><strong>*Make It More User-Friendly*</strong> You can make the Subscription Modification Process, more user-friendly, by setting up a <a href="#" onclick="alert(\'Optional. This can be configured inside your PayPal® account. PayPal® allows you to create Custom Page Styles, and assign a unique name to them. You can add your own header image and color selection to the checkout form. Once you\\\'ve created a Custom Page Style at PayPal®, you can tell s2Member to use that Page Style whenever you generate your Button Code.\'); return false;">Custom Page Style at PayPal®</a>, specifically for Subscription Modification Buttons. Use a custom header image, with a brief explanation to the Customer. Something like, "Log into PayPal®", "You can Modify your Subscription!".</em></p>' . "\n";
145
  echo '<p><em><strong>*Integrating Conditionals*</strong> Since each Modification Button is configured for a specific Level, you may want to create multiple Modification Buttons, one for each combination you intend to make available. s2Member\'s API Conditionals can help you display the proper Button to each Customer, based on the status of their existing account. For further details, see: <code>s2Member -> API Scripting</code>.</em></p>' . "\n";
 
146
  do_action ("ws_plugin__s2member_during_paypal_buttons_page_during_left_sections_during_modification_buttons", get_defined_vars ());
147
  /**/
148
  echo '<table class="form-table">' . "\n";
@@ -177,7 +179,7 @@ if (!class_exists ("c_ws_plugin__s2member_menu_page_paypal_buttons"))
177
  echo '<p><span id="ws-plugin--s2member-modification-trial-then">Then, </span>I want to charge: $<input type="text" id="ws-plugin--s2member-modification-amount" value="0.01" size="4" /> / <select id="ws-plugin--s2member-modification-term">' . file_get_contents (dirname (dirname (__FILE__)) . "/templates/options/paypal-membership-regular-terms.html") . '</select><span id="ws-plugin--s2member-modification-20p-rule"><br /><small>* Watch out for <a href="https://www.x.com/thread/41748" target="_blank" rel="external">the 20% rule</a>. Additional details are <a href="https://cms.paypal.com/us/cgi-bin/?cmd=_render-content&content_ID=developer/e_howto_api_WPRecurringPayments#id086530108PM__id08653060UE6" target="_blank" rel="external">documented here</a>.<br />* <strong>Tip</strong> <a href="' . esc_attr (c_ws_plugin__s2member_readmes::parse_readme_value ("Pro Module / Prices")) . '" target="_blank" rel="external">s2Member Pro Forms</a> are NOT subjected to this ridiculous 20% rule.</small></span></p>' . "\n";
178
  echo '<p>Checkout Page Style <a href="#" onclick="alert(\'Optional. This can be configured inside your PayPal® account. PayPal® allows you to create Custom Page Styles, and assign a unique name to them. You can add your own header image and color selection to the checkout form. Once you\\\'ve created a Custom Page Style at PayPal®, you can enter that Page Style here.\\n\\nIn addition. The Shortcode below, provided by s2Member; supports an image attribute: image=\\\'\\\'default\\\'\\\'. This can be changed to a full URL, pointing to a custom image of your own; instead of the default PayPal® Button image.\'); return false;" tabindex="-1">[?]</a>: <input type="text" id="ws-plugin--s2member-modification-page-style" value="paypal" size="18" /> <select id="ws-plugin--s2member-modification-currency">' . file_get_contents (dirname (dirname (__FILE__)) . "/templates/options/paypal-currencies.html") . '</select> <input type="button" value="Generate Button Code" onclick="ws_plugin__s2member_paypalButtonGenerate(\'modification\');" class="button-primary" /></p>' . "\n";
179
  echo '<p>Description: <input type="text" id="ws-plugin--s2member-modification-desc" value="Description and pricing details here." size="73" /></p>' . "\n";
180
- 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.\\n\\n*ADVANCED TIP: You can specifiy a list of Custom Capabilities that come with this purchase. Or, you could tell s2Member to (ADD) Custom Capabilities to any that already exist for a particular Member. Just start your list of Custom Capabilities with a (+) sign.\\n\\nSo instead of setting a Member\\\'s full set of Custom Capabilities to:\\nmusic,videos,archives,gifts\\n\\nYou could (ADD) new ones to any that already exist:\\n+calendar,forums,tools\\n\\nOr to prevent any changes, (ADD) nothing:\\n+\'); return false;" tabindex="-1">[?]</a> <input type="text" id="ws-plugin--s2member-modification-ccaps" size="40" maxlength="125" /></p>' . "\n";
181
  echo '</form>' . "\n";
182
  echo '</td>' . "\n";
183
  /**/
@@ -229,6 +231,84 @@ if (!class_exists ("c_ws_plugin__s2member_menu_page_paypal_buttons"))
229
  do_action ("ws_plugin__s2member_during_paypal_buttons_page_during_left_sections_after_modification_buttons", get_defined_vars ());
230
  }
231
  /**/
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
232
  if (apply_filters ("ws_plugin__s2member_during_paypal_buttons_page_during_left_sections_display_cancellation_buttons", true, get_defined_vars ()))
233
  {
234
  do_action ("ws_plugin__s2member_during_paypal_buttons_page_during_left_sections_before_cancellation_buttons", get_defined_vars ());
@@ -240,7 +320,8 @@ if (!class_exists ("c_ws_plugin__s2member_menu_page_paypal_buttons"))
240
  echo '<p>Since all recurring charges are associated with a PayPal® Subscription; and every PayPal® Subscription is associated with a PayPal® Account; your Members will always have a PayPal® Account of their own, which is tied to their Membership with you. So... a Member can simply log into their own PayPal® account and cancel their Subscription(s) with you at anytime, all on their own. However, some Customers do not realize this. So, if you would like to make it clearer ( easier ) for Members to cancel their own Subscription(s), you can provide this Cancellation Button for them on your Login Welcome Page, or somewhere in the support section of your website. Note... you don\'t have to use this Cancellation Button at all, if you don\'t want to. It\'s completely optional.</p>' . "\n";
241
  echo '<p><em><strong>*Cancellation Process*</strong> Very simple. A Member clicks the Cancellation Button. PayPal® asks them to log into their PayPal® account. Once they\'re logged in, PayPal® will display a list of all active Subscriptions they have with you. They choose which ones they want to cancel, and s2Member is notified silently behind-the-scene, through the PayPal® IPN service.</em></p>' . "\n";
242
  echo '<p><em><strong>*Understanding Cancellations*</strong> It\'s important to realize that a Cancellation is not an EOT ( End Of Term ). All that happens during a Cancellation event, is that billing is stopped, and it\'s understood that the Customer is going to lose access, at some point in the future. This does NOT mean, that access will be revoked immediately. A separate EOT event will automatically handle a (demotion or deletion) later, at the appropriate time; which could be several days, or even a year after the Cancellation took place.</em></p>' . "\n";
243
- echo '<p><em><strong>*Some Hairy Details*</strong> There might be times whenever you notice that a Member\'s Subscription has been cancelled through PayPal®... but, s2Member continues allowing the User access to your site as a paid Member. Please don\'t be confused by this... in 99.9% of these cases, the reason for this is legitimate. s2Member will only remove the User\'s Membership privileges when an EOT ( End Of Term ) is processed, a refund occurs, a chargeback occurs, or when a cancellation occurs - which would later result in a delayed Auto-EOT by s2Member. s2Member will not process an EOT ( End Of Term ) 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";
 
244
  do_action ("ws_plugin__s2member_during_paypal_buttons_page_during_left_sections_during_cancellation_buttons", get_defined_vars ());
245
  /**/
246
  echo '<table class="form-table">' . "\n";
@@ -327,7 +408,7 @@ if (!class_exists ("c_ws_plugin__s2member_menu_page_paypal_buttons"))
327
  echo '</select></p>' . "\n";
328
  echo '<p>Paid Subscr. ID: <input id="ws-plugin--s2member-reg-link-subscr-id" type="text" value="" size="50" /> <a href="#" onclick="alert(\'The Customer\\\'s Paid Subscr. ID ( aka: Recurring Profile ID, Transaction ID ) must be unique. This value can be obtained from inside your PayPal® account under the History tab. Each paying Customer MUST be associated with a unique Paid Subscr. ID. If the Customer is NOT associated with a Paid Subscr. ID, you will need to generate a unique value for this field on your own. But keep in mind, s2Member will be unable to maintain future communication with the PayPal® IPN ( i.e. Notification ) service if this value does not reflect a real Paid Subscr. ID that exists in your PayPal® History log.\'); return false;" tabindex="-1">[?]</a></p>' . "\n";
329
  echo '<p>Custom String Value: <input id="ws-plugin--s2member-reg-link-custom" type="text" 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_sq (esc_attr ($_SERVER["HTTP_HOST"])) . '\\\'\\\' 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_sq (esc_attr ($_SERVER["HTTP_HOST"])) . '|cv1|cv2|cv3\'); return false;" tabindex="-1">[?]</a> <input type="button" value="Generate Access Link" onclick="ws_plugin__s2member_paypalRegLinkGenerate();" class="button-primary" /> <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";
330
- 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" id="ws-plugin--s2member-reg-link-ccaps" size="40" maxlength="125" 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";
331
  echo '<p>Fixed Term Length ( for Buy Now transactions ): <input id="ws-plugin--s2member-reg-link-fixed-term" type="text" 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";
332
  echo '<p id="ws-plugin--s2member-reg-link" style="font-family:Consolas, monospace; display:none;"></p>' . "\n";
333
  echo '</form>' . "\n";
@@ -355,7 +436,7 @@ if (!class_exists ("c_ws_plugin__s2member_menu_page_paypal_buttons"))
355
  echo '<p>In other words, Customers will NOT need to login, just to receive access to the Specific Post/Page they purchased access to. s2Member will immediately redirect the Customer to the Specific Post/Page after checkout is completed successfully. An email is also sent to the Customer with a link ( see: <code>s2Member -> PayPal® Options -> Specific Post/Page Email</code> ). Authentication is handled automatically through self-expiring links, good for 72 hours by default.</p>' . "\n";
356
  echo '<p>Specific Post/Page Access, is sort of like selling a product. Only, instead of shipping anything to the Customer, you just give them access to a specific Post/Page on your site; one that you created in WordPress®. A Specific Post/Page that is protected by s2Member, might contain a download link for your eBook, access to file &amp; music downloads, access to additional support services, and the list goes on and on. The possibilities with this are endless; as long as your digital product can be delivered through access to a WordPress® Post/Page that you\'ve created. To protect Specific Posts/Pages, please see: <code>s2Member -> Restriction Options -> Specific Post/Page Access</code>. Once you\'ve configured your Specific Post/Page Restrictions, those Posts/Pages will be available in the menus below.</p>' . "\n";
357
  echo '<p>Very simple. All you do is customize the form fields provided, for each Post/Page that you plan to sell. Then press (Generate Button Code). These special PayPal® Buttons are customized to work with s2Member seamlessly. You can even Package Additional Posts/Pages together into one transaction.</p>' . "\n";
358
- echo '<p><em>* Buttons are NOT saved here. This is only a Button Generator. Once you\'ve generated your Button, copy/paste it into your WordPress® Editor, wherever you feel it would be most appropriate. If you lose your Button Code, you\'ll need to come back &amp; re-generate a new one. If you\'re in Sandbox Test-Mode, and you\'re NOT using the Shortcode Format, please remember to come back and re-generate your Buttons before you go live.</em></p>' . "\n";
359
  do_action ("ws_plugin__s2member_during_paypal_buttons_page_during_left_sections_during_sp_buttons", get_defined_vars ());
360
  /**/
361
  echo '<table class="form-table">' . "\n";
@@ -528,7 +609,7 @@ if (!class_exists ("c_ws_plugin__s2member_menu_page_paypal_buttons"))
528
  echo '<ul>' . "\n";
529
  echo '<li><code>cancel="0"</code> Cancellation Button. Only valid w/ Membership Level Access. Possible values: <code>0</code> = this is NOT a Cancellation Button, <code>1</code> = this IS a Cancellation Button.</li>' . "\n";
530
  echo '<li><code>cc="USD"</code> 3 character Currency Code. Not valid when <code>cancel="1"</code>.</li>' . "\n";
531
- echo (!is_multisite () || !c_ws_plugin__s2member_utils_conds::is_multisite_farm () || is_main_site ()) ? '<li><code>ccaps="music,videos"</code> A comma-delimited list of Custom Capabilities. Only valid w/ Membership Level Access.</li>' . "\n" : '';
532
  echo '<li><code>custom="' . esc_html ($_SERVER["HTTP_HOST"]) . '"</code> must start with your domain. Additional values can be piped in ( ex: <code>custom="' . esc_html ($_SERVER["HTTP_HOST"]) . '|cv1|cv2|cv3|etc"</code> ). Not valid when <code>cancel="1"</code>.</li>' . "\n";
533
  echo '<li><code>desc="Gold Membership"</code> A brief purchase Description. Not valid when <code>cancel="1"</code>.</li>' . "\n";
534
  echo '<li><code>dg="0"</code> The Digital Goods directive. s2Member will eventually be integrated with <a href="https://cms.paypal.com/us/cgi-bin/?cmd=_render-content&content_ID=developer/e_howto_api_IntroducingExpressCheckoutDG" target="_blank" rel="external">Digital Goods</a> for inline Express Checkout. But for now, this should always be <code>0</code>.</li>' . "\n";
@@ -536,15 +617,15 @@ if (!class_exists ("c_ws_plugin__s2member_menu_page_paypal_buttons"))
536
  echo '<li><code>ids="14"</code> A Post/Page ID#, or a comma-delimited list of IDs. Only valid when <code>sp="1"</code> for Specific Post/Page Access.</li>' . "\n";
537
  echo '<li><code>image="default"</code> Button Image Location. Possible values: <code>default</code> = use the default PayPal® Button, <code>http://...</code> = location of your custom Image.</li>' . "\n";
538
  echo '<li><code>lc=""</code> Optional 2 character Locale Code <em>( i.e. Country Code )</em>. This controls the interface language used at PayPal® during checkout. If unspecified, the language is determined by PayPal® when possible, defaulting to <code>US</code> <em>english</em> when not possible. Not valid when <code>cancel="1"</code>.</li>' . "\n";
539
- echo '<li><code>level="1"</code> Membership Level [1-4] <em>( or, up to the number of configured Levels )</em>. Only valid for Buttons providing paid Membership Level Access.</li>' . "\n";
540
  echo '<li><code>modify="0"</code> Modification directive. Only valid w/ Membership Level Access. Possible values: <code>0</code> = allows Customers to only create a new Subscription, <code>1</code> = allows Customers to modify their current Subscription or sign up for a new one, <code>2</code> = allows Customers to only modify their current Subscription.</li>' . "\n";
541
  echo '<li><code>ns="1"</code> The <em>no_shipping</em> directive. Possible values: <code>0</code> = prompt for an address, but do not require one, <code>1</code> = do not prompt for a shipping address, <code>2</code> = prompt for an address, and require one. Not valid when <code>cancel="1"</code>.</li>' . "\n";
542
  echo '<li><code>output="button"</code> Output Type. Possible values: <code>button</code> = PayPal® Button w/hidden inputs, <code>anchor</code> = PayPal® Button ( &lt;a&gt; anchor tag ) URL w/ ?query string, <code>url</code> = raw URL w/ ?query string.</li>' . "\n";
543
  echo '<li><code>ps="paypal"</code> PayPal® checkout Page Style. Not valid when <code>cancel="1"</code>.</li>' . "\n";
544
  echo '<li><code>ra="0.01"</code> Regular, Buy Now, and/or Recurring Amount. Must be &gt;= <code>0.01</code>. Not valid when <code>cancel="1"</code>.</li>' . "\n";
545
- echo '<li><code>rp="1"</code> Regular Period. Only valid w/ Membership Level Access. Must be &gt;= <code>1</code> ( ex: <code>1</code> Week, <code>2</code> Months, <code>1</code> Month, <code>3</code> Days ).</li>' . "\n";
546
- echo '<li><code>rt="M"</code> Regular Term. Only valid w/ Membership Level Access. Possible values: <code>D</code> = Days, <code>W</code> = Weeks, <code>M</code> = Months, <code>Y</code> = Years, <code>L</code> = Lifetime.</li>' . "\n";
547
- echo '<li><code>rr="1"</code> Recurring directive. Only valid w/ Membership Level Access. Possible values: <code>0</code> = non-recurring "Subscription" with possible Trial Period for free, or at a different Trial Amount; <code>1</code> = recurring "Subscription" with possible Trial Period for free, or at a different Trial Amount; <code>BN</code> = non-recurring "Buy Now" functionality, no Trial Period possible.</li>' . "\n";
548
  echo '<li><code>rrt=""</code> Recurring Times <em>( i.e. a fixed number of installments )</em>. Only valid w/ Membership Level Access. When unspecified, any recurring charges will remain ongoing until cancelled, or until payments start failing. If this is set to <code>1 or higher</code> the regular recurring charges will only continue for X billing cycles, depending on what you specify. This is only valid when <code>rr="1"</code> for recurring "Subscriptions". Please note that a fixed number of installments, also means a fixed period of access. If a Customer\'s billing is monthly, and you set <code>rrt="3"</code>, billing will continue for only 3 monthly installments. After that, billing would stop, and their access to the site would be revoked as well <em>( based on your EOT Behavior setting under: s2Member -> PayPal® Options )</em>.</li>' . "\n";
549
  echo '<li><code>rra="1"</code> Reattempt failed payments? Possible values: <code>0</code> = do NOT reattempt billing when/if a recurring payment fails; <code>1</code> = yes, DO reattempt billing when/if a recurring payment fails. With PayPal® Standard integration, PayPal® will retry a maximum of 2 times when you set <code>rra="1"</code>; after that, a Subscription would be terminated due to Max Failed Payments having been reached. PayPal® Standard integration does NOT make it possible to configure Max Failed Payments, it simply defaults to a value of <code>2</code> whenever <code>rra="1"</code>, indicating that you DO want to retry failed payments.</li>' . "\n";
550
  echo '<li><code>sp="0"</code> Specific Post/Page Button. Possible values: <code>0</code> = this is NOT a Specific Post/Page Access Button, <code>1</code> = this IS a Specific Post/Page Access Button.</li>' . "\n";
75
  echo '<p><span id="ws-plugin--s2member-level' . $n . '-trial-then">Then, </span>I want to charge: $<input type="text" id="ws-plugin--s2member-level' . $n . '-amount" value="0.01" size="4" /> / <select id="ws-plugin--s2member-level' . $n . '-term">' . file_get_contents (dirname (dirname (__FILE__)) . "/templates/options/paypal-membership-regular-terms.html") . '</select></p>' . "\n";
76
  echo '<p>Checkout Page Style <a href="#" onclick="alert(\'Optional. This can be configured inside your PayPal® account. PayPal® allows you to create Custom Page Styles, and assign a unique name to them. You can add your own header image and color selection to the checkout form. Once you\\\'ve created a Custom Page Style at PayPal®, you can enter that Page Style here.\\n\\nIn addition. The Shortcode below, provided by s2Member; supports an image attribute: image=\\\'\\\'default\\\'\\\'. This can be changed to a full URL, pointing to a custom image of your own; instead of the default PayPal® Button image.\'); return false;" tabindex="-1">[?]</a>: <input type="text" id="ws-plugin--s2member-level' . $n . '-page-style" value="paypal" size="18" /> <select id="ws-plugin--s2member-level' . $n . '-currency">' . file_get_contents (dirname (dirname (__FILE__)) . "/templates/options/paypal-currencies.html") . '</select> <input type="button" value="Generate Button Code" onclick="ws_plugin__s2member_paypalButtonGenerate(\'level' . $n . '\');" class="button-primary" /></p>' . "\n";
77
  echo '<p>Description: <input type="text" id="ws-plugin--s2member-level' . $n . '-desc" value="' . format_to_edit ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["level" . $n . "_label"]) . ' / description and pricing details here." size="73" /></p>' . "\n";
78
+ 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.\\n\\n*ADVANCED TIP: You can specifiy a list of Custom Capabilities that will be (Added) with this purchase. Or, you could tell s2Member to (Remove All) Custom Capabilities that may or may not already exist for a particular Member, and (Add) only the new ones that you specify. To do this, just start your list of Custom Capabilities with `-all`.\\n\\nSo instead of just (Adding) Custom Capabilities:\\nmusic,videos,archives,gifts\\n\\nYou could (Remove All) that may already exist, and then (Add) new ones:\\n-all,calendar,forums,tools\\n\\nOr to just (Remove All) and (Add) nothing:\\n-all\'); return false;" tabindex="-1">[?]</a> <input type="text" id="ws-plugin--s2member-level' . $n . '-ccaps" size="40" maxlength="125" /></p>' . "\n";
79
  echo '</form>' . "\n";
80
  echo '</td>' . "\n";
81
  /**/
139
  echo '<div class="ws-menu-page-section ws-plugin--s2member-modification-buttons-section">' . "\n";
140
  echo '<h3>Button Code Generator For Subscription Modifications</h3>' . "\n";
141
  echo '<p>If you\'d like to give your Members <em>( and/or your Free Subscribers )</em> the ability to modify their billing plan, by switching to a more expensive option, or a less expensive option; generate a new PayPal® Modification Button here. Configure the updated Level, pricing, terms, etc. Then, make that new Modification Button available to Members who are logged into their existing account with you. For example, you might want to insert a "Level #2" Upgrade Button into your Login Welcome Page, which would up-sell existing Level #1 Members to a more expensive plan that you offer.</p>' . "\n";
142
+ echo '<p><em><strong>*Important Note*</strong> Modification Buttons should be displayed to existing Users/Members, and they should be logged-in, BEFORE clicking this Button. Otherwise, post-processing of their transaction will fail to recognize the Customer\'s existing account within WordPress®. Please display this Button only to Users/Members that are already logged into their account ( perhaps in your Login Welcome Page for s2Member ), or in another location where you can be absolutely sure that a User/Member is logged in. s2Member\'s Simple Conditionals could also be used to ensure a User/Member is logged in, by wrapping your Shortcode within a Conditional test. For further details, please see: <code>s2Member -> API Scripting -> Simple Conditionals</code>.</em></p>' . "\n";
143
+ echo '<p><em><strong>*Modification Process*</strong> When you send a Member to PayPal® using a Subscription Modification Button, PayPal® will ask them to login. Once they\'re logged in, instead of being able to signup for a new Membership, PayPal® will provide them with the ability to upgrade and/or downgrade their existing Membership with you, by allowing them to switch to the Membership Plan that was specified in the Subscription Modification Button. PayPal® handles this nicely, and you\'ll be happy to know that s2Member has been pre-configured to deal with this scenario as well, so that everything remains automated. Their Membership Access Level will either be promoted, or demoted, based on the actions they took at PayPal® during the modification process. Once an existing Member completes their Subscription Modification at PayPal®, they\'ll be brought back to their Login Welcome Page, instead of to the registration screen.</em></p>' . "\n";
144
  echo '<p><em><strong>*Also Works For Free Subscribers*</strong> Although a Free Subscriber does not have an existing PayPal® Subscription, s2Member is capable of adapting to this scenario gracefully. Just make sure that your existing Free Subscribers <em>( the ones who wish to upgrade )</em> pay for their Membership through a Modification Button generated by s2Member. That will allow them to continue using their existing account with you. In other words, they can keep their existing Username <em>( and anything already associated with that Username )</em>, rather than being forced to re-register after checkout.</em></p>' . "\n";
145
  echo '<p><em><strong>*Make It More User-Friendly*</strong> You can make the Subscription Modification Process, more user-friendly, by setting up a <a href="#" onclick="alert(\'Optional. This can be configured inside your PayPal® account. PayPal® allows you to create Custom Page Styles, and assign a unique name to them. You can add your own header image and color selection to the checkout form. Once you\\\'ve created a Custom Page Style at PayPal®, you can tell s2Member to use that Page Style whenever you generate your Button Code.\'); return false;">Custom Page Style at PayPal®</a>, specifically for Subscription Modification Buttons. Use a custom header image, with a brief explanation to the Customer. Something like, "Log into PayPal®", "You can Modify your Subscription!".</em></p>' . "\n";
146
  echo '<p><em><strong>*Integrating Conditionals*</strong> Since each Modification Button is configured for a specific Level, you may want to create multiple Modification Buttons, one for each combination you intend to make available. s2Member\'s API Conditionals can help you display the proper Button to each Customer, based on the status of their existing account. For further details, see: <code>s2Member -> API Scripting</code>.</em></p>' . "\n";
147
+ echo (!is_multisite () || !c_ws_plugin__s2member_utils_conds::is_multisite_farm () || is_main_site ()) ? '<p><em><strong>*Independent Custom Capabilities*</strong> If you just want to sell an existing Member new Custom Capabilities, without affecting their paid Subscription in any way, please see the next Button Generator: <code>Capability (Buy Now) Buttons</code>. Independent Capability Buttons facilitate Buy Now functionality, specifically for Custom Capabilities, without affecting the Customer\'s primary Subscription and Membership Level Access.</em></p>' . "\n" : '';
148
  do_action ("ws_plugin__s2member_during_paypal_buttons_page_during_left_sections_during_modification_buttons", get_defined_vars ());
149
  /**/
150
  echo '<table class="form-table">' . "\n";
179
  echo '<p><span id="ws-plugin--s2member-modification-trial-then">Then, </span>I want to charge: $<input type="text" id="ws-plugin--s2member-modification-amount" value="0.01" size="4" /> / <select id="ws-plugin--s2member-modification-term">' . file_get_contents (dirname (dirname (__FILE__)) . "/templates/options/paypal-membership-regular-terms.html") . '</select><span id="ws-plugin--s2member-modification-20p-rule"><br /><small>* Watch out for <a href="https://www.x.com/thread/41748" target="_blank" rel="external">the 20% rule</a>. Additional details are <a href="https://cms.paypal.com/us/cgi-bin/?cmd=_render-content&content_ID=developer/e_howto_api_WPRecurringPayments#id086530108PM__id08653060UE6" target="_blank" rel="external">documented here</a>.<br />* <strong>Tip</strong> <a href="' . esc_attr (c_ws_plugin__s2member_readmes::parse_readme_value ("Pro Module / Prices")) . '" target="_blank" rel="external">s2Member Pro Forms</a> are NOT subjected to this ridiculous 20% rule.</small></span></p>' . "\n";
180
  echo '<p>Checkout Page Style <a href="#" onclick="alert(\'Optional. This can be configured inside your PayPal® account. PayPal® allows you to create Custom Page Styles, and assign a unique name to them. You can add your own header image and color selection to the checkout form. Once you\\\'ve created a Custom Page Style at PayPal®, you can enter that Page Style here.\\n\\nIn addition. The Shortcode below, provided by s2Member; supports an image attribute: image=\\\'\\\'default\\\'\\\'. This can be changed to a full URL, pointing to a custom image of your own; instead of the default PayPal® Button image.\'); return false;" tabindex="-1">[?]</a>: <input type="text" id="ws-plugin--s2member-modification-page-style" value="paypal" size="18" /> <select id="ws-plugin--s2member-modification-currency">' . file_get_contents (dirname (dirname (__FILE__)) . "/templates/options/paypal-currencies.html") . '</select> <input type="button" value="Generate Button Code" onclick="ws_plugin__s2member_paypalButtonGenerate(\'modification\');" class="button-primary" /></p>' . "\n";
181
  echo '<p>Description: <input type="text" id="ws-plugin--s2member-modification-desc" value="Description and pricing details here." size="73" /></p>' . "\n";
182
+ 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.\\n\\n*ADVANCED TIP: You can specifiy a list of Custom Capabilities that will be (Added) with this purchase. Or, you could tell s2Member to (Remove All) Custom Capabilities that may or may not already exist for a particular Member, and (Add) only the new ones that you specify. To do this, just start your list of Custom Capabilities with `-all`.\\n\\nSo instead of just (Adding) Custom Capabilities:\\nmusic,videos,archives,gifts\\n\\nYou could (Remove All) that may already exist, and then (Add) new ones:\\n-all,calendar,forums,tools\\n\\nOr to just (Remove All) and (Add) nothing:\\n-all\'); return false;" tabindex="-1">[?]</a> <input type="text" id="ws-plugin--s2member-modification-ccaps" size="40" maxlength="125" /></p>' . "\n";
183
  echo '</form>' . "\n";
184
  echo '</td>' . "\n";
185
  /**/
231
  do_action ("ws_plugin__s2member_during_paypal_buttons_page_during_left_sections_after_modification_buttons", get_defined_vars ());
232
  }
233
  /**/
234
+ if (apply_filters ("ws_plugin__s2member_during_paypal_buttons_page_during_left_sections_display_ccap_buttons", (!is_multisite () || !c_ws_plugin__s2member_utils_conds::is_multisite_farm () || is_main_site ()), get_defined_vars ()))
235
+ {
236
+ do_action ("ws_plugin__s2member_during_paypal_buttons_page_during_left_sections_before_ccap_buttons", get_defined_vars ());
237
+ /**/
238
+ echo '<div class="ws-menu-page-group" title="PayPal® Capability (Buy Now) Buttons">' . "\n";
239
+ /**/
240
+ echo '<div class="ws-menu-page-section ws-plugin--s2member-ccap-buttons-section">' . "\n";
241
+ echo '<h3>Button Code Generator For Independent Custom Capabilities</h3>' . "\n";
242
+ echo '<p>This is VERY advanced. For further details, please check your Dashboard: <code>s2Member -> API Scripting -> Custom Capabiities</code>.</p>' . "\n";
243
+ echo '<p>With s2Member, you can sell one or more Custom Capabilities using Buy Now functionality, to "existing" Users/Members, regardless of which Membership Level they have on your site <em>( i.e. you could even sell Independent Custom Capabilities to Users at Membership Level #0, normally referred to as Free Subscribers, if you like )</em>. So this is quite flexible. Independent Custom Capabilities do NOT rely on any specific Membership Level. That\'s why s2Member refers to these as `Independent` Custom Capabilities, because you can sell Capabilities this way, through Buy Now functionality, and the Customer\'s Membership Level Access, along with any existing paid Subscription they may already have with you, will remain completely unaffected. That being said, if you intend to charge a recurring fee for Custom Capabilities, please use a <code>Subscr. Modification Button</code> instead; because Independent Custom Capabilities can only be sold through Buy Now functionality.</p>' . "\n";
244
+ echo '<p>Independent Custom Capabilities are added to a Customer\'s account immediately after checkout, and the Customer will have the Custom Capabilities for as long as their Membership lasts, based on their primary Subscription with your site, and/or forever, if they have a Lifetime account with you. In other words, Independent Custom Capabilities will exist on the Customer\'s account forever, or until an EOT <em>( End Of Term )</em> occurs on their primary Subscription with you; in which case s2Member would demote or delete the Customer\'s account <em>( based on your EOT configuration )</em>, and all Custom Capabilities are removed as well.</p>' . "\n";
245
+ echo '<p>Very simple. All you do is customize the form fields provided, for each set of Custom Capabilities that you plan to sell. Then press (Generate Button Code). These special PayPal® Buttons are customized to work with s2Member seamlessly. The Customer will be granted additional access to one or more Custom Capabilities that you specify; while the Customer\'s Membership Level Access and any existing paid Subscription they may already have with you, will remain completely unaffected.</p>' . "\n";
246
+ echo '<p><em><strong>*Important Note*</strong> Independent Custom Capability Buttons should ONLY be displayed to existing Users/Members, and they MUST be logged-in, BEFORE clicking this Button. Otherwise, post-processing of their transaction will fail to recognize the Customer\'s existing account within WordPress®. Please display this Button only to Users/Members that are already logged into their account ( perhaps in your Login Welcome Page for s2Member ), or in another location where you can be absolutely sure that a User/Member is logged in. s2Member\'s Simple Conditionals could also be used to ensure a User/Member is logged in, by wrapping your Shortcode within a Conditional test. For further details, please see: <code>s2Member -> API Scripting -> Simple Conditionals</code>.</em></p>' . "\n";
247
+ echo '<p><em>* Buttons are NOT saved here. This is only a Button Generator. Once you\'ve generated your Button, copy/paste it into your WordPress® Editor. If you lose your Button Code, you\'ll need to come back &amp; re-generate a new one. If you\'re in Sandbox Test-Mode, and you\'re NOT using the Shortcode Format, please remember to come back and re-generate your Buttons before you go live.</em></p>' . "\n";
248
+ do_action ("ws_plugin__s2member_during_paypal_buttons_page_during_left_sections_during_ccap_buttons", get_defined_vars ());
249
+ /**/
250
+ echo '<table class="form-table">' . "\n";
251
+ echo '<tbody>' . "\n";
252
+ echo '<tr>' . "\n";
253
+ /**/
254
+ echo '<th class="ws-menu-page-th-side">' . "\n";
255
+ echo '<label for="ws-plugin--s2member-ccap-shortcode">' . "\n";
256
+ echo 'Button Code<br />For Capabilities:<br /><br />' . "\n";
257
+ echo '<div id="ws-plugin--s2member-ccap-button-prev"></div>' . "\n";
258
+ echo '</label>' . "\n";
259
+ echo '</th>' . "\n";
260
+ /**/
261
+ echo '<td>' . "\n";
262
+ echo '<form onsubmit="return false;">' . "\n";
263
+ echo '<p>I want to charge: $<input type="text" id="ws-plugin--s2member-ccap-amount" value="0.01" size="4" /> / <select id="ws-plugin--s2member-ccap-term">' . file_get_contents (dirname (dirname (__FILE__)) . "/templates/options/paypal-membership-ccap-terms.html") . '</select></p>' . "\n";
264
+ echo '<p>Checkout Page Style <a href="#" onclick="alert(\'Optional. This can be configured inside your PayPal® account. PayPal® allows you to create Custom Page Styles, and assign a unique name to them. You can add your own header image and color selection to the checkout form. Once you\\\'ve created a Custom Page Style at PayPal®, you can enter that Page Style here.\\n\\nIn addition. The Shortcode below, provided by s2Member; supports an image attribute: image=\\\'\\\'default\\\'\\\'. This can be changed to a full URL, pointing to a custom image of your own; instead of the default PayPal® Button image.\'); return false;" tabindex="-1">[?]</a>: <input type="text" id="ws-plugin--s2member-ccap-page-style" value="paypal" size="18" /> <select id="ws-plugin--s2member-ccap-currency">' . file_get_contents (dirname (dirname (__FILE__)) . "/templates/options/paypal-currencies.html") . '</select> <input type="button" value="Generate Button Code" onclick="ws_plugin__s2member_paypalCcapButtonGenerate();" class="button-primary" /></p>' . "\n";
265
+ echo '<p>Description: <input type="text" id="ws-plugin--s2member-ccap-desc" value="Description and pricing details here." size="73" /></p>' . "\n";
266
+ echo '<p>Custom Capabilities ( comma-delimited ) <a href="#" onclick="alert(\'Optional. This is VERY advanced.\\nSee: s2Member -> API Scripting -> Custom Capabilities.\\n\\n*ADVANCED TIP: You can specifiy a list of Custom Capabilities that will be (Added) with this purchase. Or, you could tell s2Member to (Remove All) Custom Capabilities that may or may not already exist for a particular Member, and (Add) only the new ones that you specify. To do this, just start your list of Custom Capabilities with `-all`.\\n\\nSo instead of just (Adding) Custom Capabilities:\\nmusic,videos,archives,gifts\\n\\nYou could (Remove All) that may already exist, and then (Add) new ones:\\n-all,calendar,forums,tools\'); return false;" tabindex="-1">[?]</a> <input type="text" id="ws-plugin--s2member-ccap-ccaps" size="40" maxlength="125" /></p>' . "\n";
267
+ echo '</form>' . "\n";
268
+ echo '</td>' . "\n";
269
+ /**/
270
+ echo '</tr>' . "\n";
271
+ echo '<tr>' . "\n";
272
+ /**/
273
+ echo '<td colspan="2">' . "\n";
274
+ echo '<form onsubmit="return false;">' . "\n";
275
+ do_action ("ws_plugin__s2member_during_paypal_buttons_page_during_left_sections_during_ccap_buttons_before_shortcode", get_defined_vars ());
276
+ echo '<strong>WordPress® Shortcode:</strong> ( recommended for both the WordPress® Visual &amp; HTML Editors )<br />' . "\n";
277
+ $ws_plugin__s2member_temp_s = trim (file_get_contents (dirname (dirname (__FILE__)) . "/templates/shortcodes/paypal-ccaps-checkout-button-shortcode.html"));
278
+ $ws_plugin__s2member_temp_s = preg_replace ("/%%custom%%/", c_ws_plugin__s2member_utils_strings::esc_ds (esc_attr ($_SERVER["HTTP_HOST"])), $ws_plugin__s2member_temp_s);
279
+ echo '<input id="ws-plugin--s2member-ccap-shortcode" type="text" value="' . format_to_edit ($ws_plugin__s2member_temp_s) . '" onclick="this.select ();" style="font-family:Consolas, monospace; width:99%;" />' . "\n";
280
+ /**/
281
+ echo '<div' . ((is_multisite () && c_ws_plugin__s2member_utils_conds::is_multisite_farm () && !is_main_site ()) ? ' style="display:none;"' : '') . '><br />' . "\n";
282
+ echo '<strong>Resulting PayPal® Button Code:</strong> ( ultimately, your Shortcode will produce this snippet )<br />' . "\n";
283
+ echo '<textarea id="ws-plugin--s2member-ccap-button" rows="8" wrap="off" onclick="this.select ();" style="font-family:Consolas, monospace; width:99%;">';
284
+ $ws_plugin__s2member_temp_s = trim (file_get_contents (dirname (dirname (__FILE__)) . "/templates/buttons/paypal-ccaps-checkout-button.html"));
285
+ $ws_plugin__s2member_temp_s = preg_replace ("/%%endpoint%%/", c_ws_plugin__s2member_utils_strings::esc_ds (esc_attr (($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["paypal_sandbox"]) ? "www.sandbox.paypal.com" : "www.paypal.com")), $ws_plugin__s2member_temp_s);
286
+ $ws_plugin__s2member_temp_s = preg_replace ("/%%paypal_business%%/", c_ws_plugin__s2member_utils_strings::esc_ds (esc_attr ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["paypal_business"])), $ws_plugin__s2member_temp_s);
287
+ $ws_plugin__s2member_temp_s = preg_replace ("/%%cancel_return%%/", c_ws_plugin__s2member_utils_strings::esc_ds (esc_attr (home_url ("/"))), $ws_plugin__s2member_temp_s);
288
+ $ws_plugin__s2member_temp_s = preg_replace ("/%%notify_url%%/", c_ws_plugin__s2member_utils_strings::esc_ds (esc_attr (site_url ("/?s2member_paypal_notify=1"))), $ws_plugin__s2member_temp_s);
289
+ $ws_plugin__s2member_temp_s = preg_replace ("/%%return%%/", c_ws_plugin__s2member_utils_strings::esc_ds (esc_attr (site_url ("/?s2member_paypal_return=1"))), $ws_plugin__s2member_temp_s);
290
+ $ws_plugin__s2member_temp_s = preg_replace ("/%%custom%%/", c_ws_plugin__s2member_utils_strings::esc_ds (esc_attr ($_SERVER["HTTP_HOST"])), $ws_plugin__s2member_temp_s);
291
+ $ws_plugin__s2member_temp_s = preg_replace ("/%%images%%/", c_ws_plugin__s2member_utils_strings::esc_ds (esc_attr ($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["dir_url"] . "/images")), $ws_plugin__s2member_temp_s);
292
+ $ws_plugin__s2member_temp_s = preg_replace ("/%%wpurl%%/", c_ws_plugin__s2member_utils_strings::esc_ds (esc_attr (site_url ())), $ws_plugin__s2member_temp_s);
293
+ echo format_to_edit ($ws_plugin__s2member_temp_s);
294
+ echo '</textarea><br />' . "\n";
295
+ echo '&uarr; Use this more advanced Code if you\'re building a theme or plugin that integrates with s2Member.<br />' . "\n";
296
+ 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";
297
+ echo '</div>' . "\n";
298
+ /**/
299
+ echo '</form>' . "\n";
300
+ echo '</td>' . "\n";
301
+ /**/
302
+ echo '</tr>' . "\n";
303
+ echo '</tbody>' . "\n";
304
+ echo '</table>' . "\n";
305
+ echo '</div>' . "\n";
306
+ /**/
307
+ echo '</div>' . "\n";
308
+ /**/
309
+ do_action ("ws_plugin__s2member_during_paypal_buttons_page_during_left_sections_after_ccap_buttons", get_defined_vars ());
310
+ }
311
+ /**/
312
  if (apply_filters ("ws_plugin__s2member_during_paypal_buttons_page_during_left_sections_display_cancellation_buttons", true, get_defined_vars ()))
313
  {
314
  do_action ("ws_plugin__s2member_during_paypal_buttons_page_during_left_sections_before_cancellation_buttons", get_defined_vars ());
320
  echo '<p>Since all recurring charges are associated with a PayPal® Subscription; and every PayPal® Subscription is associated with a PayPal® Account; your Members will always have a PayPal® Account of their own, which is tied to their Membership with you. So... a Member can simply log into their own PayPal® account and cancel their Subscription(s) with you at anytime, all on their own. However, some Customers do not realize this. So, if you would like to make it clearer ( easier ) for Members to cancel their own Subscription(s), you can provide this Cancellation Button for them on your Login Welcome Page, or somewhere in the support section of your website. Note... you don\'t have to use this Cancellation Button at all, if you don\'t want to. It\'s completely optional.</p>' . "\n";
321
  echo '<p><em><strong>*Cancellation Process*</strong> Very simple. A Member clicks the Cancellation Button. PayPal® asks them to log into their PayPal® account. Once they\'re logged in, PayPal® will display a list of all active Subscriptions they have with you. They choose which ones they want to cancel, and s2Member is notified silently behind-the-scene, through the PayPal® IPN service.</em></p>' . "\n";
322
  echo '<p><em><strong>*Understanding Cancellations*</strong> It\'s important to realize that a Cancellation is not an EOT ( End Of Term ). All that happens during a Cancellation event, is that billing is stopped, and it\'s understood that the Customer is going to lose access, at some point in the future. This does NOT mean, that access will be revoked immediately. A separate EOT event will automatically handle a (demotion or deletion) later, at the appropriate time; which could be several days, or even a year after the Cancellation took place.</em></p>' . "\n";
323
+ echo '<p><em><strong>*Some Hairy Details*</strong> There might be times whenever you notice that a Member\'s Subscription has been cancelled through PayPal®... but, s2Member continues allowing the User access to your site as a paid Member. Please don\'t be confused by this... in 99.9% of these cases, the reason for this is legitimate. s2Member will only remove the User\'s Membership privileges when an EOT ( End Of Term ) is processed, a refund occurs, a chargeback occurs, or when a cancellation occurs - which would later result in a delayed Auto-EOT by s2Member.</em></p>' . "\n";
324
+ echo '<p><em>s2Member will not process an EOT ( End Of Term ) 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";
325
  do_action ("ws_plugin__s2member_during_paypal_buttons_page_during_left_sections_during_cancellation_buttons", get_defined_vars ());
326
  /**/
327
  echo '<table class="form-table">' . "\n";
408
  echo '</select></p>' . "\n";
409
  echo '<p>Paid Subscr. ID: <input id="ws-plugin--s2member-reg-link-subscr-id" type="text" value="" size="50" /> <a href="#" onclick="alert(\'The Customer\\\'s Paid Subscr. ID ( aka: Recurring Profile ID, Transaction ID ) must be unique. This value can be obtained from inside your PayPal® account under the History tab. Each paying Customer MUST be associated with a unique Paid Subscr. ID. If the Customer is NOT associated with a Paid Subscr. ID, you will need to generate a unique value for this field on your own. But keep in mind, s2Member will be unable to maintain future communication with the PayPal® IPN ( i.e. Notification ) service if this value does not reflect a real Paid Subscr. ID that exists in your PayPal® History log.\'); return false;" tabindex="-1">[?]</a></p>' . "\n";
410
  echo '<p>Custom String Value: <input id="ws-plugin--s2member-reg-link-custom" type="text" 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_sq (esc_attr ($_SERVER["HTTP_HOST"])) . '\\\'\\\' 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_sq (esc_attr ($_SERVER["HTTP_HOST"])) . '|cv1|cv2|cv3\'); return false;" tabindex="-1">[?]</a> <input type="button" value="Generate Access Link" onclick="ws_plugin__s2member_paypalRegLinkGenerate();" class="button-primary" /> <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";
411
+ 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" id="ws-plugin--s2member-reg-link-ccaps" size="40" maxlength="125" 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";
412
  echo '<p>Fixed Term Length ( for Buy Now transactions ): <input id="ws-plugin--s2member-reg-link-fixed-term" type="text" 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";
413
  echo '<p id="ws-plugin--s2member-reg-link" style="font-family:Consolas, monospace; display:none;"></p>' . "\n";
414
  echo '</form>' . "\n";
436
  echo '<p>In other words, Customers will NOT need to login, just to receive access to the Specific Post/Page they purchased access to. s2Member will immediately redirect the Customer to the Specific Post/Page after checkout is completed successfully. An email is also sent to the Customer with a link ( see: <code>s2Member -> PayPal® Options -> Specific Post/Page Email</code> ). Authentication is handled automatically through self-expiring links, good for 72 hours by default.</p>' . "\n";
437
  echo '<p>Specific Post/Page Access, is sort of like selling a product. Only, instead of shipping anything to the Customer, you just give them access to a specific Post/Page on your site; one that you created in WordPress®. A Specific Post/Page that is protected by s2Member, might contain a download link for your eBook, access to file &amp; music downloads, access to additional support services, and the list goes on and on. The possibilities with this are endless; as long as your digital product can be delivered through access to a WordPress® Post/Page that you\'ve created. To protect Specific Posts/Pages, please see: <code>s2Member -> Restriction Options -> Specific Post/Page Access</code>. Once you\'ve configured your Specific Post/Page Restrictions, those Posts/Pages will be available in the menus below.</p>' . "\n";
438
  echo '<p>Very simple. All you do is customize the form fields provided, for each Post/Page that you plan to sell. Then press (Generate Button Code). These special PayPal® Buttons are customized to work with s2Member seamlessly. You can even Package Additional Posts/Pages together into one transaction.</p>' . "\n";
439
+ echo '<p><em>* Buttons are NOT saved here. This is only a Button Generator. Once you\'ve generated your Button, copy/paste it into your WordPress® Editor. If you lose your Button Code, you\'ll need to come back &amp; re-generate a new one. If you\'re in Sandbox Test-Mode, and you\'re NOT using the Shortcode Format, please remember to come back and re-generate your Buttons before you go live.</em></p>' . "\n";
440
  do_action ("ws_plugin__s2member_during_paypal_buttons_page_during_left_sections_during_sp_buttons", get_defined_vars ());
441
  /**/
442
  echo '<table class="form-table">' . "\n";
609
  echo '<ul>' . "\n";
610
  echo '<li><code>cancel="0"</code> Cancellation Button. Only valid w/ Membership Level Access. Possible values: <code>0</code> = this is NOT a Cancellation Button, <code>1</code> = this IS a Cancellation Button.</li>' . "\n";
611
  echo '<li><code>cc="USD"</code> 3 character Currency Code. Not valid when <code>cancel="1"</code>.</li>' . "\n";
612
+ echo (!is_multisite () || !c_ws_plugin__s2member_utils_conds::is_multisite_farm () || is_main_site ()) ? '<li><code>ccaps="music,videos"</code> A comma-delimited list of Custom Capabilities. Only valid w/ Membership Level Access and/or Independent Capabilities.</li>' . "\n" : '';
613
  echo '<li><code>custom="' . esc_html ($_SERVER["HTTP_HOST"]) . '"</code> must start with your domain. Additional values can be piped in ( ex: <code>custom="' . esc_html ($_SERVER["HTTP_HOST"]) . '|cv1|cv2|cv3|etc"</code> ). Not valid when <code>cancel="1"</code>.</li>' . "\n";
614
  echo '<li><code>desc="Gold Membership"</code> A brief purchase Description. Not valid when <code>cancel="1"</code>.</li>' . "\n";
615
  echo '<li><code>dg="0"</code> The Digital Goods directive. s2Member will eventually be integrated with <a href="https://cms.paypal.com/us/cgi-bin/?cmd=_render-content&content_ID=developer/e_howto_api_IntroducingExpressCheckoutDG" target="_blank" rel="external">Digital Goods</a> for inline Express Checkout. But for now, this should always be <code>0</code>.</li>' . "\n";
617
  echo '<li><code>ids="14"</code> A Post/Page ID#, or a comma-delimited list of IDs. Only valid when <code>sp="1"</code> for Specific Post/Page Access.</li>' . "\n";
618
  echo '<li><code>image="default"</code> Button Image Location. Possible values: <code>default</code> = use the default PayPal® Button, <code>http://...</code> = location of your custom Image.</li>' . "\n";
619
  echo '<li><code>lc=""</code> Optional 2 character Locale Code <em>( i.e. Country Code )</em>. This controls the interface language used at PayPal® during checkout. If unspecified, the language is determined by PayPal® when possible, defaulting to <code>US</code> <em>english</em> when not possible. Not valid when <code>cancel="1"</code>.</li>' . "\n";
620
+ echo '<li><code>level="1"</code> Membership Level [1-4] <em>( or, up to the number of configured Levels )</em>. Only valid for Buttons providing paid Membership Level Access.' . ((is_multisite () && c_ws_plugin__s2member_utils_conds::is_multisite_farm () && !is_main_site ()) ? '' : ' Or, with Independent Custom Capabilities this MUST be set to <code>level="*"</code>.') . '</li>' . "\n";
621
  echo '<li><code>modify="0"</code> Modification directive. Only valid w/ Membership Level Access. Possible values: <code>0</code> = allows Customers to only create a new Subscription, <code>1</code> = allows Customers to modify their current Subscription or sign up for a new one, <code>2</code> = allows Customers to only modify their current Subscription.</li>' . "\n";
622
  echo '<li><code>ns="1"</code> The <em>no_shipping</em> directive. Possible values: <code>0</code> = prompt for an address, but do not require one, <code>1</code> = do not prompt for a shipping address, <code>2</code> = prompt for an address, and require one. Not valid when <code>cancel="1"</code>.</li>' . "\n";
623
  echo '<li><code>output="button"</code> Output Type. Possible values: <code>button</code> = PayPal® Button w/hidden inputs, <code>anchor</code> = PayPal® Button ( &lt;a&gt; anchor tag ) URL w/ ?query string, <code>url</code> = raw URL w/ ?query string.</li>' . "\n";
624
  echo '<li><code>ps="paypal"</code> PayPal® checkout Page Style. Not valid when <code>cancel="1"</code>.</li>' . "\n";
625
  echo '<li><code>ra="0.01"</code> Regular, Buy Now, and/or Recurring Amount. Must be &gt;= <code>0.01</code>. Not valid when <code>cancel="1"</code>.</li>' . "\n";
626
+ echo '<li><code>rp="1"</code> Regular Period. Only valid w/ Membership Level Access' . ((is_multisite () && c_ws_plugin__s2member_utils_conds::is_multisite_farm () && !is_main_site ()) ? '' : ' and/or Independent Custom Capabilities') . '. Must be &gt;= <code>1</code> ( ex: <code>1</code> Week, <code>2</code> Months, <code>1</code> Month, <code>3</code> Days ).</li>' . "\n";
627
+ echo '<li><code>rt="M"</code> Regular Term. Only valid w/ Membership Level Access' . ((is_multisite () && c_ws_plugin__s2member_utils_conds::is_multisite_farm () && !is_main_site ()) ? '' : ' and/or Independent Custom Capabilities') . '. Possible values: <code>D</code> = Days, <code>W</code> = Weeks, <code>M</code> = Months, <code>Y</code> = Years, <code>L</code> = Lifetime.</li>' . "\n";
628
+ echo '<li><code>rr="1"</code> Recurring directive. Only valid w/ Membership Level Access' . ((is_multisite () && c_ws_plugin__s2member_utils_conds::is_multisite_farm () && !is_main_site ()) ? '' : ' and/or Independent Custom Capabilities') . '. Possible values: <code>0</code> = non-recurring "Subscription" with possible Trial Period for free, or at a different Trial Amount; <code>1</code> = recurring "Subscription" with possible Trial Period for free, or at a different Trial Amount; <code>BN</code> = non-recurring "Buy Now" functionality, no Trial Period possible.</li>' . "\n";
629
  echo '<li><code>rrt=""</code> Recurring Times <em>( i.e. a fixed number of installments )</em>. Only valid w/ Membership Level Access. When unspecified, any recurring charges will remain ongoing until cancelled, or until payments start failing. If this is set to <code>1 or higher</code> the regular recurring charges will only continue for X billing cycles, depending on what you specify. This is only valid when <code>rr="1"</code> for recurring "Subscriptions". Please note that a fixed number of installments, also means a fixed period of access. If a Customer\'s billing is monthly, and you set <code>rrt="3"</code>, billing will continue for only 3 monthly installments. After that, billing would stop, and their access to the site would be revoked as well <em>( based on your EOT Behavior setting under: s2Member -> PayPal® Options )</em>.</li>' . "\n";
630
  echo '<li><code>rra="1"</code> Reattempt failed payments? Possible values: <code>0</code> = do NOT reattempt billing when/if a recurring payment fails; <code>1</code> = yes, DO reattempt billing when/if a recurring payment fails. With PayPal® Standard integration, PayPal® will retry a maximum of 2 times when you set <code>rra="1"</code>; after that, a Subscription would be terminated due to Max Failed Payments having been reached. PayPal® Standard integration does NOT make it possible to configure Max Failed Payments, it simply defaults to a value of <code>2</code> whenever <code>rra="1"</code>, indicating that you DO want to retry failed payments.</li>' . "\n";
631
  echo '<li><code>sp="0"</code> Specific Post/Page Button. Possible values: <code>0</code> = this is NOT a Specific Post/Page Access Button, <code>1</code> = this IS a Specific Post/Page Access Button.</li>' . "\n";
includes/menu-pages/paypal-ops.inc.php CHANGED
@@ -15,7 +15,7 @@
15
  * @since 3.0
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_paypal_ops"))
21
  {
@@ -360,7 +360,7 @@ if (!class_exists ("c_ws_plugin__s2member_menu_page_paypal_ops"))
360
  echo '<strong>You can also use these special Replacement Codes if you need them:</strong>' . "\n";
361
  echo '<ul>' . "\n";
362
  echo '<li><code>%%registration_url%%</code> = The full URL ( generated by s2Member ) where the Customer can get registered.</li>' . "\n";
363
- echo '<li><code>%%subscr_id%%</code> = The PayPal® Subscription ID, which remains constant throughout any &amp; all future payments. [ <a href="#" onclick="alert(\'There is one exception. If you are selling Lifetime or Fixed-Term ( non-recurring ) access, using Buy Now functionality; the %%subscr_id%% is actually set to the Transaction ID for the purchase.\\n\\nPayPal® does not provide a specific Subscription ID for Buy Now purchases. Since Lifetime &amp; Fixed-Term Subscriptions are NOT recurring ( i.e. there is only ONE payment ), using the Transaction ID as the Subscription ID is a graceful way to deal with this minor conflict.\'); return false;">?</a> ]</li>' . "\n";
364
  echo '<li><code>%%initial%%</code> = The Initial Fee charged during signup. If you offered a 100% Free Trial, this will be <code>0</code>. [ <a href="#" onclick="alert(\'This will always represent the amount of money the Customer spent, whenever they initially signed up, no matter what. If a Customer signs up, under the terms of a 100% Free Trial Period, this will be 0.\'); return false;">?</a> ]</li>' . "\n";
365
  echo '<li><code>%%regular%%</code> = The Regular Amount of the Subscription. This value is <code>always > 0</code>, no matter what. [ <a href="#" onclick="alert(\'This is how much the Subscription costs after an Initial Period expires. The %%regular%% rate is always > 0. If you did NOT offer an Initial Period at a different price, %%initial%% and %%regular%% will be equal to the same thing.\'); return false;">?</a> ]</li>' . "\n";
366
  echo '<li><code>%%recurring%%</code> = This is the amount that will be charged on a recurring basis, or <code>0</code> if non-recurring. [ <a href="#" onclick="alert(\'If Recurring Payments have not been required, this will be equal to 0. That being said, %%regular%% &amp; %%recurring%% are usually the same value. This variable can be used in two different ways. You can use it to determine what the Regular Recurring Rate is, or to determine whether the Subscription will recur or not. If it is going to recur, %%recurring%% will be > 0.\'); return false;">?</a> ]</li>' . "\n";
@@ -507,7 +507,8 @@ if (!class_exists ("c_ws_plugin__s2member_menu_page_paypal_ops"))
507
  echo '<h3>PayPal® EOT Behavior ( required, please choose )</h3>' . "\n";
508
  echo '<p>EOT = End Of Term. By default, s2Member will demote a paid Member to a Free Subscriber whenever their Subscription term has ended ( i.e. expired ), been cancelled, refunded, charged back to you, etc. s2Member demotes them to a Free Subscriber, so they will no longer have Member Level Access to your site. However, in some cases, you may prefer to have Customer accounts deleted completely, instead of just being demoted. This is where you choose which method works best for your site. If you don\'t want s2Member to take ANY action at all, you can disable s2Member\'s EOT System temporarily, or even completely.</p>' . "\n";
509
  echo '<p>The PayPal® IPN service will notify s2Member whenever a Member\'s payments have been failing, and/or whenever a Member\'s Subscription has expired for any reason. Even refunds &amp; chargeback reversals are supported through the IPN service. For example, if you issue a refund to an unhappy Customer through PayPal®, s2Member will eventually be notified, and the account for that Customer will either be demoted to a Free Subscriber, or deleted automatically ( based on your configuration ). The communication from PayPal® -> s2Member is seamless.</p>' . "\n";
510
- echo '<p><em><strong>*Some Hairy Details*</strong> There might be times whenever you notice that a Member\'s Subscription has been cancelled through PayPal®... but, s2Member continues allowing the User access to your site as a paid Member. Please don\'t be confused by this... in 99.9% of these cases, the reason for this is legitimate. s2Member will only remove the User\'s Membership privileges when an EOT ( End Of Term ) is processed, a refund occurs, a chargeback occurs, or when a cancellation occurs - which would later result in a delayed Auto-EOT by s2Member. 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";
 
511
  do_action ("ws_plugin__s2member_during_paypal_ops_page_during_left_sections_during_eot_behavior", get_defined_vars ());
512
  /**/
513
  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";
15
  * @since 3.0
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_paypal_ops"))
21
  {
360
  echo '<strong>You can also use these special Replacement Codes if you need them:</strong>' . "\n";
361
  echo '<ul>' . "\n";
362
  echo '<li><code>%%registration_url%%</code> = The full URL ( generated by s2Member ) where the Customer can get registered.</li>' . "\n";
363
+ echo '<li><code>%%subscr_id%%</code> = The PayPal® Subscription ID, which remains constant throughout any &amp; all future payments. [ <a href="#" onclick="alert(\'There is one exception. If you are selling Lifetime or Fixed-Term ( non-recurring ) access, using Buy Now functionality; the %%subscr_id%% is actually set to the Transaction ID for the purchase. PayPal® does not provide a specific Subscription ID for Buy Now purchases. Since Lifetime &amp; Fixed-Term Subscriptions are NOT recurring ( i.e. there is only ONE payment ), using the Transaction ID as the Subscription ID is a graceful way to deal with this minor conflict.\'); return false;">?</a> ]</li>' . "\n";
364
  echo '<li><code>%%initial%%</code> = The Initial Fee charged during signup. If you offered a 100% Free Trial, this will be <code>0</code>. [ <a href="#" onclick="alert(\'This will always represent the amount of money the Customer spent, whenever they initially signed up, no matter what. If a Customer signs up, under the terms of a 100% Free Trial Period, this will be 0.\'); return false;">?</a> ]</li>' . "\n";
365
  echo '<li><code>%%regular%%</code> = The Regular Amount of the Subscription. This value is <code>always > 0</code>, no matter what. [ <a href="#" onclick="alert(\'This is how much the Subscription costs after an Initial Period expires. The %%regular%% rate is always > 0. If you did NOT offer an Initial Period at a different price, %%initial%% and %%regular%% will be equal to the same thing.\'); return false;">?</a> ]</li>' . "\n";
366
  echo '<li><code>%%recurring%%</code> = This is the amount that will be charged on a recurring basis, or <code>0</code> if non-recurring. [ <a href="#" onclick="alert(\'If Recurring Payments have not been required, this will be equal to 0. That being said, %%regular%% &amp; %%recurring%% are usually the same value. This variable can be used in two different ways. You can use it to determine what the Regular Recurring Rate is, or to determine whether the Subscription will recur or not. If it is going to recur, %%recurring%% will be > 0.\'); return false;">?</a> ]</li>' . "\n";
507
  echo '<h3>PayPal® EOT Behavior ( required, please choose )</h3>' . "\n";
508
  echo '<p>EOT = End Of Term. By default, s2Member will demote a paid Member to a Free Subscriber whenever their Subscription term has ended ( i.e. expired ), been cancelled, refunded, charged back to you, etc. s2Member demotes them to a Free Subscriber, so they will no longer have Member Level Access to your site. However, in some cases, you may prefer to have Customer accounts deleted completely, instead of just being demoted. This is where you choose which method works best for your site. If you don\'t want s2Member to take ANY action at all, you can disable s2Member\'s EOT System temporarily, or even completely.</p>' . "\n";
509
  echo '<p>The PayPal® IPN service will notify s2Member whenever a Member\'s payments have been failing, and/or whenever a Member\'s Subscription has expired for any reason. Even refunds &amp; chargeback reversals are supported through the IPN service. For example, if you issue a refund to an unhappy Customer through PayPal®, s2Member will eventually be notified, and the account for that Customer will either be demoted to a Free Subscriber, or deleted automatically ( based on your configuration ). The communication from PayPal® -> s2Member is seamless.</p>' . "\n";
510
+ echo '<p><em><strong>*Some Hairy Details*</strong> There might be times whenever you notice that a Member\'s Subscription has been cancelled through PayPal®... but, s2Member continues allowing the User access to your site as a paid Member. Please don\'t be confused by this... in 99.9% of these cases, the reason for this is legitimate. s2Member will only remove the User\'s Membership privileges when an EOT ( End Of Term ) is processed, a refund occurs, a chargeback occurs, or when a cancellation occurs - which would later result in a delayed Auto-EOT by s2Member.</em></p>' . "\n";
511
+ 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";
512
  do_action ("ws_plugin__s2member_during_paypal_ops_page_during_left_sections_during_eot_behavior", get_defined_vars ());
513
  /**/
514
  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";
includes/menu-pages/scripting.inc.php CHANGED
@@ -15,7 +15,7 @@
15
  * @since 3.0
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_scripting"))
21
  {
@@ -330,7 +330,8 @@ if (!class_exists ("c_ws_plugin__s2member_menu_page_scripting"))
330
  echo '<p>Custom Capabilities are always prepended with <code>access_s2member_ccap_</code>. You fill in the last part, with ONLY lowercase alpha-numerics and/or underscores. For example, let\'s say you want to sell Membership Level #1, as is. But, you also want to sell a slight variation of Membership Level #1, that includes the ability to access the Music &amp; Video sections of your site. So, instead of selling this additional access under a whole new Membership Level, you could just sell a modified version of Membership Level #1. Add the the Custom Capabilities: <code>music,videos</code>. Once a Member has these Capabilities, you can test for these Capabilities using <code>current_user_can("access_s2member_ccap_music")</code> and <code>current_user_can("access_s2member_ccap_videos")</code>.</p>' . "\n";
331
  echo '<p>The important thing to realize, is that Custom Capabilities, are just that. They\'re custom. s2Member only deals with the default Capabilities that it uses. If you start using Custom Capabilities, you MUST use Simple or Advanced Conditionals ( <em>i.e. <code>current_user_can()</code> logic</em> ) to test for them. Either in your theme files with PHP, or in Posts/Pages using Simple Conditionals <em>( powered by Shortcodes )</em>.</p>' . "\n";
332
  echo '<p><strong>*New*</strong> Starting with s2Member v3.2+, you can now tell s2Member to require certain Custom Capabilities on a per Post/Page basis. So now, s2Member <em>( if you prefer )</em> CAN handle Custom Capabilities for you automatically! Whenever you edit a Post/Page, you can tell s2Member <em>( i.e. there is a Meta Box for s2Member in your Post/Page editing station )</em>... you can tell s2Member to require certain Custom Capabilities that you type in, using comma-delimited format. In other words, you will need to type in some of the trigger words that you used whenever you created your Payment Buttons/Forms. This way paying Members will have the Custom Capabilities to view different kinds of content that you offer.</p>' . "\n";
333
- echo '<p><strong>*New*</strong> By default, a Checkout Button or Form generated by s2Member is designed to set and/or reset a Member\'s Custom Capabilities to the ones you specify in the Button/Form Code. However, starting with s2Member v3.5+, you can tell s2Member to (ADD) additional Custom Capabilities to any that already exist for a particular Member. This is accomplished on a per Form/Button basis by preceding your comma-delimited list of Custom Capabilities with a (+) sign. For further details on this topic, click the <a href="#" onclick="alert(\'*ADVANCED TIP: You can specifiy a comma-delimited list of Custom Capabilities that come with a purchase. Or, you could tell s2Member to (ADD) Custom Capabilities to any that already exist for a particular Member. Just start your list of Custom Capabilities with a (+) sign.\\n\\nSo instead of setting a Member\\\'s full set of Custom Capabilities to:\\nmusic,videos,archives,gifts\\n\\nYou could (ADD) new ones to any that already exist:\\n+calendar,forums,tools\\n\\nOr to prevent any changes, (ADD) nothing:\\n+\'); return false;" tabindex="-1">[?]</a> icon next to the Custom Capabilities field in any Button/Form Generator supplied by s2Member.</p>' . "\n";
 
334
  do_action ("ws_plugin__s2member_during_scripting_page_during_left_sections_during_custom_capabilities", get_defined_vars ());
335
  /**/
336
  echo '<div class="ws-menu-page-hr"></div>' . "\n";
15
  * @since 3.0
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_scripting"))
21
  {
330
  echo '<p>Custom Capabilities are always prepended with <code>access_s2member_ccap_</code>. You fill in the last part, with ONLY lowercase alpha-numerics and/or underscores. For example, let\'s say you want to sell Membership Level #1, as is. But, you also want to sell a slight variation of Membership Level #1, that includes the ability to access the Music &amp; Video sections of your site. So, instead of selling this additional access under a whole new Membership Level, you could just sell a modified version of Membership Level #1. Add the the Custom Capabilities: <code>music,videos</code>. Once a Member has these Capabilities, you can test for these Capabilities using <code>current_user_can("access_s2member_ccap_music")</code> and <code>current_user_can("access_s2member_ccap_videos")</code>.</p>' . "\n";
331
  echo '<p>The important thing to realize, is that Custom Capabilities, are just that. They\'re custom. s2Member only deals with the default Capabilities that it uses. If you start using Custom Capabilities, you MUST use Simple or Advanced Conditionals ( <em>i.e. <code>current_user_can()</code> logic</em> ) to test for them. Either in your theme files with PHP, or in Posts/Pages using Simple Conditionals <em>( powered by Shortcodes )</em>.</p>' . "\n";
332
  echo '<p><strong>*New*</strong> Starting with s2Member v3.2+, you can now tell s2Member to require certain Custom Capabilities on a per Post/Page basis. So now, s2Member <em>( if you prefer )</em> CAN handle Custom Capabilities for you automatically! Whenever you edit a Post/Page, you can tell s2Member <em>( i.e. there is a Meta Box for s2Member in your Post/Page editing station )</em>... you can tell s2Member to require certain Custom Capabilities that you type in, using comma-delimited format. In other words, you will need to type in some of the trigger words that you used whenever you created your Payment Buttons/Forms. This way paying Members will have the Custom Capabilities to view different kinds of content that you offer.</p>' . "\n";
333
+ echo '<p><strong>*New*</strong> By default, a Checkout Button or Form generated by s2Member is designed to (Add) Custom Capabilities to any that may or may not already exist for a particular User/Member. However, starting with s2Member v110815+, you can tell s2Member to (Remove All) Custom Capabilities, and then (Add) only the new ones that you specify. This is accomplished on a per Form/Button basis by preceding your comma-delimited list of Custom Capabilities with `-all`. For further details on this topic, click the <a href="#" onclick="alert(\'*ADVANCED TIP: You can specifiy a list of Custom Capabilities that will be (Added) with this purchase. Or, you could tell s2Member to (Remove All) Custom Capabilities that may or may not already exist for a particular Member, and (Add) only the new ones that you specify. To do this, just start your list of Custom Capabilities with `-all`.\\n\\nSo instead of just (Adding) Custom Capabilities:\\nmusic,videos,archives,gifts\\n\\nYou could (Remove All) that may already exist, and then (Add) new ones:\\n-all,calendar,forums,tools\\n\\nOr to just (Remove All) and (Add) nothing:\\n-all\'); return false;" tabindex="-1">[?]</a> icon next to the Custom Capabilities field in any Button/Form Generator supplied by s2Member.</p>' . "\n";
334
+ echo '<p><strong>*New*</strong> Independent Custom Capabilities. You can now sell one or more Custom Capabilities using Buy Now functionality, to "existing" Users/Members, regardless of which Membership Level they have on your site <em>( i.e. you could even sell Independent Custom Capabilities to Users at Membership Level #0, normally referred to as Free Subscribers, if you like )</em>. So this is quite flexible. For further details, please check your Dashboard, under: <code>s2Member -> PayPal® Buttons -> Capability (Buy Now) Buttons</code>.</p>' . "\n";
335
  do_action ("ws_plugin__s2member_during_scripting_page_during_left_sections_during_custom_capabilities", get_defined_vars ());
336
  /**/
337
  echo '<div class="ws-menu-page-hr"></div>' . "\n";
includes/menu-pages/start.inc.php CHANGED
@@ -15,7 +15,7 @@
15
  * @since 3.0
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_start"))
21
  {
@@ -177,7 +177,8 @@ if (!class_exists ("c_ws_plugin__s2member_menu_page_start"))
177
  echo '<h3>Subscription Cancellations / Expirations / Terminations</h3>' . "\n";
178
  echo '<p>You\'ll be happy to know that s2Member handles cancellations, expirations, failed payments, terminations ( e.g. refunds &amp; chargebacks ) for you automatically. If you log into your PayPal® account and cancel a Member\'s Subscription, or, if the Member logs into their PayPal® account and cancels their own Subscription, s2Member will be notified of these important changes and react accordingly through the PayPal® IPN service that runs silently behind-the-scene.</p>' . "\n";
179
  echo '<p>The PayPal® IPN service will notify s2Member whenever a Member\'s payments have been failing, and/or whenever a Member\'s Subscription has expired for any reason. Even refunds &amp; chargeback reversals are supported through the IPN service. If you issue a refund to an unhappy Customer through PayPal®, s2Member will be notified, and the account for that Customer will either be demoted to a Free Subscriber, or deleted automatically ( based on your configuration ). The communication from PayPal® -> s2Member is seamless.</p>' . "\n";
180
- echo '<p><em><strong>*Some Hairy Details*</strong> There might be times whenever you notice that a Member\'s Subscription has been cancelled through PayPal®... but, s2Member continues allowing the User access to your site as a paid Member. Please don\'t be confused by this... in 99.9% of these cases, the reason for this is legitimate. s2Member will only remove the User\'s Membership privileges when an EOT ( End Of Term ) is processed, a refund occurs, a chargeback occurs, or when a cancellation occurs - which would later result in a delayed Auto-EOT by s2Member. 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";
 
181
  do_action ("ws_plugin__s2member_during_start_page_during_left_sections_during_automation_process", get_defined_vars ());
182
  echo '</div>' . "\n";
183
  /**/
15
  * @since 3.0
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_start"))
21
  {
177
  echo '<h3>Subscription Cancellations / Expirations / Terminations</h3>' . "\n";
178
  echo '<p>You\'ll be happy to know that s2Member handles cancellations, expirations, failed payments, terminations ( e.g. refunds &amp; chargebacks ) for you automatically. If you log into your PayPal® account and cancel a Member\'s Subscription, or, if the Member logs into their PayPal® account and cancels their own Subscription, s2Member will be notified of these important changes and react accordingly through the PayPal® IPN service that runs silently behind-the-scene.</p>' . "\n";
179
  echo '<p>The PayPal® IPN service will notify s2Member whenever a Member\'s payments have been failing, and/or whenever a Member\'s Subscription has expired for any reason. Even refunds &amp; chargeback reversals are supported through the IPN service. If you issue a refund to an unhappy Customer through PayPal®, s2Member will be notified, and the account for that Customer will either be demoted to a Free Subscriber, or deleted automatically ( based on your configuration ). The communication from PayPal® -> s2Member is seamless.</p>' . "\n";
180
+ echo '<p><em><strong>*Some Hairy Details*</strong> There might be times whenever you notice that a Member\'s Subscription has been cancelled through PayPal®... but, s2Member continues allowing the User access to your site as a paid Member. Please don\'t be confused by this... in 99.9% of these cases, the reason for this is legitimate. s2Member will only remove the User\'s Membership privileges when an EOT ( End Of Term ) is processed, a refund occurs, a chargeback occurs, or when a cancellation occurs - which would later result in a delayed Auto-EOT by s2Member.</em></p>' . "\n";
181
+ 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";
182
  do_action ("ws_plugin__s2member_during_start_page_during_left_sections_during_automation_process", get_defined_vars ());
183
  echo '</div>' . "\n";
184
  /**/
includes/menu-pages/trk-ops.inc.php CHANGED
@@ -15,7 +15,7 @@
15
  * @since 3.0
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_trk_ops"))
21
  {
@@ -49,12 +49,15 @@ if (!class_exists ("c_ws_plugin__s2member_menu_page_trk_ops"))
49
  {
50
  do_action ("ws_plugin__s2member_during_trk_ops_page_during_left_sections_before_signup_tracking", get_defined_vars ());
51
  /**/
52
- echo '<div class="ws-menu-page-group" title="Membership Signup Tracking Codes">' . "\n";
53
  /**/
54
  echo '<div class="ws-menu-page-section ws-plugin--s2member-signup-tracking-section">' . "\n";
55
- echo '<h3>Membership Signup Tracking Codes ( optional )</h3>' . "\n";
56
- echo '<p>If you use affiliate software, a list server, tracking codes from advertising networks, or the like; you\'ll want to read this section. The HTML' . ((is_multisite () && c_ws_plugin__s2member_utils_conds::is_multisite_farm () && !is_main_site ()) ? '' : ' and/or PHP') . ' code that you enter below, will be loaded up in a web browser, after a Customer completes Signup through your Payment Gateway. Tracking Codes are only displayed/processed one time for each Customer. s2Member will display your Tracking Codes in one of four possible locations... <strong>1.</strong> If possible, on the Thank-You Return Page, after returning from your Payment Gateway. <strong>2.</strong> Otherwise, if possible, on the Registration Form, after returning from your Payment Gateway. <em>Note. If you offer a 100% free Trial Period, Tracking Codes will be displayed in location #2 when using PayPal® Standard Button integration.</em> <strong>3.</strong> Otherwise, if possible, on the Login Form after Registration is completed. <strong>4.</strong> Otherwise, in the footer of your WordPress® theme, as soon as possible <em>( common with s2Member Pro Form integration )</em>; or after the Customer\'s very first login.</p>' . "\n";
57
- echo '<p>Signup Tracking Codes are displayed for all types of Membership Level Access. Including: Recurring Subscriptions ( with or without a Free Trial Period ), Non-Recurring Subscriptions ( with or without a Free Trial Period ), Lifetime Subscriptions, and even Fixed-Term Subscriptions. All of these are supported by s2Member\'s Button/Form Generators, and all of these are supported here.</p>' . "\n";
 
 
 
58
  do_action ("ws_plugin__s2member_during_trk_ops_page_during_left_sections_during_signup_tracking", get_defined_vars ());
59
  /**/
60
  echo '<table class="form-table">' . "\n";
@@ -75,7 +78,7 @@ if (!class_exists ("c_ws_plugin__s2member_menu_page_trk_ops"))
75
  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";
76
  echo '<strong>You can also use these special Replacement Codes if you need them:</strong>' . "\n";
77
  echo '<ul>' . "\n";
78
- echo '<li><code>%%subscr_id%%</code> = The Paid Subscription ID, which remains constant throughout any &amp; all future payments. [ <a href="#" onclick="alert(\'There is one exception. If you are selling Lifetime or Fixed-Term ( non-recurring ) access, using Buy Now functionality; the %%subscr_id%% is actually set to the Transaction ID for the purchase.\\n\\nPayment Gateways do not provide a specific Subscription ID for Buy Now purchases. Since Lifetime &amp; Fixed-Term Subscriptions are NOT recurring ( i.e. there is only ONE payment ), using the Transaction ID as the Subscription ID is a graceful way to deal with this minor conflict.\'); return false;">?</a> ]</li>' . "\n";
79
  echo '<li><code>%%initial%%</code> = The Initial Fee charged during signup. If you offered a 100% Free Trial Period, this will be <code>0</code>. [ <a href="#" onclick="alert(\'This will always represent the amount of money the Customer spent, whenever they initially signed up, no matter what. If a Customer signs up, under the terms of a 100% Free Trial Period, this will be 0.\'); return false;">?</a> ]</li>' . "\n";
80
  echo '<li><code>%%regular%%</code> = The Regular Amount of the Subscription. This value is <code>always > 0</code>, no matter what. [ <a href="#" onclick="alert(\'This is how much the Subscription costs after an Initial Period expires. The %%regular%% rate is always > 0. If you did NOT offer an Initial Period at a different price, %%initial%% and %%regular%% will be equal to the same thing.\'); return false;">?</a> ]</li>' . "\n";
81
  echo '<li><code>%%recurring%%</code> = This is the amount that will be charged on a recurring basis, or <code>0</code> if non-recurring. [ <a href="#" onclick="alert(\'If Recurring Payments have not been required, this will be equal to 0. That being said, %%regular%% &amp; %%recurring%% are usually the same value. This variable can be used in two different ways. You can use it to determine what the Regular Recurring Rate is, or to determine whether the Subscription will recur or not. If it is going to recur, %%recurring%% will be > 0.\'); return false;">?</a> ]</li>' . "\n";
@@ -111,6 +114,165 @@ if (!class_exists ("c_ws_plugin__s2member_menu_page_trk_ops"))
111
  do_action ("ws_plugin__s2member_during_trk_ops_page_during_left_sections_after_signup_tracking", get_defined_vars ());
112
  }
113
  /**/
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
114
  if (apply_filters ("ws_plugin__s2member_during_trk_ops_page_during_left_sections_display_sp_tracking", true, get_defined_vars ()))
115
  {
116
  do_action ("ws_plugin__s2member_during_trk_ops_page_during_left_sections_before_sp_tracking", get_defined_vars ());
@@ -119,7 +281,7 @@ if (!class_exists ("c_ws_plugin__s2member_menu_page_trk_ops"))
119
  /**/
120
  echo '<div class="ws-menu-page-section ws-plugin--s2member-sp-tracking-section">' . "\n";
121
  echo '<h3>Tracking Codes For Specific Post/Page Access ( optional )</h3>' . "\n";
122
- echo '<p>If you use affiliate software, a list server, tracking codes from advertising networks, or the like; you\'ll want to read this section. The HTML' . ((is_multisite () && c_ws_plugin__s2member_utils_conds::is_multisite_farm () && !is_main_site ()) ? '' : ' and/or PHP') . ' code that you enter below, will be loaded up in a web browser, after a Customer completes a successful transaction through your Payment Gateway; specifically for Post/Page Access. These Codes are NOT injected for any type of Membership Level Access. These are only for Specific Post/Page transactions. The Tracking Codes that you enter below, will be displayed in one of two possible locations... <strong>1.</strong> If possible, on the Thank-You Return Page, after returning from your Payment Gateway. <strong>2.</strong> Otherwise, in the footer of your WordPress® theme, as soon as possible <em>( common with s2Member Pro Form integration )</em>.</p>' . "\n";
123
  do_action ("ws_plugin__s2member_during_trk_ops_page_during_left_sections_during_sp_tracking", get_defined_vars ());
124
  /**/
125
  echo '<table class="form-table">' . "\n";
@@ -172,24 +334,53 @@ if (!class_exists ("c_ws_plugin__s2member_menu_page_trk_ops"))
172
  do_action ("ws_plugin__s2member_during_trk_ops_page_during_left_sections_after_sp_tracking", get_defined_vars ());
173
  }
174
  /**/
 
 
 
 
 
 
 
 
 
 
 
175
  if (apply_filters ("ws_plugin__s2member_during_trk_ops_page_during_left_sections_display_idev", true, get_defined_vars ()))
176
  {
177
  do_action ("ws_plugin__s2member_during_trk_ops_page_during_left_sections_before_idev", get_defined_vars ());
178
  /**/
179
- echo '<div class="ws-menu-page-group" title="Integrating iDevAffiliate® Software">' . "\n";
180
  /**/
181
  echo '<div class="ws-menu-page-section ws-plugin--s2member-idev-section">' . "\n";
182
  echo '<h3>Integrating iDevAffiliate® ( affiliate program management )</h3>' . "\n";
183
  echo '<a href="http://www.idevdirect.com/14200.html" target="_blank"><img src="' . esc_attr ($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["dir_url"]) . '/images/idev-logo.gif" class="ws-menu-page-right" style="width:125px; height:125px; border:0;" alt="." /></a>' . "\n";
184
  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.idevdirect.com/14200.html" 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.idevdirect.com/14200.html" 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";
185
- echo '<p>If you choose to <a href="http://www.idevdirect.com/14200.html" 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 the Custom Tracking field at the top of this page. You MUST also add Replacement Codes to your Hidden Image Tag. To save you some trouble, we\'ve provided two examples below. The first example is for Signup Tracking ( Membership Access ), and the second example is for Specific Post/Page Tracking.</p>' . "\n";
186
  do_action ("ws_plugin__s2member_during_trk_ops_page_during_left_sections_during_idev", get_defined_vars ());
 
187
  echo '<div class="ws-menu-page-hr"></div>' . "\n";
 
188
  echo '<p>idev_saleamt=<strong>%%initial%%</strong><br />idev_ordernum=<strong>%%subscr_id%%</strong></p>' . "\n";
189
  echo '<p>' . c_ws_plugin__s2member_utils_strings::highlight_php (file_get_contents (dirname (__FILE__) . "/code-samples/idev-signup-tracking-code.php")) . '</p>' . "\n";
 
190
  echo '<div class="ws-menu-page-hr"></div>' . "\n";
 
 
 
 
 
 
 
 
 
 
 
 
 
 
191
  echo '<p>idev_saleamt=<strong>%%amount%%</strong><br />idev_ordernum=<strong>%%txn_id%%</strong></p>' . "\n";
192
  echo '<p>' . c_ws_plugin__s2member_utils_strings::highlight_php (file_get_contents (dirname (__FILE__) . "/code-samples/idev-sp-tracking-code.php")) . '</p>' . "\n";
 
193
  echo '<div class="ws-menu-page-hr"></div>' . "\n";
194
  echo '<p>Your <code>profile</code> ID will be assigned by iDevAffiliate®. Be sure to replace <code>profile=123</code> with your own profile ID.</p>' . "\n";
195
  echo '<p><em><strong>*Tip*</strong> iDevAffiliate® also provides an alternative method, using a 3rd-party call. The alternative 3rd-party call, could be used with <code>s2Member -> API Notifications.</code> A 3rd-party call, is essentially an HTTP connection that runs silently behind-the-scene, as opposed to being loaded in a browser. It\'s a bit more powerful, but also more advanced.</em></p>' . "\n";
@@ -204,20 +395,38 @@ if (!class_exists ("c_ws_plugin__s2member_menu_page_trk_ops"))
204
  {
205
  do_action ("ws_plugin__s2member_during_trk_ops_page_during_left_sections_before_shareasale", get_defined_vars ());
206
  /**/
207
- echo '<div class="ws-menu-page-group" title="Integrating ShareASale® Tracking">' . "\n";
208
  /**/
209
  echo '<div class="ws-menu-page-section ws-plugin--s2member-shareasale-section">' . "\n";
210
  echo '<h3>Integrating ShareASale® ( affiliate program management )</h3>' . "\n";
211
  echo '<a href="http://www.shareasale.com/merchantsignup.cfm" target="_blank"><img src="' . esc_attr ($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["dir_url"]) . '/images/sas-logo.png" class="ws-menu-page-right" style="width:125px; height:125px; border:0;" alt="." /></a>' . "\n";
212
  echo '<p>Established in 2000, <a href="http://www.shareasale.com/merchantsignup.cfm" 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";
213
- echo '<p>If you <a href="http://www.shareasale.com/merchantsignup.cfm" 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 the Custom Tracking field at the top of this page. You MUST also add Replacement Codes to your Hidden Image Tag. To save you some trouble, we\'ve provided two examples below. The first example is for Signup Tracking ( Membership Access ), and the second example is for Specific Post/Page Tracking. The variables are different, depending on which type of transaction you\'re tracking.</p>' . "\n";
214
  do_action ("ws_plugin__s2member_during_trk_ops_page_during_left_sections_during_shareasale", get_defined_vars ());
 
215
  echo '<div class="ws-menu-page-hr"></div>' . "\n";
 
216
  echo '<p>amount=<strong>%%initial%%</strong><br />tracking=<strong>%%subscr_id%%</strong></p>' . "\n";
217
  echo '<p>' . c_ws_plugin__s2member_utils_strings::highlight_php (file_get_contents (dirname (__FILE__) . "/code-samples/sas-signup-tracking-code.php")) . '</p>' . "\n";
 
218
  echo '<div class="ws-menu-page-hr"></div>' . "\n";
 
 
 
 
 
 
 
 
 
 
 
 
 
 
219
  echo '<p>amount=<strong>%%amount%%</strong><br />tracking=<strong>%%txn_id%%</strong></p>' . "\n";
220
  echo '<p>' . c_ws_plugin__s2member_utils_strings::highlight_php (file_get_contents (dirname (__FILE__) . "/code-samples/sas-sp-tracking-code.php")) . '</p>' . "\n";
 
221
  echo '<div class="ws-menu-page-hr"></div>' . "\n";
222
  echo '<p>Your <code>merchantID</code> will be assigned by ShareASale®. Be sure to replace <code>merchantID=123</code> with the one they assign you.</p>' . "\n";
223
  echo '<p><em><strong>*Tip*</strong> ShareASale® also provides an alternative method, using a 3rd-party call. The alternative 3rd-party call, could be used with <code>s2Member -> API Notifications.</code> A 3rd-party call, is essentially an HTTP connection that runs silently behind-the-scene, as opposed to being loaded in a browser. It\'s a bit more powerful, but also more advanced.</em></p>' . "\n";
15
  * @since 3.0
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_trk_ops"))
21
  {
49
  {
50
  do_action ("ws_plugin__s2member_during_trk_ops_page_during_left_sections_before_signup_tracking", get_defined_vars ());
51
  /**/
52
+ echo '<div class="ws-menu-page-group" title="Signup Tracking Codes">' . "\n";
53
  /**/
54
  echo '<div class="ws-menu-page-section ws-plugin--s2member-signup-tracking-section">' . "\n";
55
+ echo '<h3>Signup Tracking Codes ( optional )</h3>' . "\n";
56
+ echo '<p>If you use affiliate software, a list server, tracking codes from advertising networks, or the like; you\'ll want to read this section. The HTML' . ((is_multisite () && c_ws_plugin__s2member_utils_conds::is_multisite_farm () && !is_main_site ()) ? '' : ' and/or PHP') . ' code that you enter below, will be loaded up in a web browser, after a "new", "paying" Member, completes Signup through your Payment Gateway. This is marked `Signup`, because Signup Tracking Codes will be displayed each time a "new", "paying" Member, signs up. Depending on your fee structure, this may include a first Initial Payment that establishes their Subscription, or it may not.</p>' . "\n";
57
+ echo '<p>Signup Tracking Codes will only be displayed once for each Member. Signup Tracking Codes are displayed right after a "new", "paying" Member, signs up successfully through your Payment Gateway, regardless of whether any money has actually been transacted initially. In other words, Signup Tracking Codes are displayed anytime a "new", "paying" Member, signs up, even if you provided them with a 100% Free Trial Period <em>( e.g. no money is being transacted intially )</em>.</p>' . "\n";
58
+ echo '<p>s2Member will display your Signup Tracking Codes in one of four possible locations... <strong>1.</strong> If possible, on the Thank-You Return Page, after returning from your Payment Gateway. <strong>2.</strong> Otherwise, if possible, on the Registration Form, after returning from your Payment Gateway. <em>Note. If you offer a 100% free Trial Period, Tracking Codes will be displayed in location #2 when using PayPal® Standard Button integration.</em> <strong>3.</strong> Otherwise, if possible, on the Login Form after Registration is completed. <strong>4.</strong> Otherwise, in the footer of your WordPress® theme, as soon as possible <em>( immediately with s2Member Pro Form integration )</em>; or after the Customer\'s very first login.</p>' . "\n";
59
+ echo '<p>Signup Tracking Codes are displayed for all types of Membership Level Access. Including Recurring Subscriptions <em>( with or without a Free Trial Period )</em>, Non-Recurring Subscriptions <em>( with or without a Free Trial Period )</em>, Lifetime Subscriptions, and even Fixed-Term Subscriptions. All of these are supported by s2Member\'s Button/Form Generators.</p>' . "\n";
60
+ echo '<p>Signup Tracking Codes will NOT be processed for Free Subscribers that register without going through your Payment Gateway at all. Signup Tracking Codes will NOT be processed when an "existing" User/Member pays for a new Subscription <em>( see: Modification Tracking Codes for that scenario )</em>.' . ((is_multisite () && c_ws_plugin__s2member_utils_conds::is_multisite_farm () && !is_main_site ()) ? '' : ' And, Signup Tracking Codes will NOT be processed on Buy Now transactions for Independent Custom Capabilities <em>( see: Capability Tracking Codes for that scenario )</em>.') . '</p>' . "\n";
61
  do_action ("ws_plugin__s2member_during_trk_ops_page_during_left_sections_during_signup_tracking", get_defined_vars ());
62
  /**/
63
  echo '<table class="form-table">' . "\n";
78
  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";
79
  echo '<strong>You can also use these special Replacement Codes if you need them:</strong>' . "\n";
80
  echo '<ul>' . "\n";
81
+ echo '<li><code>%%subscr_id%%</code> = The Paid Subscription ID, which remains constant throughout any &amp; all future payments. [ <a href="#" onclick="alert(\'There is one exception. If you are selling Lifetime or Fixed-Term ( non-recurring ) access, using Buy Now functionality; the %%subscr_id%% is actually set to the Transaction ID for the purchase. Payment Gateways do not provide a specific Subscription ID for Buy Now purchases. Since Lifetime &amp; Fixed-Term Subscriptions are NOT recurring ( i.e. there is only ONE payment ), using the Transaction ID as the Subscription ID is a graceful way to deal with this minor conflict.\'); return false;">?</a> ]</li>' . "\n";
82
  echo '<li><code>%%initial%%</code> = The Initial Fee charged during signup. If you offered a 100% Free Trial Period, this will be <code>0</code>. [ <a href="#" onclick="alert(\'This will always represent the amount of money the Customer spent, whenever they initially signed up, no matter what. If a Customer signs up, under the terms of a 100% Free Trial Period, this will be 0.\'); return false;">?</a> ]</li>' . "\n";
83
  echo '<li><code>%%regular%%</code> = The Regular Amount of the Subscription. This value is <code>always > 0</code>, no matter what. [ <a href="#" onclick="alert(\'This is how much the Subscription costs after an Initial Period expires. The %%regular%% rate is always > 0. If you did NOT offer an Initial Period at a different price, %%initial%% and %%regular%% will be equal to the same thing.\'); return false;">?</a> ]</li>' . "\n";
84
  echo '<li><code>%%recurring%%</code> = This is the amount that will be charged on a recurring basis, or <code>0</code> if non-recurring. [ <a href="#" onclick="alert(\'If Recurring Payments have not been required, this will be equal to 0. That being said, %%regular%% &amp; %%recurring%% are usually the same value. This variable can be used in two different ways. You can use it to determine what the Regular Recurring Rate is, or to determine whether the Subscription will recur or not. If it is going to recur, %%recurring%% will be > 0.\'); return false;">?</a> ]</li>' . "\n";
114
  do_action ("ws_plugin__s2member_during_trk_ops_page_during_left_sections_after_signup_tracking", get_defined_vars ());
115
  }
116
  /**/
117
+ if (apply_filters ("ws_plugin__s2member_during_trk_ops_page_during_left_sections_display_modification_tracking", true, get_defined_vars ()))
118
+ {
119
+ do_action ("ws_plugin__s2member_during_trk_ops_page_during_left_sections_before_modification_tracking", get_defined_vars ());
120
+ /**/
121
+ echo '<div class="ws-menu-page-group" title="Modification Tracking Codes">' . "\n";
122
+ /**/
123
+ echo '<div class="ws-menu-page-section ws-plugin--s2member-modification-tracking-section">' . "\n";
124
+ echo '<h3>Modification Tracking Codes ( optional )</h3>' . "\n";
125
+ echo '<p>If you use affiliate software, a list server, tracking codes from advertising networks, or the like; you\'ll want to read this section. The HTML' . ((is_multisite () && c_ws_plugin__s2member_utils_conds::is_multisite_farm () && !is_main_site ()) ? '' : ' and/or PHP') . ' code that you enter below, will be loaded up in a web browser, each time a Subscription Modification occurs. This is marked `Modification`, because Modification Tracking Codes are displayed each time an "existing" User/Member <em>( even if they are/were a Free Subscriber )</em> signs up for a paid Subscription <em>( i.e. a Modification takes place against an existing account within WordPress® )</em>, or an "existing" Member modifies their paid Subscription terms <em>( again, a Modification takes places against an existing account within WordPress® )</em>. Depending on your fee structure, this may include a first Initial Payment that establishes their Subscription, or it may not.</p>' . "\n";
126
+ echo '<p>Modification Tracking Codes are displayed right after a Member signs up and/or modifies billing terms successfully through your Payment Gateway, regardless of whether any money has actually been transacted initially. In other words, Modification Tracking Codes are displayed, even if you provided them with a 100% Free Trial Period <em>( e.g. no money is being transacted intially )</em>.</p>' . "\n";
127
+ echo '<p>s2Member will display your Modification Tracking Codes in one of three possible locations... <strong>1.</strong> If possible, on the Thank-You Return Page, after returning from your Payment Gateway. <strong>2.</strong> Otherwise, if possible, on the Login Form after returning from your Payment Gateway <em>( i.e. when the Customer is asked to log back in )</em>. <strong>3.</strong> Otherwise, in the footer of your WordPress® theme, as soon as possible <em>( immediately with s2Member Pro Form integration )</em>; or after the Customer\'s next login.</p>' . "\n";
128
+ echo '<p>Modification Tracking Codes are displayed for all types of Membership Level Access. Including Recurring Subscriptions <em>( with or without a Free Trial Period )</em>, Non-Recurring Subscriptions <em>( with or without a Free Trial Period )</em>, Lifetime Subscriptions, and even Fixed-Term Subscriptions. All of these are supported by s2Member\'s Button/Form Generators.</p>' . "\n";
129
+ echo '<p>Modification Tracking Codes will NOT be processed for Free Subscribers that register without going through your Payment Gateway at all. Modification Tracking Codes will NOT be processed when a "new" User/Member signs up <em>( see: Signup Tracking Codes for that scenario )</em>.' . ((is_multisite () && c_ws_plugin__s2member_utils_conds::is_multisite_farm () && !is_main_site ()) ? '' : ' And, Modification Tracking Codes will NOT be processed on Buy Now transactions for Independent Custom Capabilities <em>( see: Capability Tracking Codes for that scenario )</em>.') . '</p>' . "\n";
130
+ do_action ("ws_plugin__s2member_during_trk_ops_page_during_left_sections_during_modification_tracking", get_defined_vars ());
131
+ /**/
132
+ echo '<table class="form-table">' . "\n";
133
+ echo '<tbody>' . "\n";
134
+ echo '<tr>' . "\n";
135
+ /**/
136
+ echo '<th>' . "\n";
137
+ echo '<label for="ws-plugin--s2member-modification-tracking-codes">' . "\n";
138
+ echo 'Integrate Modification Tracking Codes:' . "\n";
139
+ echo '</label>' . "\n";
140
+ echo '</th>' . "\n";
141
+ /**/
142
+ echo '</tr>' . "\n";
143
+ echo '<tr>' . "\n";
144
+ /**/
145
+ echo '<td>' . "\n";
146
+ echo '<textarea name="ws_plugin__s2member_modification_tracking_codes" id="ws-plugin--s2member-modification-tracking-codes" rows="8" wrap="off" spellcheck="false" style="font-family:Consolas, monospace;">' . format_to_edit ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["modification_tracking_codes"]) . '</textarea><br />' . "\n";
147
+ 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";
148
+ echo '<strong>You can also use these special Replacement Codes if you need them:</strong>' . "\n";
149
+ echo '<ul>' . "\n";
150
+ echo '<li><code>%%subscr_id%%</code> = The Paid Subscription ID, which remains constant throughout any &amp; all future payments. [ <a href="#" onclick="alert(\'There is one exception. If you are selling Lifetime or Fixed-Term ( non-recurring ) access, using Buy Now functionality; the %%subscr_id%% is actually set to the Transaction ID for the purchase. Payment Gateways do not provide a specific Subscription ID for Buy Now purchases. Since Lifetime &amp; Fixed-Term Subscriptions are NOT recurring ( i.e. there is only ONE payment ), using the Transaction ID as the Subscription ID is a graceful way to deal with this minor conflict.\'); return false;">?</a> ]</li>' . "\n";
151
+ echo '<li><code>%%initial%%</code> = The Initial Fee charged during signup. If you offered a 100% Free Trial Period, this will be <code>0</code>. [ <a href="#" onclick="alert(\'This will always represent the amount of money the Customer spent, whenever they initially signed up, no matter what. If a Customer signs up, under the terms of a 100% Free Trial Period, this will be 0.\'); return false;">?</a> ]</li>' . "\n";
152
+ echo '<li><code>%%regular%%</code> = The Regular Amount of the Subscription. This value is <code>always > 0</code>, no matter what. [ <a href="#" onclick="alert(\'This is how much the Subscription costs after an Initial Period expires. The %%regular%% rate is always > 0. If you did NOT offer an Initial Period at a different price, %%initial%% and %%regular%% will be equal to the same thing.\'); return false;">?</a> ]</li>' . "\n";
153
+ echo '<li><code>%%recurring%%</code> = This is the amount that will be charged on a recurring basis, or <code>0</code> if non-recurring. [ <a href="#" onclick="alert(\'If Recurring Payments have not been required, this will be equal to 0. That being said, %%regular%% &amp; %%recurring%% are usually the same value. This variable can be used in two different ways. You can use it to determine what the Regular Recurring Rate is, or to determine whether the Subscription will recur or not. If it is going to recur, %%recurring%% will be > 0.\'); return false;">?</a> ]</li>' . "\n";
154
+ echo '<li><code>%%first_name%%</code> = The First Name of the Customer who purchased the Membership Subscription.</li>' . "\n";
155
+ echo '<li><code>%%last_name%%</code> = The Last Name of the Customer who purchased the Membership Subscription.</li>' . "\n";
156
+ echo '<li><code>%%full_name%%</code> = The Full Name ( First &amp; Last ) of the Customer who purchased the Membership Subscription.</li>' . "\n";
157
+ echo '<li><code>%%payer_email%%</code> = The Email Address of the Customer who purchased the Membership Subscription.</li>' . "\n";
158
+ echo '<li><code>%%item_number%%</code> = The Item Number ( colon separated <code><em>level:custom_capabilities:fixed term</em></code> ) that the Subscription is for.</li>' . "\n";
159
+ echo '<li><code>%%item_name%%</code> = The Item Name ( as provided by the <code>desc=""</code> attribute in your Shortcode, which briefly describes the Item Number ).</li>' . "\n";
160
+ echo '<li><code>%%initial_term%%</code> = This is the term length of the Initial Period. This will be a numeric value, followed by a space, then a single letter. [ <a href="#" onclick="alert(\'Here are some examples:\\n\\n%%initial_term%% = 1 D ( this means 1 Day )\\n%%initial_term%% = 1 W ( this means 1 Week )\\n%%initial_term%% = 1 M ( this means 1 Month )\\n%%initial_term%% = 1 Y ( this means 1 Year )\\n\\nThe Initial Period never recurs, so this only lasts for the term length specified, then it is over.\'); return false;">?</a> ]</li>' . "\n";
161
+ echo '<li><code>%%regular_term%%</code> = This is the term length of the Regular Period. This will be a numeric value, followed by a space, then a single letter. [ <a href="#" onclick="alert(\'Here are some examples:\\n\\n%%regular_term%% = 1 D ( this means 1 Day )\\n%%regular_term%% = 1 W ( this means 1 Week )\\n%%regular_term%% = 1 M ( this means 1 Month )\\n%%regular_term%% = 1 Y ( this means 1 Year )\\n%%regular_term%% = 1 L ( this means 1 Lifetime )\\n\\nThe Regular Term is usually recurring. So the Regular Term value represents the period ( or duration ) of each recurring period. If %%recurring%% = 0, then the Regular Term only applies once, because it is not recurring. So if it is not recurring, the value of %%regular_term%% simply represents how long their Membership privileges are going to last after the %%initial_term%% has expired, if there was an Initial Term. The value of this variable ( %%regular_term%% ) will never be empty, it will always be at least: 1 D, meaning 1 day. No exceptions.\'); return false;">?</a> ]</li>' . "\n";
162
+ echo '<li><code>%%user_first_name%%</code> = The First Name listed on their User account. This might be different than what is on file with your Payment Gateway.</li>' . "\n";
163
+ echo '<li><code>%%user_last_name%%</code> = The Last Name listed on their User account. This might be different than what is on file with your Payment Gateway.</li>' . "\n";
164
+ echo '<li><code>%%user_full_name%%</code> = The Full Name listed on their User account. This might be different than what is on file with your Payment Gateway.</li>' . "\n";
165
+ echo '<li><code>%%user_email%%</code> = The Email Address associated with their User account. This might be different than what is on file with your Payment Gateway.</li>' . "\n";
166
+ echo '<li><code>%%user_login%%</code> = The Username associated with their account. The Customer created this during registration.</li>' . "\n";
167
+ echo '<li><code>%%user_ip%%</code> = The Customer\'s original IP Address, during checkout/registration via <code>$_SERVER["REMOTE_ADDR"]</code>.</li>' . "\n";
168
+ echo '<li><code>%%user_id%%</code> = A unique WordPress® User ID that references this account in the WordPress® database.</li>' . "\n";
169
+ echo '</ul>' . "\n";
170
+ /**/
171
+ echo '<strong>Custom Registration Fields are also supported in this Notification:</strong>' . "\n";
172
+ echo '<ul>' . "\n";
173
+ echo '<li><code>%%date_of_birth%%</code> would be valid; if you have a Custom Registration Field with the ID <code>date_of_birth</code>.</li>' . "\n";
174
+ echo '<li><code>%%street_address%%</code> would be valid; if you have a Custom Registration Field with the ID <code>street_address</code>.</li>' . "\n";
175
+ echo '<li><code>%%country%%</code> would be valid; if you have a Custom Registration Field with the ID <code>country</code>.</li>' . "\n";
176
+ echo '<li><em><code>%%etc, etc...%%</code> <strong>see:</strong> s2Member -> General Options -> Custom Registration Fields</em>.</li>' . "\n";
177
+ echo '</ul>' . "\n";
178
+ /**/
179
+ echo '<strong>Custom Replacement Codes can also be inserted using these instructions:</strong>' . "\n";
180
+ echo '<ul>' . "\n";
181
+ echo '<li><code>%%cv0%%</code> = The domain of your site, which is passed through the `custom` attribute in your Shortcode.</li>' . "\n";
182
+ echo '<li><code>%%cv1%%</code> = If you need to track additional custom variables, you can pipe delimit them into the `custom` attribute; inside your Shortcode, like this: <code>custom="' . esc_html ($_SERVER["HTTP_HOST"]) . '|cv1|cv2|cv3"</code>. You can have an unlimited number of custom variables. Obviously, this is for advanced webmasters; but the functionality has been made available for those who need it.</li>' . "\n";
183
+ echo '</ul>' . "\n";
184
+ echo '<strong>This example uses cv1 to record a special marketing campaign:</strong><br />' . "\n";
185
+ echo '<em>( The campaign ( i.e. christmas-promo ) could be referenced using <code>%%cv1%%</code> )</em><br />' . "\n";
186
+ echo '<code>custom="' . esc_html ($_SERVER["HTTP_HOST"]) . '|christmas-promo"</code>' . "\n";
187
+ /**/
188
+ echo '</td>' . "\n";
189
+ /**/
190
+ echo '</tr>' . "\n";
191
+ echo '</tbody>' . "\n";
192
+ echo '</table>' . "\n";
193
+ echo '</div>' . "\n";
194
+ /**/
195
+ echo '</div>' . "\n";
196
+ /**/
197
+ do_action ("ws_plugin__s2member_during_trk_ops_page_during_left_sections_after_modification_tracking", get_defined_vars ());
198
+ }
199
+ /**/
200
+ if (apply_filters ("ws_plugin__s2member_during_trk_ops_page_during_left_sections_display_ccap_tracking", (!is_multisite () || !c_ws_plugin__s2member_utils_conds::is_multisite_farm () || is_main_site ()), get_defined_vars ()))
201
+ {
202
+ do_action ("ws_plugin__s2member_during_trk_ops_page_during_left_sections_before_ccap_tracking", get_defined_vars ());
203
+ /**/
204
+ echo '<div class="ws-menu-page-group" title="Capability Tracking Codes">' . "\n";
205
+ /**/
206
+ echo '<div class="ws-menu-page-section ws-plugin--s2member-ccap-tracking-section">' . "\n";
207
+ echo '<h3>Capability Tracking Codes ( optional )</h3>' . "\n";
208
+ echo '<p>If you use affiliate software, a list server, tracking codes from advertising networks, or the like; you\'ll want to read this section. The HTML' . ((is_multisite () && c_ws_plugin__s2member_utils_conds::is_multisite_farm () && !is_main_site ()) ? '' : ' and/or PHP') . ' code that you enter below, will be loaded up in a web browser, each time Independent Custom Capabilities are purchased. This is marked `Capability`, because Capability Tracking Codes are displayed each time an "existing" User/Member <em>( even if they are/were a Free Subscriber )</em> pays you for Independent Custom Capabilities through a Buy Now transaction. This is the only circumstance in which your Capability Tracking Codes will be displayed.</p>' . "\n";
209
+ echo '<p>s2Member will display your Capability Tracking Codes in one of three possible locations... <strong>1.</strong> If possible, on the Thank-You Return Page, after returning from your Payment Gateway. <strong>2.</strong> Otherwise, if possible, on the Login Form after returning from your Payment Gateway <em>( i.e. when the Customer is asked to log back in )</em>. <strong>3.</strong> Otherwise, in the footer of your WordPress® theme, as soon as possible <em>( immediately with s2Member Pro Form integration )</em>; or after the Customer\'s next login.</p>' . "\n";
210
+ do_action ("ws_plugin__s2member_during_trk_ops_page_during_left_sections_during_ccap_tracking", get_defined_vars ());
211
+ /**/
212
+ echo '<table class="form-table">' . "\n";
213
+ echo '<tbody>' . "\n";
214
+ echo '<tr>' . "\n";
215
+ /**/
216
+ echo '<th>' . "\n";
217
+ echo '<label for="ws-plugin--s2member-ccap-tracking-codes">' . "\n";
218
+ echo 'Integrate Capability Tracking Codes:' . "\n";
219
+ echo '</label>' . "\n";
220
+ echo '</th>' . "\n";
221
+ /**/
222
+ echo '</tr>' . "\n";
223
+ echo '<tr>' . "\n";
224
+ /**/
225
+ echo '<td>' . "\n";
226
+ echo '<textarea name="ws_plugin__s2member_ccap_tracking_codes" id="ws-plugin--s2member-ccap-tracking-codes" rows="8" wrap="off" spellcheck="false" style="font-family:Consolas, monospace;">' . format_to_edit ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["ccap_tracking_codes"]) . '</textarea><br />' . "\n";
227
+ 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";
228
+ echo '<strong>You can also use these special Replacement Codes if you need them:</strong>' . "\n";
229
+ echo '<ul>' . "\n";
230
+ echo '<li><code>%%txn_id%%</code> = The Payment Transaction ID, which is always unique for each payment received.</li>' . "\n";
231
+ echo '<li><code>%%amount%%</code> = The Amount of the payment. Most affiliate programs calculate commissions from this.</li>' . "\n";
232
+ echo '<li><code>%%first_name%%</code> = The First Name of the Customer who purchased the Independent Custom Capabilities.</li>' . "\n";
233
+ echo '<li><code>%%last_name%%</code> = The Last Name of the Customer who purchased the Independent Custom Capabilities.</li>' . "\n";
234
+ echo '<li><code>%%full_name%%</code> = The Full Name ( First &amp; Last ) of the Customer who purchased the Independent Custom Capabilities.</li>' . "\n";
235
+ echo '<li><code>%%payer_email%%</code> = The Email Address of the Customer who purchased the Independent Custom Capabilities.</li>' . "\n";
236
+ echo '<li><code>%%item_number%%</code> = The Item Number ( colon separated <code><em>*level:custom_capabilities:fixed term</em></code> ) that the payment is for. [ <a href="#" onclick="alert(\'With Independent Custom Capabilities, the `level` portion of this string will be an asterisk ( `*` ), since the Membership Level is irrelevant, and remains `as it was`.\'); return false;">?</a> ]</li>' . "\n";
237
+ echo '<li><code>%%item_name%%</code> = The Item Name ( as provided by the <code>desc=""</code> attribute in your Shortcode, which briefly describes the Item Number ).</li>' . "\n";
238
+ echo '<li><code>%%user_first_name%%</code> = The First Name listed on their User account. This might be different than what is on file with your Payment Gateway.</li>' . "\n";
239
+ echo '<li><code>%%user_last_name%%</code> = The Last Name listed on their User account. This might be different than what is on file with your Payment Gateway.</li>' . "\n";
240
+ echo '<li><code>%%user_full_name%%</code> = The Full Name listed on their User account. This might be different than what is on file with your Payment Gateway.</li>' . "\n";
241
+ echo '<li><code>%%user_email%%</code> = The Email Address associated with their User account. This might be different than what is on file with your Payment Gateway.</li>' . "\n";
242
+ echo '<li><code>%%user_login%%</code> = The Username associated with their account. The Customer created this during registration.</li>' . "\n";
243
+ echo '<li><code>%%user_ip%%</code> = The Customer\'s original IP Address, during checkout/registration via <code>$_SERVER["REMOTE_ADDR"]</code>.</li>' . "\n";
244
+ echo '<li><code>%%user_id%%</code> = A unique WordPress® User ID that references this account in the WordPress® database.</li>' . "\n";
245
+ echo '</ul>' . "\n";
246
+ /**/
247
+ echo '<strong>Custom Registration Fields are also supported in this Notification:</strong>' . "\n";
248
+ echo '<ul>' . "\n";
249
+ echo '<li><code>%%date_of_birth%%</code> would be valid; if you have a Custom Registration Field with the ID <code>date_of_birth</code>.</li>' . "\n";
250
+ echo '<li><code>%%street_address%%</code> would be valid; if you have a Custom Registration Field with the ID <code>street_address</code>.</li>' . "\n";
251
+ echo '<li><code>%%country%%</code> would be valid; if you have a Custom Registration Field with the ID <code>country</code>.</li>' . "\n";
252
+ echo '<li><em><code>%%etc, etc...%%</code> <strong>see:</strong> s2Member -> General Options -> Custom Registration Fields</em>.</li>' . "\n";
253
+ echo '</ul>' . "\n";
254
+ /**/
255
+ echo '<strong>Custom Replacement Codes can also be inserted using these instructions:</strong>' . "\n";
256
+ echo '<ul>' . "\n";
257
+ echo '<li><code>%%cv0%%</code> = The domain of your site, which is passed through the `custom` attribute in your Shortcode.</li>' . "\n";
258
+ echo '<li><code>%%cv1%%</code> = If you need to track additional custom variables, you can pipe delimit them into the `custom` attribute; inside your Shortcode, like this: <code>custom="' . esc_html ($_SERVER["HTTP_HOST"]) . '|cv1|cv2|cv3"</code>. You can have an unlimited number of custom variables. Obviously, this is for advanced webmasters; but the functionality has been made available for those who need it.</li>' . "\n";
259
+ echo '</ul>' . "\n";
260
+ echo '<strong>This example uses cv1 to record a special marketing campaign:</strong><br />' . "\n";
261
+ echo '<em>( The campaign ( i.e. christmas-promo ) could be referenced using <code>%%cv1%%</code> )</em><br />' . "\n";
262
+ echo '<code>custom="' . esc_html ($_SERVER["HTTP_HOST"]) . '|christmas-promo"</code>' . "\n";
263
+ /**/
264
+ echo '</td>' . "\n";
265
+ /**/
266
+ echo '</tr>' . "\n";
267
+ echo '</tbody>' . "\n";
268
+ echo '</table>' . "\n";
269
+ echo '</div>' . "\n";
270
+ /**/
271
+ echo '</div>' . "\n";
272
+ /**/
273
+ do_action ("ws_plugin__s2member_during_trk_ops_page_during_left_sections_after_ccap_tracking", get_defined_vars ());
274
+ }
275
+ /**/
276
  if (apply_filters ("ws_plugin__s2member_during_trk_ops_page_during_left_sections_display_sp_tracking", true, get_defined_vars ()))
277
  {
278
  do_action ("ws_plugin__s2member_during_trk_ops_page_during_left_sections_before_sp_tracking", get_defined_vars ());
281
  /**/
282
  echo '<div class="ws-menu-page-section ws-plugin--s2member-sp-tracking-section">' . "\n";
283
  echo '<h3>Tracking Codes For Specific Post/Page Access ( optional )</h3>' . "\n";
284
+ echo '<p>If you use affiliate software, a list server, tracking codes from advertising networks, or the like; you\'ll want to read this section. The HTML' . ((is_multisite () && c_ws_plugin__s2member_utils_conds::is_multisite_farm () && !is_main_site ()) ? '' : ' and/or PHP') . ' code that you enter below, will be loaded up in a web browser, after a Customer completes a successful transaction through your Payment Gateway; specifically for Post/Page Access. These Codes are NOT injected for any type of Membership Level Access' . ((is_multisite () && c_ws_plugin__s2member_utils_conds::is_multisite_farm () && !is_main_site ()) ? '' : ' or Independent Custom Capabilities') . '. These are only for Specific Post/Page transactions. The Tracking Codes that you enter below, will be displayed in one of two possible locations... <strong>1.</strong> If possible, on the Thank-You Return Page, after returning from your Payment Gateway. <strong>2.</strong> Otherwise, in the footer of your WordPress® theme, as soon as possible <em>( immediately with s2Member Pro Form integration )</em>.</p>' . "\n";
285
  do_action ("ws_plugin__s2member_during_trk_ops_page_during_left_sections_during_sp_tracking", get_defined_vars ());
286
  /**/
287
  echo '<table class="form-table">' . "\n";
334
  do_action ("ws_plugin__s2member_during_trk_ops_page_during_left_sections_after_sp_tracking", get_defined_vars ());
335
  }
336
  /**/
337
+ if (apply_filters ("ws_plugin__s2member_during_trk_ops_page_during_left_sections_display_integrations_header", true, get_defined_vars ()))
338
+ {
339
+ do_action ("ws_plugin__s2member_during_trk_ops_page_during_left_sections_before_integrations_header", get_defined_vars ());
340
+ /**/
341
+ echo '<div style="border-bottom:1px solid #DFDFDF; margin:-20px 0 9px 0; padding:0;">&nbsp;</div>' . "\n";
342
+ echo '<div id="icon-tools" class="icon32" style="margin-top:0; margin-bottom:0; padding-top:0; padding-bottom:0;"><br /></div>' . "\n";
343
+ echo '<h2 style="margin-top:0; margin-bottom:0; padding-top:0; padding-bottom:0;">API / Tracking Integrations</h2>' . "\n";
344
+ /**/
345
+ do_action ("ws_plugin__s2member_during_trk_ops_page_during_left_sections_after_integrations_header", get_defined_vars ());
346
+ }
347
+ /**/
348
  if (apply_filters ("ws_plugin__s2member_during_trk_ops_page_during_left_sections_display_idev", true, get_defined_vars ()))
349
  {
350
  do_action ("ws_plugin__s2member_during_trk_ops_page_during_left_sections_before_idev", get_defined_vars ());
351
  /**/
352
+ echo '<div class="ws-menu-page-group" title="Integrating iDevAffiliate®">' . "\n";
353
  /**/
354
  echo '<div class="ws-menu-page-section ws-plugin--s2member-idev-section">' . "\n";
355
  echo '<h3>Integrating iDevAffiliate® ( affiliate program management )</h3>' . "\n";
356
  echo '<a href="http://www.idevdirect.com/14200.html" target="_blank"><img src="' . esc_attr ($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["dir_url"]) . '/images/idev-logo.gif" class="ws-menu-page-right" style="width:125px; height:125px; border:0;" alt="." /></a>' . "\n";
357
  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.idevdirect.com/14200.html" 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.idevdirect.com/14200.html" 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";
358
+ echo '<p>If you choose to <a href="http://www.idevdirect.com/14200.html" 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";
359
  do_action ("ws_plugin__s2member_during_trk_ops_page_during_left_sections_during_idev", get_defined_vars ());
360
+ /**/
361
  echo '<div class="ws-menu-page-hr"></div>' . "\n";
362
+ echo '<p><strong>Signup Tracking Code, for iDevAffiliate® integration:</strong></p>' . "\n";
363
  echo '<p>idev_saleamt=<strong>%%initial%%</strong><br />idev_ordernum=<strong>%%subscr_id%%</strong></p>' . "\n";
364
  echo '<p>' . c_ws_plugin__s2member_utils_strings::highlight_php (file_get_contents (dirname (__FILE__) . "/code-samples/idev-signup-tracking-code.php")) . '</p>' . "\n";
365
+ /**/
366
  echo '<div class="ws-menu-page-hr"></div>' . "\n";
367
+ echo '<p><strong>Modification Tracking Code, for iDevAffiliate® integration:</strong></p>' . "\n";
368
+ echo '<p>idev_saleamt=<strong>%%initial%%</strong><br />idev_ordernum=<strong>%%subscr_id%%</strong></p>' . "\n";
369
+ echo '<p>' . c_ws_plugin__s2member_utils_strings::highlight_php (file_get_contents (dirname (__FILE__) . "/code-samples/idev-modification-tracking-code.php")) . '</p>' . "\n";
370
+ /**/
371
+ if (!is_multisite () || !c_ws_plugin__s2member_utils_conds::is_multisite_farm () || is_main_site ())
372
+ {
373
+ echo '<div class="ws-menu-page-hr"></div>' . "\n";
374
+ echo '<p><strong>Capability Tracking Code, for iDevAffiliate® integration:</strong></p>' . "\n";
375
+ echo '<p>idev_saleamt=<strong>%%amount%%</strong><br />idev_ordernum=<strong>%%txn_id%%</strong></p>' . "\n";
376
+ echo '<p>' . c_ws_plugin__s2member_utils_strings::highlight_php (file_get_contents (dirname (__FILE__) . "/code-samples/idev-ccap-tracking-code.php")) . '</p>' . "\n";
377
+ }
378
+ /**/
379
+ echo '<div class="ws-menu-page-hr"></div>' . "\n";
380
+ echo '<p><strong>Specific Post/Page Tracking Code, for iDevAffiliate® integration:</strong></p>' . "\n";
381
  echo '<p>idev_saleamt=<strong>%%amount%%</strong><br />idev_ordernum=<strong>%%txn_id%%</strong></p>' . "\n";
382
  echo '<p>' . c_ws_plugin__s2member_utils_strings::highlight_php (file_get_contents (dirname (__FILE__) . "/code-samples/idev-sp-tracking-code.php")) . '</p>' . "\n";
383
+ /**/
384
  echo '<div class="ws-menu-page-hr"></div>' . "\n";
385
  echo '<p>Your <code>profile</code> ID will be assigned by iDevAffiliate®. Be sure to replace <code>profile=123</code> with your own profile ID.</p>' . "\n";
386
  echo '<p><em><strong>*Tip*</strong> iDevAffiliate® also provides an alternative method, using a 3rd-party call. The alternative 3rd-party call, could be used with <code>s2Member -> API Notifications.</code> A 3rd-party call, is essentially an HTTP connection that runs silently behind-the-scene, as opposed to being loaded in a browser. It\'s a bit more powerful, but also more advanced.</em></p>' . "\n";
395
  {
396
  do_action ("ws_plugin__s2member_during_trk_ops_page_during_left_sections_before_shareasale", get_defined_vars ());
397
  /**/
398
+ echo '<div class="ws-menu-page-group" title="Integrating ShareASale®">' . "\n";
399
  /**/
400
  echo '<div class="ws-menu-page-section ws-plugin--s2member-shareasale-section">' . "\n";
401
  echo '<h3>Integrating ShareASale® ( affiliate program management )</h3>' . "\n";
402
  echo '<a href="http://www.shareasale.com/merchantsignup.cfm" target="_blank"><img src="' . esc_attr ($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["dir_url"]) . '/images/sas-logo.png" class="ws-menu-page-right" style="width:125px; height:125px; border:0;" alt="." /></a>' . "\n";
403
  echo '<p>Established in 2000, <a href="http://www.shareasale.com/merchantsignup.cfm" 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";
404
+ echo '<p>If you <a href="http://www.shareasale.com/merchantsignup.cfm" 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";
405
  do_action ("ws_plugin__s2member_during_trk_ops_page_during_left_sections_during_shareasale", get_defined_vars ());
406
+ /**/
407
  echo '<div class="ws-menu-page-hr"></div>' . "\n";
408
+ echo '<p><strong>Signup Tracking Code, for ShareASale® integration:</strong></p>' . "\n";
409
  echo '<p>amount=<strong>%%initial%%</strong><br />tracking=<strong>%%subscr_id%%</strong></p>' . "\n";
410
  echo '<p>' . c_ws_plugin__s2member_utils_strings::highlight_php (file_get_contents (dirname (__FILE__) . "/code-samples/sas-signup-tracking-code.php")) . '</p>' . "\n";
411
+ /**/
412
  echo '<div class="ws-menu-page-hr"></div>' . "\n";
413
+ echo '<p><strong>Modification Tracking Code, for ShareASale® integration:</strong></p>' . "\n";
414
+ echo '<p>amount=<strong>%%initial%%</strong><br />tracking=<strong>%%subscr_id%%</strong></p>' . "\n";
415
+ echo '<p>' . c_ws_plugin__s2member_utils_strings::highlight_php (file_get_contents (dirname (__FILE__) . "/code-samples/sas-modification-tracking-code.php")) . '</p>' . "\n";
416
+ /**/
417
+ if (!is_multisite () || !c_ws_plugin__s2member_utils_conds::is_multisite_farm () || is_main_site ())
418
+ {
419
+ echo '<div class="ws-menu-page-hr"></div>' . "\n";
420
+ echo '<p><strong>Capability Tracking Code, for ShareASale® integration:</strong></p>' . "\n";
421
+ echo '<p>amount=<strong>%%amount%%</strong><br />tracking=<strong>%%txn_id%%</strong></p>' . "\n";
422
+ echo '<p>' . c_ws_plugin__s2member_utils_strings::highlight_php (file_get_contents (dirname (__FILE__) . "/code-samples/sas-ccap-tracking-code.php")) . '</p>' . "\n";
423
+ }
424
+ /**/
425
+ echo '<div class="ws-menu-page-hr"></div>' . "\n";
426
+ echo '<p><strong>Specific Post/Page Tracking Code, for ShareASale® integration:</strong></p>' . "\n";
427
  echo '<p>amount=<strong>%%amount%%</strong><br />tracking=<strong>%%txn_id%%</strong></p>' . "\n";
428
  echo '<p>' . c_ws_plugin__s2member_utils_strings::highlight_php (file_get_contents (dirname (__FILE__) . "/code-samples/sas-sp-tracking-code.php")) . '</p>' . "\n";
429
+ /**/
430
  echo '<div class="ws-menu-page-hr"></div>' . "\n";
431
  echo '<p>Your <code>merchantID</code> will be assigned by ShareASale®. Be sure to replace <code>merchantID=123</code> with the one they assign you.</p>' . "\n";
432
  echo '<p><em><strong>*Tip*</strong> ShareASale® also provides an alternative method, using a 3rd-party call. The alternative 3rd-party call, could be used with <code>s2Member -> API Notifications.</code> A 3rd-party call, is essentially an HTTP connection that runs silently behind-the-scene, as opposed to being loaded in a browser. It\'s a bit more powerful, but also more advanced.</em></p>' . "\n";
includes/menu-pages/ws-mlist.inc.php CHANGED
@@ -15,7 +15,7 @@
15
  * @since 110524RC
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_pages_ws_mlist"))
21
  {
@@ -35,25 +35,29 @@ if (!class_exists ("c_ws_plugin__s2member_menu_pages_ws_mlist"))
35
  /**/
36
  if (!is_ssl ()) /* Feed panel. */
37
  {
38
- echo '<div id="ws-mlist-div-feed-animator">' . "\n";
39
- echo '<a href="http://feeds.feedburner.com/~r/s2member-updates/~6/1" target="_blank"><img src="http://feeds.feedburner.com/s2member-updates.1.gif" alt="s2Member® ( Updates )" style="border:0" /></a>' . "\n";
 
 
 
 
40
  echo '</div>' . "\n";
41
  }
42
  /**/
43
- echo '<div id="ws-mlist-div-header">' . "\n";
44
  echo '<ins>+</ins>Email Updates<em>!</em>' . "\n";
45
  echo '</div>' . "\n";
46
  /**/
47
- echo '<div id="ws-mlist-div-container">' . "\n";
48
  /**/
49
  echo '<div id="ws-mlist-div-fname">' . "\n";
50
  echo '<label for="ws-mlist-fname">First Name:</label><br />' . "\n";
51
- echo '<input type="text" name="FNAME" id="ws-mlist-fname" value="' . format_to_edit ($user->first_name) . '" />' . "\n";
52
  echo '</div>' . "\n";
53
  /**/
54
  echo '<div id="ws-mlist-div-lname">' . "\n";
55
  echo '<label for="ws-mlist-lname">Last Name:</label><br />' . "\n";
56
- echo '<input type="text" name="LNAME" id="ws-mlist-lname" value="' . format_to_edit ($user->last_name) . '" />' . "\n";
57
  echo '</div>' . "\n";
58
  /**/
59
  echo '<div id="ws-mlist-div-email">' . "\n";
15
  * @since 110524RC
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_pages_ws_mlist"))
21
  {
35
  /**/
36
  if (!is_ssl ()) /* Feed panel. */
37
  {
38
+ echo '<div class="ws-menu-page-r-group-header">' . "\n";
39
+ echo '<ins class="open">-</ins>Latest News<em>!</em>' . "\n";
40
+ echo '</div>' . "\n";
41
+ /**/
42
+ echo '<div class="ws-menu-page-r-group" style="display:block;">' . "\n";
43
+ echo '<script type="text/javascript" src="http://feeds.feedburner.com/s2member-updates?format=sigpro&amp;nItems=3&amp;openLinks=new&amp;displayTitle=false&amp;displayFeedIcon=false&amp;displayExcerpts=false&amp;displayAuthor=false&amp;displayDate=false&amp;displayEnclosures=false&amp;displayLinkToFeed=false"></script>' . "\n";
44
  echo '</div>' . "\n";
45
  }
46
  /**/
47
+ echo '<div class="ws-menu-page-r-group-header">' . "\n";
48
  echo '<ins>+</ins>Email Updates<em>!</em>' . "\n";
49
  echo '</div>' . "\n";
50
  /**/
51
+ echo '<div class="ws-menu-page-r-group">' . "\n";
52
  /**/
53
  echo '<div id="ws-mlist-div-fname">' . "\n";
54
  echo '<label for="ws-mlist-fname">First Name:</label><br />' . "\n";
55
+ echo '<input type="text" name="FNAME" id="ws-mlist-fname" value="' . esc_attr ($user->first_name) . '" />' . "\n";
56
  echo '</div>' . "\n";
57
  /**/
58
  echo '<div id="ws-mlist-div-lname">' . "\n";
59
  echo '<label for="ws-mlist-lname">Last Name:</label><br />' . "\n";
60
+ echo '<input type="text" name="LNAME" id="ws-mlist-lname" value="' . esc_attr ($user->last_name) . '" />' . "\n";
61
  echo '</div>' . "\n";
62
  /**/
63
  echo '<div id="ws-mlist-div-email">' . "\n";
includes/mime-types.ini CHANGED
@@ -185,7 +185,6 @@ mid = audio/midi
185
  midi = audio/midi
186
  mp2 = audio/mpeg
187
  mp3 = audio/mpeg
188
- mp4 = audio/mp4
189
  mpga = audio/mpeg
190
  ra = audio/x-pn-realaudio
191
  ram = audio/x-pn-realaudio
185
  midi = audio/midi
186
  mp2 = audio/mpeg
187
  mp3 = audio/mpeg
 
188
  mpga = audio/mpeg
189
  ra = audio/x-pn-realaudio
190
  ram = audio/x-pn-realaudio
includes/syscon.inc.php CHANGED
@@ -18,7 +18,7 @@
18
  * @since 3.0
19
  */
20
  if (realpath (__FILE__) === realpath ($_SERVER["SCRIPT_FILENAME"]))
21
- exit ("Do not access this file directly.");
22
  /*
23
  Determine the full URL to the directory this plugin resides in.
24
  */
@@ -34,9 +34,9 @@ $GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["max_levels"] = apply_filters ("ws_plug
34
  /*
35
  Configure regular expression matches for Membership Access Item Numbers ( including those with only Custom Capabilities ).
36
  */
37
- $GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["membership_item_number_w_level_regex"] = "/^([1-9][0-9]*)(?:(?:\:(\+?[a-z_0-9,]+|\+)?)?(?:\:([0-9]+ [A-Z])?)?)?$/";
38
- $GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["membership_item_number_wo_level_regex"] = "/^(\*)(?:(?:\:(\+?[a-z_0-9,]+|\+)?)?(?:\:([0-9]+ [A-Z])?)?)?$/";
39
- $GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["membership_item_number_w_or_wo_level_regex"] = "/^([1-9][0-9]*|\*)(?:(?:\:(\+?[a-z_0-9,]+|\+)?)?(?:\:([0-9]+ [A-Z])?)?)?$/";
40
  /*
41
  Configure regular expression match for Specific Post/Page Access Item Numbers ( all elements required here ).
42
  */
@@ -107,7 +107,7 @@ if (!function_exists ("ws_plugin__s2member_configure_options_and_their_defaults"
107
  $default_options["max_ip_restriction_time"] = "3600";
108
  $default_options["max_failed_login_attempts"] = "5";
109
  /**/
110
- $default_options["run_deactivation_routines"] = "1";
111
  /**/
112
  $default_options["custom_reg_fields"] = "";
113
  $default_options["custom_reg_names"] = "1";
@@ -176,11 +176,14 @@ if (!function_exists ("ws_plugin__s2member_configure_options_and_their_defaults"
176
  $default_options["paypal_btn_encryption"] = "0";
177
  /**/
178
  $default_options["signup_tracking_codes"] = "";
 
 
 
 
179
  $default_options["signup_email_recipients"] = '"%%full_name%%" <%%payer_email%%>';
180
  $default_options["signup_email_subject"] = "Congratulations! ( your membership has been approved )";
181
  $default_options["signup_email_message"] = "Thanks %%first_name%%! Your membership has been approved.\n\nIf you haven't already done so, the next step is to Register a Username.\n\nComplete your registration here:\n%%registration_url%%\n\nIf you have any trouble, please feel free to contact us.\n\nBest Regards,\n" . get_bloginfo ("name");
182
  /**/
183
- $default_options["sp_tracking_codes"] = "";
184
  $default_options["sp_email_recipients"] = '"%%full_name%%" <%%payer_email%%>';
185
  $default_options["sp_email_subject"] = "Thank You! ( instructions for access )";
186
  $default_options["sp_email_message"] = "Thanks %%first_name%%!\n\n%%item_name%%\n\nYour order can be retrieved here:\n%%sp_access_url%%\n( link expires in %%sp_access_exp%% )\n\nIf you have any trouble, please feel free to contact us.\n\nBest Regards,\n" . get_bloginfo ("name");
@@ -259,11 +262,6 @@ if (!function_exists ("ws_plugin__s2member_configure_options_and_their_defaults"
259
  /**/
260
  unset ($n, $v, $l); /* Unset/cleanup these working variables from the routines above. */
261
  /*
262
- Disable de-activation routines ( by default ) on a Multisite Blog Farm installation; excluding the Main Site.
263
- */
264
- if (is_multisite () && !is_main_site () && defined ("MULTISITE_FARM") && MULTISITE_FARM) /* Auto-protects Blog Owners. */
265
- $default_options["run_deactivation_routines"] = "0"; /* By default, disable all de-activation routines in this case. */
266
- /*
267
  Here they are merged. User options will overwrite some or all default values.
268
  */
269
  $GLOBALS["WS_PLUGIN__"]["s2member"]["o"] = array_merge ($default_options, (($options !== false) ? (array)$options : (array)get_option ("ws_plugin__s2member_options")));
@@ -293,7 +291,7 @@ if (!function_exists ("ws_plugin__s2member_configure_options_and_their_defaults"
293
  foreach ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"] as $key => &$value)
294
  {
295
  if (!isset ($default_options[$key]) && !preg_match ("/^pro_/", $key))
296
- unset ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"][$key]);
297
  /**/
298
  else if ($key === "options_checksum" && (!is_string ($value) || !strlen ($value)))
299
  $value = $default_options[$key];
@@ -406,7 +404,7 @@ if (!function_exists ("ws_plugin__s2member_configure_options_and_their_defaults"
406
  else if ($key === "paypal_btn_encryption" && (!is_string ($value) || !is_numeric ($value)))
407
  $value = $default_options[$key];
408
  /**/
409
- else if (preg_match ("/^(signup|sp)_tracking_codes$/", $key) && (!is_string ($value) || !strlen ($value)))
410
  $value = $default_options[$key];
411
  /**/
412
  else if (preg_match ("/^(signup|sp)_email_recipients$/", $key) && !is_string ($value)) /* Can be empty. */
18
  * @since 3.0
19
  */
20
  if (realpath (__FILE__) === realpath ($_SERVER["SCRIPT_FILENAME"]))
21
+ exit("Do not access this file directly.");
22
  /*
23
  Determine the full URL to the directory this plugin resides in.
24
  */
34
  /*
35
  Configure regular expression matches for Membership Access Item Numbers ( including those with only Custom Capabilities ).
36
  */
37
+ $GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["membership_item_number_w_level_regex"] = "/^([1-9][0-9]*)(?:(?:\:((?:-all\+|\+-all|-all|\+)?[a-z_0-9,\+]*)?)?(?:\:([0-9]+ [A-Z])?)?)?$/";
38
+ $GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["membership_item_number_wo_level_regex"] = "/^(\*)(?:(?:\:((?:-all\+|\+-all|-all|\+)?[a-z_0-9,\+]*)?)?(?:\:([0-9]+ [A-Z])?)?)?$/";
39
+ $GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["membership_item_number_w_or_wo_level_regex"] = "/^([1-9][0-9]*|\*)(?:(?:\:((?:-all\+|\+-all|-all|\+)?[a-z_0-9,\+]*)?)?(?:\:([0-9]+ [A-Z])?)?)?$/";
40
  /*
41
  Configure regular expression match for Specific Post/Page Access Item Numbers ( all elements required here ).
42
  */
107
  $default_options["max_ip_restriction_time"] = "3600";
108
  $default_options["max_failed_login_attempts"] = "5";
109
  /**/
110
+ $default_options["run_deactivation_routines"] = "0";
111
  /**/
112
  $default_options["custom_reg_fields"] = "";
113
  $default_options["custom_reg_names"] = "1";
176
  $default_options["paypal_btn_encryption"] = "0";
177
  /**/
178
  $default_options["signup_tracking_codes"] = "";
179
+ $default_options["modification_tracking_codes"] = "";
180
+ $default_options["ccap_tracking_codes"] = "";
181
+ $default_options["sp_tracking_codes"] = "";
182
+ /**/
183
  $default_options["signup_email_recipients"] = '"%%full_name%%" <%%payer_email%%>';
184
  $default_options["signup_email_subject"] = "Congratulations! ( your membership has been approved )";
185
  $default_options["signup_email_message"] = "Thanks %%first_name%%! Your membership has been approved.\n\nIf you haven't already done so, the next step is to Register a Username.\n\nComplete your registration here:\n%%registration_url%%\n\nIf you have any trouble, please feel free to contact us.\n\nBest Regards,\n" . get_bloginfo ("name");
186
  /**/
 
187
  $default_options["sp_email_recipients"] = '"%%full_name%%" <%%payer_email%%>';
188
  $default_options["sp_email_subject"] = "Thank You! ( instructions for access )";
189
  $default_options["sp_email_message"] = "Thanks %%first_name%%!\n\n%%item_name%%\n\nYour order can be retrieved here:\n%%sp_access_url%%\n( link expires in %%sp_access_exp%% )\n\nIf you have any trouble, please feel free to contact us.\n\nBest Regards,\n" . get_bloginfo ("name");
262
  /**/
263
  unset ($n, $v, $l); /* Unset/cleanup these working variables from the routines above. */
264
  /*
 
 
 
 
 
265
  Here they are merged. User options will overwrite some or all default values.
266
  */
267
  $GLOBALS["WS_PLUGIN__"]["s2member"]["o"] = array_merge ($default_options, (($options !== false) ? (array)$options : (array)get_option ("ws_plugin__s2member_options")));
291
  foreach ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"] as $key => &$value)
292
  {
293
  if (!isset ($default_options[$key]) && !preg_match ("/^pro_/", $key))
294
+ unset($GLOBALS["WS_PLUGIN__"]["s2member"]["o"][$key]);
295
  /**/
296
  else if ($key === "options_checksum" && (!is_string ($value) || !strlen ($value)))
297
  $value = $default_options[$key];
404
  else if ($key === "paypal_btn_encryption" && (!is_string ($value) || !is_numeric ($value)))
405
  $value = $default_options[$key];
406
  /**/
407
+ else if (preg_match ("/^(signup|modification|ccap|sp)_tracking_codes$/", $key) && (!is_string ($value) || !strlen ($value)))
408
  $value = $default_options[$key];
409
  /**/
410
  else if (preg_match ("/^(signup|sp)_email_recipients$/", $key) && !is_string ($value)) /* Can be empty. */
includes/templates/buttons/paypal-ccaps-checkout-button.html ADDED
@@ -0,0 +1,30 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <form action="https://%%endpoint%%/cgi-bin/webscr" method="post">
2
+ <input type="hidden" name="business" value="%%paypal_business%%" />
3
+ <input type="hidden" name="cmd" value="_xclick" />
4
+ <!-- Instant Payment Notification & Return Page Details -->
5
+ <input type="hidden" name="notify_url" value="%%notify_url%%" />
6
+ <input type="hidden" name="cancel_return" value="%%cancel_return%%" />
7
+ <input type="hidden" name="return" value="%%return%%" />
8
+ <input type="hidden" name="rm" value="2" />
9
+ <!-- Configures Basic Checkout Fields -->
10
+ <input type="hidden" name="lc" value="" />
11
+ <input type="hidden" name="no_shipping" value="1" />
12
+ <input type="hidden" name="no_note" value="1" />
13
+ <input type="hidden" name="custom" value="%%custom%%" />
14
+ <input type="hidden" name="currency_code" value="USD" />
15
+ <input type="hidden" name="page_style" value="paypal" />
16
+ <input type="hidden" name="charset" value="utf-8" />
17
+ <input type="hidden" name="item_name" value="Description and pricing details here." />
18
+ <input type="hidden" name="item_number" value="*:music,videos" />
19
+ <input type="hidden" name="amount" value="0.01" />
20
+ <!-- Configures s2Member's Unique Invoice ID/Code -->
21
+ <input type="hidden" name="invoice" value="<?php echo S2MEMBER_VALUE_FOR_PP_INV(); ?>" />
22
+ <!-- Associates Purchase With A User/Member ( when/if applicable ) -->
23
+ <input type="hidden" name="on0" value="<?php echo S2MEMBER_CURRENT_USER_VALUE_FOR_PP_ON0; ?>" />
24
+ <input type="hidden" name="os0" value="<?php echo S2MEMBER_CURRENT_USER_VALUE_FOR_PP_OS0; ?>" />
25
+ <!-- Identifies The Customer's IP Address For Tracking -->
26
+ <input type="hidden" name="on1" value="<?php echo S2MEMBER_CURRENT_USER_VALUE_FOR_PP_ON1; ?>" />
27
+ <input type="hidden" name="os1" value="<?php echo S2MEMBER_CURRENT_USER_VALUE_FOR_PP_OS1; ?>" />
28
+ <!-- Displays The PayPal® Image Button -->
29
+ <input type="image" src="https://www.paypal.com/en_US/i/btn/btn_xpressCheckout.gif" style="width:auto; height:auto; border:0;" alt="PayPal®" />
30
+ </form>
includes/templates/options/paypal-membership-ccap-terms.html ADDED
@@ -0,0 +1,3 @@
 
 
 
1
+ <optgroup label="PayPal® ( Buy Now )">
2
+ <option value="1-L-BN" selected="selected">One Time ( for lifetime access, non-recurring )</option>
3
+ </optgroup>
includes/templates/shortcodes/paypal-ccaps-checkout-button-shortcode.html ADDED
@@ -0,0 +1 @@
 
1
+ [s2Member-PayPal-Button level="*" ccaps="music,videos" desc="Description and pricing details here." ps="paypal" lc="" cc="USD" dg="0" ns="1" custom="%%custom%%" ra="0.01" rp="1" rt="L" rr="BN" image="default" output="button" /]
ms.txt CHANGED
@@ -1,7 +1,7 @@
1
  = Is s2Member compatible with WordPress® 3.0+ Multisite Networking ? =
2
- Yes. s2Member v3.2+, and also s2Member Pro, are BOTH compatible with Multisite Networking enabled. After you enable Multisite Networking, install the s2Member plugin. Then navigate to `s2Member -> Multisite ( Config )` in the Dashboard on your ( Main Site ). You can get started now, by turning on [Multisite Networking](http://codex.wordpress.org/Create_A_Network) inside your installation of WordPress®.
3
 
4
  = What about Multisite Networking ( WPMU ), used on a Blog Farm? =
5
- Yes, preliminary ( experimental ) support for Multisite Blog Farms has also been implemented. If you're running a Multisite Blog Farm ( i.e. you offer Blogs ), please contact s2Member.com for further details. With Multisite Networking enabled, your site could ALSO offer a Customer access to create a Blog of their own, where a Customer becomes a "Member" of your ( Main Site ), and also a Blog Owner/Administrator. With s2Member installed ( network wide ), each of your Blog Owners could offer Membership too, using a single installation of the s2Member plugin ( which is a great selling point ). We refer to this as a Multisite Blog Farm.
6
 
7
- You can get started now, by turning on [Multisite Networking](http://codex.wordpress.org/Create_A_Network) inside your installation of WordPress®. Then, install the s2Member plugin ( network wide ). In the Dashboard for your Main Site, see: `s2Member -> Multisite ( Config )`. Before you go live, please contact [s2Member.com](http://www.s2member.com/contact/) for full documentation on Multisite Blog Farms. There is some additional functionality that can be enabled for security on a Blog Farm installation; and also some menus/documentation/functionality that can be disabled. NOTE ~ You will be asked to make a donation, or to purchase a Support Package for s2Member.
1
  = Is s2Member compatible with WordPress® 3.0+ Multisite Networking ? =
2
+ Yes. s2Member and also s2Member Pro, are BOTH compatible with Multisite Networking enabled. After you enable Multisite Networking, install the s2Member plugin. Then navigate to `s2Member -> Multisite ( Config )` in the Dashboard on your ( Main Site ). You can get started now, by turning on [Multisite Networking](http://codex.wordpress.org/Create_A_Network) inside your installation of WordPress®.
3
 
4
  = What about Multisite Networking ( WPMU ), used on a Blog Farm? =
5
+ Yes, preliminary ( experimental ) support for Multisite Blog Farms has also been implemented. If you're running a Multisite Blog Farm ( i.e. you offer Blogs ), please contact s2Member.com for further details. With Multisite Networking enabled, your site could ALSO offer a Customer access to create a Blog of their own, where a Customer becomes a "Member" of your ( Main Site ), and also a Blog Owner/Administrator. With s2Member installed ( Network Wide ), each of your Blog Owners could offer Membership too, using a single installation of the s2Member plugin ( which is a great selling point ). We refer to this as a Multisite Blog Farm.
6
 
7
+ You can get started now, by turning on [Multisite Networking](http://codex.wordpress.org/Create_A_Network) inside your installation of WordPress®. Then, install the s2Member plugin ( Network Wide ). In the Dashboard for your Main Site, see: `s2Member -> Multisite ( Config )`. Before you go live, please contact [s2Member.com](http://www.s2member.com/contact/) for full documentation on Multisite Blog Farms. There is some additional functionality that can be enabled for security on a Blog Farm installation; and also some menus/documentation/functionality that can be disabled. NOTE ~ You will be asked to make a donation, or to purchase a Support Package for s2Member.
readme.txt CHANGED
@@ -1,7 +1,7 @@
1
  === s2Member® ( Membership w/ PayPal® ) ===
2
 
3
- Version: 110812
4
- Stable tag: 110812
5
  Framework: WS-P-110523
6
 
7
  SSL Compatible: yes
@@ -60,7 +60,7 @@ Yes. s2Member, and also s2Member Pro, are BOTH compatible with Multisite Network
60
 
61
  [youtube http://www.youtube.com/watch?v=FyA8Qmm2DHY /]
62
 
63
- s2Member® (Membership w/ PayPal®). Powerful (free) membership capabilities. Protect members only content. The s2Member Framework (free) integrates w/ PayPal® (very easy), and fully supports recurring billing. s2Member supports custom Pages for registration (including Custom Registration Fields), account access, and a lot more. s2Member is now compatible with Multisite Networking too, and even with BuddyPress and bbPress. In addition, with the s2Member Pro Module (an optional paid upgrade), you can add support for unlimited Membership Levels, PayPal® Pro (w/ Pro Forms), Authorize.Net® (w/ Pro Forms), ccBill®, Google® Checkout, ClickBank®, AliPay®, advanced User Import/Export tools, the ability to use Coupon Codesm, and more. Videos available at: [s2Member.com / Videos](http://www.s2member.com/videos/).
64
 
65
  s2Member supports Free Subscribers (at Level #0), and four primary Membership Levels [1-4] (unlimited with s2Member Pro). You can label your Membership Levels anything you like. The defaults are Free, Bronze, Silver, Gold, and Platinum. s2Member also supports an unlimited number of Custom Capability Packages. Custom Capabilities are an easy way to extend s2Member in creative ways. Custom Capabilities allow you to create an unlimited number of Membership Packages, all with different Capabilities and prices.
66
 
@@ -161,8 +161,24 @@ Please visit s2Member.com for [video tutorials](http://www.s2member.com/videos/)
161
 
162
  == Changelog ==
163
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
164
  = v110812 =
165
- * **(s2Member) Security fix.** This release addresses an important security vulnerability in previous releases of the s2Member Framework *( i.e. the free version of s2Member )*. Sites with Download Options configured for s2Member should be advised to update to s2Member v110812+ as soon as possible to avoid possible exploits.
166
 
167
  = v110731 =
168
  * **(s2Member) Bug fix / Multisite.** In the Multisite (Config) panel, s2Member was not properly displaying the number of Blogs allowed at Level #0, in some cases.
@@ -382,62 +398,6 @@ Please visit s2Member.com for [video tutorials](http://www.s2member.com/videos/)
382
  * **(s2Member Pro). Upgrader/bug fix.** The automatic upgrader for the s2Member Pro module was inadvertently deleting itself ( sometimes ) whenever an upgrade failed through WordPress® with script memory/timeout errors. This routine has been modified to better handle it's "point of no return" by unzipping the latest distribution into a separate temporary directory. In addition to this change, the update routine now analyzes your server configuration to ensure enough memory is available before the update routine begins. In the event that your installation lacks the memory required ( at least 256M ) to unzip the s2Member Pro module, a warning to that affect will be displayed and you will need to upload the `/s2member-pro/` directory via FTP instead; following instructions in the `/readme.txt` file.
383
  IMPORTANT: Since previous versions of the automatic updater did NOT include these important enhancements, you may not be able to use the automatic updater in your current version of s2Member Pro. Long story short, we believe the issues HAVE been corrected for "future" releases, but in order to upgrade to this release, you may need to download a copy at s2Member.com and upload it manually via FTP. Full instructions are provided in the `/readme.txt` file, and on the site at s2Member.com.
384
 
385
- = 3.3.2 =
386
- * Tested against WordPress® 3.0.3. Everything looks good.
387
- * (s2Member) Bug fix. s2Member was ignoring `?redirect_to=value` upon login, in favor of the Login Welcome Page configured for s2Member. s2Member v3.3.2 has been updated to allow the use of `redirect_to`; and to simply default to the Login Welcome Page when no `redirect_to` argument is passed in. This is the intended behavior. As of s2Member v3.3.2 this now works fully as expected.
388
- * (s2Member/s2Member Pro) Bug fix. s2Member was incorrectly calculating delayed EOT Times under certain circumstances. This was related to non-recurring Subscriptions processed on PayPal® accounts opened after October 15th, 2009. Under the right scenario, PayPal's IPN responses were fooling s2Member, by immediately expiring payments; and sending a `recurring_payment_expired` IPN before the `recurring_payment` IPN. So s2Member was incorrectly calculating the EOT Time ( i.e. `last_payment_time` was not properly considered ). The logic behind s2Member's IPN handling routines has been corrected in v3.3.2 to resolve this issue.
389
- * (s2Member/s2Member Pro) SEO / Search Engine Optimization. s2Member now sends 301 redirect headers instead of the default WordPress® 302. This prevents duplicate content warnings from search engines such as Google®. In other words, when s2Member redirects visitors ( and/or search engine spiders ) to your Membership Options Page, in response to an attempt to access a secured area of your site; the `wp_redirect()` call will send a 301 redirect header instead of a 302. This prevents duplicate content warnings associated with your Membership Options Page. In addition, a universal Filter ( i.e. `ws_plugin__s2member_content_redirect_status` ) has been added to s2Member's source code, giving developers the ability to modify this behavior dynamically; if they need to.
390
- * (s2Member Pro) Bug fix. s2Member Pro's AliPay® integration was incorrectly handling Return URLs on success. This release fixes the invalid syntax inside `/functions/separates/alipay-return.inc.php`.
391
- * (s2Member Pro) Compatibility. s2Member Pro Forms are now compatible with jQuery v1.4.4. jQuery v1.4.4 introduced the need for double-quotations around all attribute/value selectors.
392
- * (s2Member Pro) New Pro Form attribute. s2Member Pro Forms now accept a new Attribute ( i.e. `template=""` ). This allows developers to integrate Pro Forms with custom template files, on a per-Form basis. For further details on this topic, please check your Dashboard under: `s2Member -> PayPal® Pro Forms -> Shortcode Attributes (explained)`.
393
- * (s2Member) Bug fix. A bug that was first introduced in v3.3 was causing AWeber integrations to fail with email addresses being picked up as the administrative address instead of the Customer's address. This was related to a previous change in v3.3 where all `mail()` commands were converted to `wp_mail()` for improved compatibility. With this release ( s2Member v3.3.2 ), the bug with AWeber integration has been resolved. Thanks to everyone for reporting this important issue.
394
-
395
- = 3.3.1 =
396
- * Tested against WordPress® 3.0.2. Everything looks good.
397
- * Updated Stable Tag to v3.3.1. s2Member is compatible with WordPress® 3.0+ ( including WP 3.0.2 ).
398
-
399
- = 3.3 =
400
- * (s2Member) Bug fix / File Downloads. Use of PHP's `fread()` function has been updated to `stream_get_contents()` with a 2MB chunk size in order to satisfy the needs of site owners delivering VERY large files ( 500MB+ ) though simulated HTTP streams "inline". For instance, an MP4 video file into a FlowPlayer/JWPlayer or another Flash-based application. In addition, s2Member is now capable of output buffering its chunked file delivery, making it possible for s2Member to deliver VERY large files through most shared hosting platforms without needing to upgrade to a private server.
401
- * (s2Member) Bug fix / BuddyPress. Bug fix. New filter added in support of BuddyPress on a Multisite installation. `add_filter ("bp_signup_usermeta", "c_ws_plugin__s2member_registrations::ms_process_signup_meta");`
402
- * (s2Member) Bug fix / BuddyPress. Improved detection of BuddyPress activation/registration slugs using `BP_ACTIVATION_SLUG`, `BP_REGISTER_SLUG` in conjunction with improved routing of `$usermeta` data inside `/s2member/includes/functions/config-user-registration.inc.php`. This resolves an issue where s2Member was not properly applying Membership Levels ( e.g. an s2 Role ) with BuddyPress installed on a Multisite Network.
403
- * (s2Member) Custom Registration Fields. s2Member's API Notifications now support custom Replacement Codes for any Custom Registration Fields that you've configured with s2Member. This makes it easier for developers to integrate 3rd party services, because s2Member's API Notifications can now be configured to send additional information that may include data entered by your Customer into a Custom Registration Field. Also, s2Member still supports the `custom="domain|cv1|cv2|cv3|etc..."` Attribute in your Shortcode too. For full details, check your Dashboard under: `s2Member -> API Notifications`.
404
- * (s2Member) Improved documentation on various Replacement Codes available for s2Member. There are also some new Replacement Codes made available in various sections/integrations.
405
- * (s2Member) In WordPress®, when you list all `Users`, you will find a search box in the upper right-hand corner of the screen. This search box now has the ability to find Members by `Username, Display Name, Nickname, s2Member / Paid Subscr. ID, Custom String, and ANY Custom Registration Field value`.
406
- * (s2Member) Advanced Content Dripping. A new PHP/API Constant has been made available for Content Dripping `S2MEMBER_CURRENT_USER_PAID_REGISTRATION_DAYS` ( note the addition of "PAID" ). Also, s2Member v3.3 includes an entirely new/alternative method for Dripping Content, using a new API Function called `s2member_registration_time ([level])`. You will find all of the information/documentation on this topic inside your Dashboard under: `s2Member -> API Scripting -> Content Dripping`. s2Member now has the ability to provide you with information about when a Member pays you at each specific Membership Level. That being said, there IS an issue with this... The new function `s2member_registration_time ()` will NOT return data correctly for existing Members that paid you prior to you upgrading to s2Member v3.3+. This is because s2Member did NOT record all of this information in previous versions. So it can't give you what it doesn't have on any of your existing Members. Please check the forums for workarounds.
407
- * (s2Member) API Constants. s2Member v3.3 includes some new API Constants related to PayPal® and PayPal® Pro integration. Such as the configured PayPal® API Username, Password, Signature, etc. These will make it easier for other extensions to be built on top of s2Member should the need arise.
408
- * (s2Member/s2Member Pro) Documentation updated throughout. Some minor wording changes were required here-and-there in order to prevent confusion with all of s2Member Pro's new Gateway integrations.
409
- * (s2Member/s2Member Pro) All of s2Member's Button Generators now give you the ability to set a Trial Period and a separate Trial Billing Amount. So instead of just offering a 100% free Trial Period, you can now offer an Initial Period at one price, but have the Subscription billed later at a different Regular Recurring rate.
410
- * (s2Member Pro) New configuration panel added to s2Member Pro. The new `Other Gateways` panel allows you to enable/disable other Payment Gateways that have been integrated with s2Member Pro.
411
- * (s2Member Pro) Google® Checkout. s2Member Pro has been integrated with Google® for Direct Payments and also for Recurring Billing. In order to take advantage of this new integration method, you will need to have a copy of s2Member Pro, and a Google® Checkout Account. A Google® Checkout account is free.
412
- * (s2Member Pro) ClickBank®. s2Member Pro has now been integrated with ClickBank® for Direct Payments and also for Recurring Billing. In order to take advantage of this new integration method, you will need to have a copy of s2Member Pro, and a ClickBank® Merchant Account. Otherwise, you can just use the PayPal® Standard integration that comes with the free version of s2Member.
413
- * (s2Member Pro) AliPay®. s2Member Pro has been integrated with AliPay® for Direct Payments. In order to take advantage of this new integration method, you will need to have an AliPay® Merchant Account with Direct Pay enabled ( aka: 前台自助--即时到账收款 ). This can sometimes take a couple of days to acquire. Once you've been approved at AliPay®, you'll be given a Partner ID, and a Security Code; which you'll need to configure inside your `s2Member -> AliPay® Options`.
414
- * (s2Member Pro) PayPal® Pro integration with s2Member Pro, now supports Coupon Codes that can be configured to ONLY apply to (ta) Trial Amounts, or (ra) Regular Amounts. For further details and examples, please check your Dashboard under: `s2Member -> Coupon Codes`.
415
- * (s2Member Pro) PayPal® Pro Forms with s2Member Pro, can now be configured to recur at these new intervals: Bi-Weekly, Bi-Monthly, and Quarterly recurring cycles.
416
- * (s2Member Pro) Documentation. New documentation on ALL of s2Member's Shortcode Attributes for Pro Forms, Standard Shortcodes, and other Payment Gateways; is now included inside your Dashboard. For each Payment Gateway that you enable, there will be a Button Generator available in the s2Member Menu panel. At the bottom of each Button Generating station, you'll find a detailed examination of s2Member's Shortcode Attributes. This should make s2Member even easier for developers to integrate.
417
-
418
- = 3.2.9 =
419
- * Compatibility. s2Member's Custom Field interface was being negatively impacted by the Prototype library for JavaScript; which is utilized by some other popular plugins, such as WP-O-Matic. As a result, on some installations of s2Member ( depending on your plugin combination ), a few site owners were seeing a jumbled mix of fields in their General Options panel for s2Member. This conflict with the Prototype library has been resolved in s2Member v3.2.9+.
420
-
421
- If ( and ONLY if ) you were experiencing this issue in previous versions of s2Member, it is recommended that you delete all of your existing Custom Fields for s2Member and re-create them. If you don't delete all of your corrupted Custom Fields and start over, the issue may *appear* to still exist; but it HAS been corrected.
422
-
423
- = 3.2.8 =
424
- * Unique IP Restrictions. There is a new option under: `s2Member -> General Options -> IP Restrictions` which allows a site owner to effectively disable IP Restrictions if they'd prefer. On some hosting platforms, the `$_SERVER["REMOTE_ADDR"]` variable ( i.e. a Users IP address ) is incorrectly set to the exact same thing for all visitors; which WILL prevent s2Member's IP Restrictions from working as intended. If you're on a hosting platform that has this bug, you may wish to disable IP Restrictions completely using s2Member v3.2.8+. Otherwise, under most circumstances we recommend that you leave IP Restrictions on.
425
-
426
- = 3.2.7 =
427
- * Custom Fields ( new features ). s2Member is now equipped with a VERY powerful set of features; designed to extend the functionality of Custom Fields. s2Member now supports Text Fields ( single/multi-line ), Checkboxes ( single/multi-option ), Radio Buttons ( single/multi-option ), and Dropdowns ( single/multi-option ). In addition, with s2Member it is now possible to configure Custom Fields differently for each Membership Level. Other tools: including Validation Formats and Visibility are also available. For full details, check your Dashboard under: `s2Member -> General Options -> Custom Fields`.
428
- * Attn Developers ( before upgrading ). Hooks/Filters ( e.g. those related to Custom Fields ) have been modified in ways that may break custom scripts you've created to work with previous versions of s2Member. We suggest dropping all of your Hooks/Filters related to Custom Fields. Instead, use the NEW improved tools w/s2Member v3.2.7+. Please see: `s2Member -> General Options -> Custom Fields`.
429
- * BuddyPress/Multisite. A plugin conflict was resolved between BuddyPress/s2Member when both of these plugins were installed on a Multisite Network together. BuddyPress bypasses the default Filter ( `pre_site_option_registration` ) and instead, it uses: `bp_core_get_site_options()`. This has been resolved in s2Member v3.2.6+.
430
- * Bug fix. A bug was found in s2Member's handling of Custom Fields columns. This minor bug was conflicting with other plugins that attempt to create User-based columns. This was been resolved in s2Member v3.2.7+.
431
- * New Shortcode attribute. s2Member's PayPal Button Shortcode now accepts a new attribute ( `ta="0.00"`, Trial Amount ). In the past, if you intended to offer a "paid" Initial Period at a different price, you had to use the Full Button Code. Now you can just change the `ta="0.00"` attribute ( which is easier ).
432
- * More informative. s2Member now generates warnings for newbies that create conflicts between their Membership Options Page and Login Welcome Page. s2Member is now capable of detecting the most common conflicts, in order to produce informative messages that assist site owners.
433
- * Login/Registration Design. s2Member v3.2.7+ includes additional customization tools that allow font sizes and font families to be configured for the Login/Registration system. In your Dashboard, go to: `s2Member -> General Options -> Login/Registration Design`.
434
- * Bug fix. The Default Profile Editing Panel ( e.g. `/wp-admin/profile.php` ) was NOT validating Custom Fields. s2Member v3.2.7 resolves this for Users/Members. Administrators are exempt ( the intended functionality ).
435
- * Better instructions inside in the General Options panel for s2Member. Just a few subtle improvements based on User feedback. Hopefully these will make life a little easier for newbies.
436
-
437
- = 3.2.5 =
438
- * IP Restrictions ( reset ). Several site owners have reported issues with s2Member's IP Restrictions. A full investigation has been performed. Although no bugs were found, we suspect that recent reports on this topic are related to a combination of a.) improvements in recent versions of s2Member, with respect to IP Restrictions ( adaptive concurrency limits ); and b.) lack of support ( on the part of s2Member ) for resetting IP Restriction Logs after changes in configuration. In this release of s2Member, we've introduced a new tool for site owners, which allows you to Reset IP Restriction Logs manually, at anytime you like. For further details, please see: `s2Member -> General Options -> IP Restrictions` ( look for the new button titled: `Reset IP Restriction Logs`. ).
439
- * Compatibility. s2Member's activation/deactivation routines have been updated to support installations of WordPress® that may, or may not, already have the default WordPress® Roles installed. For instance, some installations of WordPress® are running with Role managing plugins. A site owner could have modified WordPress®, and may no longer have one, or even all of these default Roles: `administrator, editor, author, contributor, subscriber`. s2Member is now capable of dealing with this scenario gracefully upon activation/deactivation.
440
-
441
- = v3.2.4 - 1.0 =
442
- * ... trimmed away at v3.2.4.
443
  * Initial release, v1.0.
1
  === s2Member® ( Membership w/ PayPal® ) ===
2
 
3
+ Version: 110815
4
+ Stable tag: 110815
5
  Framework: WS-P-110523
6
 
7
  SSL Compatible: yes
60
 
61
  [youtube http://www.youtube.com/watch?v=FyA8Qmm2DHY /]
62
 
63
+ s2Member® (Membership w/ PayPal®). Powerful (free) membership capabilities. Protect members only content. The s2Member Framework (free) integrates w/ PayPal® (very easy), and fully supports recurring billing. s2Member supports custom Pages for registration (including Custom Registration Fields), account access, and a lot more. s2Member is now compatible with Multisite Networking too, and even with BuddyPress and bbPress. In addition, with the s2Member Pro Module (an optional paid upgrade), you can add support for unlimited Membership Levels, PayPal® Pro (w/ Pro Forms), Authorize.Net® (w/ Pro Forms), ccBill®, Google® Checkout, ClickBank®, AliPay®, advanced User Import/Export tools, the ability to use Coupon Codes, and more. Videos available at: [s2Member.com / Videos](http://www.s2member.com/videos/).
64
 
65
  s2Member supports Free Subscribers (at Level #0), and four primary Membership Levels [1-4] (unlimited with s2Member Pro). You can label your Membership Levels anything you like. The defaults are Free, Bronze, Silver, Gold, and Platinum. s2Member also supports an unlimited number of Custom Capability Packages. Custom Capabilities are an easy way to extend s2Member in creative ways. Custom Capabilities allow you to create an unlimited number of Membership Packages, all with different Capabilities and prices.
66
 
161
 
162
  == Changelog ==
163
 
164
+ = v110815 =
165
+ * (s2Member/s2Member Pro) **Independent Custom Capabilities.** You can now sell one or more Custom Capabilities using Buy Now functionality, to "existing" Users/Members, regardless of which Membership Level they have on your site *( i.e. you could even sell Independent Custom Capabilities to Users at Membership Level #0, normally referred to as Free Subscribers, if you like )*. So this is quite flexible. Independent Custom Capabilities do NOT rely on any specific Membership Level. That's why s2Member refers to these as *Independent* Custom Capabilities, because you can sell Capabilities this way, through Buy Now functionality, and the Customer's Membership Level Access, along with any existing paid Subscription they may already have with you, will remain completely unaffected. For further details, please check your Dashboard, under: `s2Member -> PayPal® Buttons -> Capability (Buy Now) Buttons`. Independent Custom Capabilities are currently integrated with PayPal® Standard Buttons, PayPal® Pro Forms, and Authorize.Net® Pro Forms only. Integration with other Payment Gateways supported by s2Member Pro will come in a future release.
166
+ * (s2Member) **API Tracking.** This release of s2Member introduces two new API Tracking methods, now making it possible to incorporate Tracking Codes *( i.e. affiliate program integrations, as one example )* for `Signup Tracking`, `Modification Tracking (new)`, and also for `Capability Tracking (new)`. For further details, please check your Dashboard, under: `s2Member -> API Tracking`. These new methods are ( in addition to ) s2Member's API Notifications, which remain available. s2Member's API Notifications are intended for more advanced tracking integrations, such as a 3rd-party call through an HTTP request.
167
+ * (s2Member) **Bug fix / Multisite.** s2Member's supplemental API Functions `current_user_is()`, `current_user_is_not()` and the `..for_blog()` alternatives, were not properly considering Super Administators on a Multisite Network installation. On a Multisite Network, the WordPress `$user->has_cap()` routine returns true for anything passed in on a Super Administrator account, causing s2Member's `user_is` API Functions to return true for Super Administrators in some cases, when it really should NOT have been. Fixed in this release. If you need to use `current_user_is()` against a Super Administrator, the `user_is` API Functions introduced by s2Member will only return true in these special cases: `current_user_is("super_administrator")` and/or `current_user_is("administrator")`. Super Administrators should always have the `administrator` Role, for all Blogs in the Network, and s2Member will also consider the fake Role `super_administrator` *( unique to s2Member )* for cases when you need to test explicity for a Super Administrator. Actually, you could also just use the WordPress core function for this: `is_super_admin()` *( recommended )*.
168
+ * (s2Member) **Bug fix / Capabilities.** When/if you require Custom Capabilities in order to view certain content sections on your site, s2Member was behaving properly in all cases, except for one specific scenario. When an Administrator of the site *( on a normal single-site installation of WordPress )*, was attempting to test-view content protected with Custom Capabilities *( this scenario was causing a problem )*. What was happening, is that s2Member was seeing that an Adminstrator did not have certain Custom Capabilities defined explicity in their account, and access was being denied *( that's actually, NOT right )*. This was in conflict with the way that s2Member handles all other content protection routines with respect to Administrators. Administrators should automatically have access to all protected content, even if Custom Capabilities are not explicity defined in their account. After all, they are Administrators. In short, this release makes it possible for Administrators of a single-site WordPress installation, to have full access to all content; even when/if Custom Capabilities are required. This should help to prevent confusion for site owners just beginning to understand s2Member's functionality with respect to Custom Capabilities.
169
+ * (s2Member Pro) **Bug fix / Coupon Codes.** s2Member Pro Forms were failing to apply Coupon Codes properly in some cases. Whenever a Coupon Code eliminated all initial charges for a Trial Amount, s2Member was attempting to charge a zero dollar sale amount, under the right scenario. Fixed in this release.
170
+ * (s2Member) **API Notifications.** Starting with this release, s2Member's Payment Notifications are also triggered whenever a Buy Now purchase for Independent Custom Capabilities takes place (new). The documentation in your Dashboard has been updated. For further details, please see: `s2Member -> API Notifications -> Payment Notifications`.
171
+ * (s2Member/s2Member Pro) **Cookies.** Both s2Member and s2Member Pro now fully support the `COOKIEPATH`, `SITECOOKIEPATH`, and `COOKIE_DOMAIN` constants from the WordPress® core, making s2Member more secure on Multisite Networks, and improving compatibility overall for sites that use one or more of these PHP Constants in their `/wp-config.php` file.
172
+ * (s2Member Pro) **UI Improvement / tabindex.** s2Member Pro Forms have been updated to skip tab indexes on reCAPTCHA box controllers *( e.g. the three mundane buttons )* that are skipped over 99.9% of the time anyway. This allows Pro Form tab controls to jump immediately to the reCAPTCHA input field, if/when enabled by your Shortcode.
173
+ * (s2Member Pro) **UI Improvement.** s2Member\'s live feed inside your Dashboard, which is responsible for delivering updates that come from Lead Developer Jason Caldwell and s2Member Support Reps, has been improved in this release. You'll see this on the right-hand side of s2Member's UI panels, near the top.
174
+ * (s2Member/s2Member Pro) **Capability Additions (Changed).** In previous versions of s2Member, when generating a Payment Button/Form, it was possible to precede your list of Custom Capabilities with a `+` sign, indicating that you wish to (Add) new Custom Capabilities instead of (Resetting) a User's Capbilities to the ones you list. Starting with this release, (Add) is now the default behavior. In other words, the `+` sign is no longer required, because s2Member will automatically (Add) Capabilities to any that already exist for a particular User/Member, even without the `+` sign *(no longer required)*. In addition, there is now a new directive available: `-all`. You may now precede your list of Custom Capabilities with `-all`, but only if you wish to (Remove/Reset) all Custom Capabilities, and then (Add) new ones. For example: `-all,music,videos`, would remove any existing Custom Capabilities that may or may not already exist for a particular User/Member, and then add: `music,videos`. There are additional examples provided by the Payment Button/Form Generators that come with s2Member. Please check your Dashboard if you'd like to learn more.
175
+ * (s2Member) **Compatibility.** s2Member's ability to modify the WordPress® Admin Bar for Users/Members has been updated to fully support WordPress® v3.2+. This feature now behaves as expected in the latest release. For further details, please check your Dashboard, under: `s2Member -> General Options -> Profile Modifications`. The Redirection option in that section, has the side effect of manipulating the Admin Bar across the top of your site *( if enabled )*, making WordPress® behave properly.
176
+ * (s2Member Pro) **Options Import/Export.** s2Member Pro now makes it possible to export your s2Member options, in their entirety, and then import them into another instance of WordPress®. For further details, please check your Dashboard, under: `s2Member -> Import/Export`.
177
+ * (s2Member/s2Member Pro) **Memory.** Memory reporting is now added to log entries by s2Member.
178
+ * (s2Member/s2Member Pro) **JavaScript.** Minor optimization of s2Member's JavaScript routine.
179
+
180
  = v110812 =
181
+ * (s2Member) **Security fix.** This release addresses an important security vulnerability in previous releases of the s2Member Framework *( i.e. the free version of s2Member )*. Sites with Download Options configured for s2Member should be advised to update to s2Member v110812+ as soon as possible to avoid possible exploits.
182
 
183
  = v110731 =
184
  * **(s2Member) Bug fix / Multisite.** In the Multisite (Config) panel, s2Member was not properly displaying the number of Blogs allowed at Level #0, in some cases.
398
  * **(s2Member Pro). Upgrader/bug fix.** The automatic upgrader for the s2Member Pro module was inadvertently deleting itself ( sometimes ) whenever an upgrade failed through WordPress® with script memory/timeout errors. This routine has been modified to better handle it's "point of no return" by unzipping the latest distribution into a separate temporary directory. In addition to this change, the update routine now analyzes your server configuration to ensure enough memory is available before the update routine begins. In the event that your installation lacks the memory required ( at least 256M ) to unzip the s2Member Pro module, a warning to that affect will be displayed and you will need to upload the `/s2member-pro/` directory via FTP instead; following instructions in the `/readme.txt` file.
399
  IMPORTANT: Since previous versions of the automatic updater did NOT include these important enhancements, you may not be able to use the automatic updater in your current version of s2Member Pro. Long story short, we believe the issues HAVE been corrected for "future" releases, but in order to upgrade to this release, you may need to download a copy at s2Member.com and upload it manually via FTP. Full instructions are provided in the `/readme.txt` file, and on the site at s2Member.com.
400
 
401
+ = v3.3.2 - 1.0 =
402
+ * ... trimmed away at v3.3.2.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
403
  * Initial release, v1.0.
s2member.php CHANGED
@@ -19,8 +19,8 @@
19
  */
20
  /* -- This section for WordPress® parsing. ------------------------------------------------------------------------------
21
 
22
- Version: 110812
23
- Stable tag: 110812
24
  Framework: WS-P-110523
25
 
26
  SSL Compatible: yes
@@ -62,7 +62,7 @@ Tags: membership, members, member, register, signup, paypal, paypal pro, pay pal
62
 
63
  -- end section for WordPress® parsing. ------------------------------------------------------------------------------- */
64
  if (realpath (__FILE__) === realpath ($_SERVER["SCRIPT_FILENAME"]))
65
- exit("Do not access this file directly.");
66
  /**
67
  * The installed version of s2Member.
68
  *
@@ -72,7 +72,7 @@ if (realpath (__FILE__) === realpath ($_SERVER["SCRIPT_FILENAME"]))
72
  * @var str
73
  */
74
  if (!defined ("WS_PLUGIN__S2MEMBER_VERSION"))
75
- define ("WS_PLUGIN__S2MEMBER_VERSION", "110812");
76
  /**
77
  * Minimum PHP version required to run s2Member.
78
  *
@@ -102,7 +102,7 @@ if (!defined ("WS_PLUGIN__S2MEMBER_MIN_WP_VERSION"))
102
  * @var str
103
  */
104
  if (!defined ("WS_PLUGIN__S2MEMBER_MIN_PRO_VERSION"))
105
- define ("WS_PLUGIN__S2MEMBER_MIN_PRO_VERSION", "110731");
106
  /*
107
  Several compatibility checks.
108
  If all pass, load the s2Member plugin.
@@ -113,7 +113,7 @@ if (version_compare (PHP_VERSION, WS_PLUGIN__S2MEMBER_MIN_PHP_VERSION, ">=") &&
113
  /*
114
  Hook before loaded.
115
  */
116
- do_action("ws_plugin__s2member_before_loaded");
117
  /*
118
  System configuraton.
119
  */
@@ -125,7 +125,7 @@ if (version_compare (PHP_VERSION, WS_PLUGIN__S2MEMBER_MIN_PHP_VERSION, ">=") &&
125
  /*
126
  Hook after system config & Hooks are loaded.
127
  */
128
- do_action("ws_plugin__s2member_config_hooks_loaded");
129
  /*
130
  Load a possible Pro module, if/when available.
131
  */
@@ -146,7 +146,7 @@ if (version_compare (PHP_VERSION, WS_PLUGIN__S2MEMBER_MIN_PHP_VERSION, ">=") &&
146
  /*
147
  Hook after loaded.
148
  */
149
- do_action("ws_plugin__s2member_after_loaded");
150
  }
151
  /*
152
  Else NOT compatible. Do we need admin compatibility errors now?
19
  */
20
  /* -- This section for WordPress® parsing. ------------------------------------------------------------------------------
21
 
22
+ Version: 110815
23
+ Stable tag: 110815
24
  Framework: WS-P-110523
25
 
26
  SSL Compatible: yes
62
 
63
  -- end section for WordPress® parsing. ------------------------------------------------------------------------------- */
64
  if (realpath (__FILE__) === realpath ($_SERVER["SCRIPT_FILENAME"]))
65
+ exit ("Do not access this file directly.");
66
  /**
67
  * The installed version of s2Member.
68
  *
72
  * @var str
73
  */
74
  if (!defined ("WS_PLUGIN__S2MEMBER_VERSION"))
75
+ define ("WS_PLUGIN__S2MEMBER_VERSION", "110815");
76
  /**
77
  * Minimum PHP version required to run s2Member.
78
  *
102
  * @var str
103
  */
104
  if (!defined ("WS_PLUGIN__S2MEMBER_MIN_PRO_VERSION"))
105
+ define ("WS_PLUGIN__S2MEMBER_MIN_PRO_VERSION", "110815");
106
  /*
107
  Several compatibility checks.
108
  If all pass, load the s2Member plugin.
113
  /*
114
  Hook before loaded.
115
  */
116
+ do_action ("ws_plugin__s2member_before_loaded");
117
  /*
118
  System configuraton.
119
  */
125
  /*
126
  Hook after system config & Hooks are loaded.
127
  */
128
+ do_action ("ws_plugin__s2member_config_hooks_loaded");
129
  /*
130
  Load a possible Pro module, if/when available.
131
  */
146
  /*
147
  Hook after loaded.
148
  */
149
+ do_action ("ws_plugin__s2member_after_loaded");
150
  }
151
  /*
152
  Else NOT compatible. Do we need admin compatibility errors now?