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

Version Description

  • (s2Member). Feature improvement. s2Member's Bridge integration with bbPress. It is now possible to allow bbPress forums to be available to the public ( with read-only access ), and to restrict participation access by Level # instead of locking everything down entirely. You now have the choice whenever you install and/or re-install the bbPress Bridge/plugin for s2Member. In addition, s2Member makes a new API function available for bbPress current_wp_user_is(). This will be useful to developers integrating bbPress with s2Member in creative ways. For further details, please check your Dashboard under: s2Member -> API Bridges -> bbPress.
  • (s2Member Pro). Feature improvement. s2Member Pro Forms for Free Registration access are now more versatile. It is now possible to configure your Pro Form Shortcode so that Free Registrants come into your site with something other than the default Level #0 Access Level. For example, if you need to, you can change the Form Attribute level="0", to level="1", attach Custom Capabilities with the ccaps="" Attribute, and even limit this access to a certain timeframe with tp="30" tt="D" ( i.e. 30 Days ). So this Form is very flexible now. It can be used to allow free access to just about any aspect of your service. For more information on this topic, please check your Dashboard under: s2Member -> PayPal Pro Forms -> Free Registration Forms. Also works with Pro Forms for Authorize.Net.
  • (s2Member). New Filters. s2Member v3.5.3 adds two new WordPress Filters that allow developers to further customize the inner workings of s2Member ( among 300+ other existing Filters already established for s2Member ). You will find these two new Filters in the source code of the free version: wp_register_location and ws_plugin__s2member_redirection_url_after_modification. For Multisite Networks, there is also this Filter available: wp_signup_location. If you're a novice site owner, please keep tabs on our forums for examples on how to utilize these new Filters. We're sure this topic will come up.
  • (s2Member). New Filters. s2Member v3.5.3 adds two new WordPress Filters that allow developers to further customize tinyURLs generated for email confirmations. You will find these two new Filters in the source code of the free version: ws_plugin__s2member_register_link_gen_alternative and ws_plugin__s2member_sp_access_link_gen_alternative. I've posted an example of how to use these in the forums. So these new Filters make it possible to use a shortening service that you prefer over tinyURL ( but you will have to integrate it yourself ). In a later release, we'll try to add some pre-integrated alternatives into the Dashboard for s2Member.
  • (s2Member). New Replacement Code. s2Member's EOT/Deletion Notification now provides additional detail about the actual event that triggers this API Notification through a new Replacement Code: %%eot_del_type%%. For further details on this new Replacement Code, and a list of possible values, please check your Dashboard under: s2Member -> API Notifications -> EOT/Deletion Notifications.
  • (s2Member). Bug fix. A common error that site owners see in s2Member's log file is unable to verify POST vars. This is due to issues with various hosting companies not being configured with either cURL and/or allow_url_fopen -> on. However, we recently discovered that WordPress ( i.e. via the WP_Http class ) will attempt to officially verify the SSL certificate issued through remote connections to Payment Gateways integrated with s2Member. This can cause an additional roadblock on some servers, because often they are not capable of officially verifying SSL certificates. They lack the extended configuration necessary to do so. In other words, this default behavior in the WP_Http class file can ultimately lead to unable to verify POST vars in s2Member. To workaround this compatibility issue, s2Member now specifies `sslverify
Download this release

Release Info

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

Code changes from version 3.5.2 to 3.5.3

Files changed (39) hide show
  1. includes/classes/auto-eots.inc.php +9 -5
  2. includes/classes/cache.inc.php +92 -0
  3. includes/classes/check-activation.inc.php +1 -1
  4. includes/classes/constants.inc.php +36 -97
  5. includes/classes/css-js-in.inc.php +1 -1
  6. includes/classes/files-in.inc.php +6 -6
  7. includes/classes/installation.inc.php +6 -6
  8. includes/classes/list-servers.inc.php +20 -19
  9. includes/classes/login-redirects.inc.php +4 -4
  10. includes/classes/menu-pages.inc.php +22 -21
  11. includes/classes/op-notices.inc.php +1 -1
  12. includes/classes/option-forces.inc.php +9 -6
  13. includes/classes/paypal-notify-in.inc.php +18 -8
  14. includes/classes/paypal-return-in.inc.php +44 -20
  15. includes/classes/register-access.inc.php +5 -1
  16. includes/classes/registrations.inc.php +135 -116
  17. includes/classes/sp-access.inc.php +4 -1
  18. includes/classes/ssl-in.inc.php +70 -24
  19. includes/classes/ssl.inc.php +1 -1
  20. includes/classes/user-deletions.inc.php +7 -3
  21. includes/classes/user-securities.inc.php +19 -23
  22. includes/classes/users-list-in.inc.php +2 -2
  23. includes/classes/users-list.inc.php +2 -1
  24. includes/classes/utils-arrays.inc.php +30 -5
  25. includes/classes/utils-dirs.inc.php +2 -2
  26. includes/classes/utils-urls.inc.php +15 -15
  27. includes/dropins/bridges/_s2member-bbpress-bridge.php +147 -63
  28. includes/hooks.inc.php +3 -3
  29. includes/menu-pages/api-ops.inc.php +3 -0
  30. includes/menu-pages/bridges.inc.php +50 -15
  31. includes/menu-pages/els-ops.inc.php +2 -2
  32. includes/menu-pages/menu-pages-s-min.js +1 -1
  33. includes/menu-pages/menu-pages-s.js +30 -0
  34. includes/menu-pages/paypal-ops.inc.php +2 -2
  35. includes/s2member-min.js +1 -1
  36. includes/s2member.js +19 -19
  37. includes/syscon.inc.php +6 -4
  38. readme.txt +26 -8
  39. s2member.php +4 -4
includes/classes/auto-eots.inc.php CHANGED
@@ -80,7 +80,7 @@ if (!class_exists ("c_ws_plugin__s2member_auto_eots"))
80
  /**/
81
  include_once ABSPATH . "wp-admin/includes/admin.php";
82
  /**/
83
- set_time_limit (0); /* Make time for processing larger userbases. */
84
  @ini_set ("memory_limit", "256M"); /* Acquire some additional RAM. */
85
  /**/
86
  eval ('foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;');
@@ -109,7 +109,7 @@ if (!class_exists ("c_ws_plugin__s2member_auto_eots"))
109
  /**/
110
  eval ('foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;');
111
  do_action ("ws_plugin__s2member_during_auto_eot_system_during_before_demote", get_defined_vars ());
112
- do_action ("ws_plugin__s2member_during_collective_eots", $user_id, get_defined_vars (), "auto-eot-cancellation-expiration-demotion");
113
  unset ($__refs, $__v); /* Unset defined __refs, __v. */
114
  /**/
115
  $demotion_role = c_ws_plugin__s2member_option_forces::force_demotion_role ("subscriber");
@@ -144,7 +144,7 @@ if (!class_exists ("c_ws_plugin__s2member_auto_eots"))
144
  {
145
  foreach (preg_split ("/[\r\n\t]+/", $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["eot_del_notification_urls"]) as $url) /* Handle EOT Notifications. */
146
  /**/
147
- 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 ($subscr_id)), $url)))
148
  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)))
149
  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)))
150
  if (($url = preg_replace ("/%%user_email%%/i", c_ws_plugin__s2member_utils_strings::esc_ds (urlencode ($user->user_email)), $url)))
@@ -168,6 +168,7 @@ if (!class_exists ("c_ws_plugin__s2member_auto_eots"))
168
  $msg = $sbj = "( s2Member / API Notification Email ) - EOT/Deletion";
169
  $msg .= "\n\n"; /* Spacing in the message body. */
170
  /**/
 
171
  $msg .= "subscr_id: %%subscr_id%%\n";
172
  $msg .= "user_first_name: %%user_first_name%%\n";
173
  $msg .= "user_last_name: %%user_last_name%%\n";
@@ -191,7 +192,7 @@ if (!class_exists ("c_ws_plugin__s2member_auto_eots"))
191
  $msg .= "cv8: %%cv8%%\n";
192
  $msg .= "cv9: %%cv9%%";
193
  /**/
194
- 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 ($subscr_id), $msg)))
195
  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)))
196
  if (($msg = preg_replace ("/%%user_full_name%%/i", c_ws_plugin__s2member_utils_strings::esc_ds (trim ($user->first_name . " " . $user->last_name)), $msg)))
197
  if (($msg = preg_replace ("/%%user_email%%/i", c_ws_plugin__s2member_utils_strings::esc_ds ($user->user_email), $msg)))
@@ -217,9 +218,12 @@ if (!class_exists ("c_ws_plugin__s2member_auto_eots"))
217
  {
218
  eval ('foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;');
219
  do_action ("ws_plugin__s2member_during_auto_eot_system_during_before_delete", get_defined_vars ());
220
- do_action ("ws_plugin__s2member_during_collective_eots", $user_id, get_defined_vars (), "auto-eot-cancellation-expiration-deletion");
221
  unset ($__refs, $__v); /* Unset defined __refs, __v. */
222
  /**/
 
 
 
223
  if (is_multisite ()) /* Multisite does NOT actually delete; ONLY removes. */
224
  {
225
  remove_user_from_blog ($user_id, $current_blog->blog_id);
80
  /**/
81
  include_once ABSPATH . "wp-admin/includes/admin.php";
82
  /**/
83
+ @set_time_limit (0); /* Make time for processing larger userbases. */
84
  @ini_set ("memory_limit", "256M"); /* Acquire some additional RAM. */
85
  /**/
86
  eval ('foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;');
109
  /**/
110
  eval ('foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;');
111
  do_action ("ws_plugin__s2member_during_auto_eot_system_during_before_demote", get_defined_vars ());
112
+ do_action ("ws_plugin__s2member_during_collective_eots", $user_id, get_defined_vars (), "auto-eot-cancellation-expiration-demotion", "cancellation-expiration");
113
  unset ($__refs, $__v); /* Unset defined __refs, __v. */
114
  /**/
115
  $demotion_role = c_ws_plugin__s2member_option_forces::force_demotion_role ("subscriber");
144
  {
145
  foreach (preg_split ("/[\r\n\t]+/", $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["eot_del_notification_urls"]) as $url) /* Handle EOT Notifications. */
146
  /**/
147
+ if (($url = preg_replace ("/%%cv([0-9]+)%%/ei", 'urlencode(trim($cv[$1]))', $url)) && ($url = preg_replace ("/%%eot_del_type%%/i", c_ws_plugin__s2member_utils_strings::esc_ds (urlencode ("auto-eot-cancellation-expiration-demotion")), $url)) && ($url = preg_replace ("/%%subscr_id%%/i", c_ws_plugin__s2member_utils_strings::esc_ds (urlencode ($subscr_id)), $url)))
148
  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)))
149
  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)))
150
  if (($url = preg_replace ("/%%user_email%%/i", c_ws_plugin__s2member_utils_strings::esc_ds (urlencode ($user->user_email)), $url)))
168
  $msg = $sbj = "( s2Member / API Notification Email ) - EOT/Deletion";
169
  $msg .= "\n\n"; /* Spacing in the message body. */
170
  /**/
171
+ $msg .= "eot_del_type: %%eot_del_type%%\n";
172
  $msg .= "subscr_id: %%subscr_id%%\n";
173
  $msg .= "user_first_name: %%user_first_name%%\n";
174
  $msg .= "user_last_name: %%user_last_name%%\n";
192
  $msg .= "cv8: %%cv8%%\n";
193
  $msg .= "cv9: %%cv9%%";
194
  /**/
195
+ if (($msg = preg_replace ("/%%cv([0-9]+)%%/ei", 'trim($cv[$1])', $msg)) && ($msg = preg_replace ("/%%eot_del_type%%/i", c_ws_plugin__s2member_utils_strings::esc_ds ("auto-eot-cancellation-expiration-demotion"), $msg)) && ($msg = preg_replace ("/%%subscr_id%%/i", c_ws_plugin__s2member_utils_strings::esc_ds ($subscr_id), $msg)))
196
  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)))
197
  if (($msg = preg_replace ("/%%user_full_name%%/i", c_ws_plugin__s2member_utils_strings::esc_ds (trim ($user->first_name . " " . $user->last_name)), $msg)))
198
  if (($msg = preg_replace ("/%%user_email%%/i", c_ws_plugin__s2member_utils_strings::esc_ds ($user->user_email), $msg)))
218
  {
219
  eval ('foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;');
220
  do_action ("ws_plugin__s2member_during_auto_eot_system_during_before_delete", get_defined_vars ());
221
+ do_action ("ws_plugin__s2member_during_collective_eots", $user_id, get_defined_vars (), "auto-eot-cancellation-expiration-deletion", "cancellation-expiration");
222
  unset ($__refs, $__v); /* Unset defined __refs, __v. */
223
  /**/
224
+ $GLOBALS["ws_plugin__s2member_eot_del_type"] = "auto-eot-cancellation-expiration-deletion";
225
+ $GLOBALS["ws_plugin__s2member_eot_del_type_spec"] = "cancellation-expiration";
226
+ /**/
227
  if (is_multisite ()) /* Multisite does NOT actually delete; ONLY removes. */
228
  {
229
  remove_user_from_blog ($user_id, $current_blog->blog_id);
includes/classes/cache.inc.php ADDED
@@ -0,0 +1,92 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /*
3
+ Copyright: © 2009 WebSharks, Inc. ( coded in the USA )
4
+ <mailto:support@websharks-inc.com> <http://www.websharks-inc.com/>
5
+
6
+ Released under the terms of the GNU General Public License.
7
+ You should have received a copy of the GNU General Public License,
8
+ along with this software. In the main directory, see: /licensing/
9
+ If not, see: <http://www.gnu.org/licenses/>.
10
+ */
11
+ /*
12
+ Direct access denial.
13
+ */
14
+ if (realpath (__FILE__) === realpath ($_SERVER["SCRIPT_FILENAME"]))
15
+ exit ("Do not access this file directly.");
16
+ /**/
17
+ if (!class_exists ("c_ws_plugin__s2member_cache"))
18
+ {
19
+ class c_ws_plugin__s2member_cache
20
+ {
21
+ /*
22
+ Pulls all of the Page links needed for Constants.
23
+ Page links are cached into the s2Member options on 15 min intervals.
24
+ This allows the API Constants to provide quick access to them without being forced to execute get_page_link() all the time, which piles up DB queries.
25
+ */
26
+ public static function cached_page_links ()
27
+ {
28
+ do_action ("ws_plugin__s2member_before_cached_page_links", get_defined_vars ());
29
+ /**/
30
+ $login_welcome_page = $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["login_welcome_page"];
31
+ $membership_options_page = $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["membership_options_page"];
32
+ $file_download_limit_exceeded_page = $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["file_download_limit_exceeded_page"];
33
+ /**/
34
+ $login_welcome_page_cache = $GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["cache"]["login_welcome_page"];
35
+ $membership_options_page_cache = $GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["cache"]["membership_options_page"];
36
+ $file_download_limit_exceeded_page_cache = $GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["cache"]["file_download_limit_exceeded_page"];
37
+ /**/
38
+ $links = array ("login_welcome_page" => "", "membership_options_page" => "", "file_download_limit_exceeded_page" => "");
39
+ /**/
40
+ if ($login_welcome_page_cache["page"] === $login_welcome_page && $login_welcome_page_cache["time"] >= strtotime ("-15 minutes"))
41
+ {
42
+ $links["login_welcome_page"] = $login_welcome_page_cache["link"];
43
+ }
44
+ else /* Otherwise, we need to query the database using get_page_link() and update the cache. */
45
+ {
46
+ $GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["cache"]["login_welcome_page"]["time"] = time ();
47
+ $GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["cache"]["login_welcome_page"]["page"] = $login_welcome_page;
48
+ $links["login_welcome_page"] = $GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["cache"]["login_welcome_page"]["link"] = get_page_link ($login_welcome_page);
49
+ /**/
50
+ $cache_needs_updating = true; /* Flag for cache update. */
51
+ }
52
+ /**/
53
+ if ($membership_options_page_cache["page"] === $membership_options_page && $membership_options_page_cache["time"] >= strtotime ("-15 minutes"))
54
+ {
55
+ $links["membership_options_page"] = $membership_options_page_cache["link"];
56
+ }
57
+ else /* Otherwise, we need to query the database using get_page_link() and update the cache. */
58
+ {
59
+ $GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["cache"]["membership_options_page"]["time"] = time ();
60
+ $GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["cache"]["membership_options_page"]["page"] = $membership_options_page;
61
+ $links["membership_options_page"] = $GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["cache"]["membership_options_page"]["link"] = get_page_link ($membership_options_page);
62
+ /**/
63
+ $cache_needs_updating = true; /* Flag for cache update. */
64
+ }
65
+ /**/
66
+ if ($file_download_limit_exceeded_page_cache["page"] === $file_download_limit_exceeded_page && $file_download_limit_exceeded_page_cache["time"] >= strtotime ("-15 minutes"))
67
+ {
68
+ $links["file_download_limit_exceeded_page"] = $file_download_limit_exceeded_page_cache["link"];
69
+ }
70
+ else /* Otherwise, we need to query the database using get_page_link() and update the cache. */
71
+ {
72
+ $GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["cache"]["file_download_limit_exceeded_page"]["time"] = time ();
73
+ $GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["cache"]["file_download_limit_exceeded_page"]["page"] = $file_download_limit_exceeded_page;
74
+ $links["file_download_limit_exceeded_page"] = $GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["cache"]["file_download_limit_exceeded_page"]["link"] = get_page_link ($file_download_limit_exceeded_page);
75
+ /**/
76
+ $cache_needs_updating = true; /* Flag for cache update. */
77
+ }
78
+ /**/
79
+ if ($cache_needs_updating) /* Cache is also reset dynamically during back-end option updates. */
80
+ {
81
+ update_option ("ws_plugin__s2member_cache", $GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["cache"]);
82
+ }
83
+ /**/
84
+ $scheme = (is_ssl ()) ? "https" : "http"; /* SSL mode? */
85
+ foreach ($links as &$link) /* Conversions for SSL and non-SSL mode. */
86
+ $link = preg_replace ("/^http(s)?\:\/\//i", $scheme . "://", $link);
87
+ /**/
88
+ return apply_filters ("ws_plugin__s2member_cached_page_links", $links, get_defined_vars ());
89
+ }
90
+ }
91
+ }
92
+ ?>
includes/classes/check-activation.inc.php CHANGED
@@ -19,7 +19,7 @@ if (!class_exists ("c_ws_plugin__s2member_check_activation"))
19
  class c_ws_plugin__s2member_check_activation
20
  {
21
  /*
22
- Check existing installations that have not been re-activated.
23
  Attach to: add_action("admin_init");
24
  */
25
  public static function check () /* Up-to-date? */
19
  class c_ws_plugin__s2member_check_activation
20
  {
21
  /*
22
+ Checks existing installs that are NOT yet re-activated.
23
  Attach to: add_action("admin_init");
24
  */
25
  public static function check () /* Up-to-date? */
includes/classes/constants.inc.php CHANGED
@@ -19,72 +19,7 @@ if (!class_exists ("c_ws_plugin__s2member_constants"))
19
  class c_ws_plugin__s2member_constants
20
  {
21
  /*
22
- This function pulls all of the Page links needed for Constants.
23
- Page links are cached into the s2Member options on 15 min intervals.
24
- This allows the API Constants to provide quick access to them without being forced to execute get_page_link() all the time, which piles up DB queries.
25
- */
26
- public static function constant_links ()
27
- {
28
- do_action ("ws_plugin__s2member_before_constant_links", get_defined_vars ());
29
- /**/
30
- $l = array ("login_welcome_page" => "", "membership_options_page" => "", "file_download_limit_exceeded_page" => "");
31
- /**/
32
- $login_welcome_page = $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["login_welcome_page"];
33
- $membership_options_page = $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["membership_options_page"];
34
- $file_download_limit_exceeded_page = $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["file_download_limit_exceeded_page"];
35
- /**/
36
- $login_welcome_page_cache = $GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["cache"]["login_welcome_page"];
37
- $membership_options_page_cache = $GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["cache"]["membership_options_page"];
38
- $file_download_limit_exceeded_page_cache = $GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["cache"]["file_download_limit_exceeded_page"];
39
- /**/
40
- if ($login_welcome_page_cache["page"] === $login_welcome_page && $login_welcome_page_cache["time"] >= strtotime ("-15 minutes"))
41
- {
42
- $l["login_welcome_page"] = $login_welcome_page_cache["link"];
43
- }
44
- else /* Otherwise, we need to query the database using get_page_link() and update the cache. */
45
- {
46
- $GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["cache"]["login_welcome_page"]["time"] = time ();
47
- $GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["cache"]["login_welcome_page"]["page"] = $login_welcome_page;
48
- $l["login_welcome_page"] = $GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["cache"]["login_welcome_page"]["link"] = get_page_link ($login_welcome_page);
49
- /**/
50
- $cache_needs_updating = true;
51
- }
52
- /**/
53
- if ($membership_options_page_cache["page"] === $membership_options_page && $membership_options_page_cache["time"] >= strtotime ("-15 minutes"))
54
- {
55
- $l["membership_options_page"] = $membership_options_page_cache["link"];
56
- }
57
- else /* Otherwise, we need to query the database using get_page_link() and update the cache. */
58
- {
59
- $GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["cache"]["membership_options_page"]["time"] = time ();
60
- $GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["cache"]["membership_options_page"]["page"] = $membership_options_page;
61
- $l["membership_options_page"] = $GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["cache"]["membership_options_page"]["link"] = get_page_link ($membership_options_page);
62
- /**/
63
- $cache_needs_updating = true;
64
- }
65
- /**/
66
- if ($file_download_limit_exceeded_page_cache["page"] === $file_download_limit_exceeded_page && $file_download_limit_exceeded_page_cache["time"] >= strtotime ("-15 minutes"))
67
- {
68
- $l["file_download_limit_exceeded_page"] = $file_download_limit_exceeded_page_cache["link"];
69
- }
70
- else /* Otherwise, we need to query the database using get_page_link() and update the cache. */
71
- {
72
- $GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["cache"]["file_download_limit_exceeded_page"]["time"] = time ();
73
- $GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["cache"]["file_download_limit_exceeded_page"]["page"] = $file_download_limit_exceeded_page;
74
- $l["file_download_limit_exceeded_page"] = $GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["cache"]["file_download_limit_exceeded_page"]["link"] = get_page_link ($file_download_limit_exceeded_page);
75
- /**/
76
- $cache_needs_updating = true;
77
- }
78
- /**/
79
- if ($cache_needs_updating) /* The cache is also reset when options are updated from a menu page. */
80
- {
81
- update_option ("ws_plugin__s2member_cache", $GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["cache"]);
82
- }
83
- /**/
84
- return apply_filters ("ws_plugin__s2member_constant_links", $l, get_defined_vars ());
85
- }
86
- /*
87
- Define several API Constants for s2Member.
88
  Note that these are duplicated into the JavaScript API as well.
89
  Attach to: add_action("init");
90
  */
@@ -92,16 +27,19 @@ if (!class_exists ("c_ws_plugin__s2member_constants"))
92
  {
93
  do_action ("ws_plugin__s2member_before_constants", get_defined_vars ());
94
  /**/
95
- $links = c_ws_plugin__s2member_constants::constant_links ();
96
- $level = c_ws_plugin__s2member_user_access::user_access_level ();
97
- $current_user = (is_user_logged_in ()) ? wp_get_current_user () : false;
98
- $file_downloads = c_ws_plugin__s2member_files::user_downloads ($current_user, false, null);
99
- $subscr_id = ($current_user) ? get_user_option ("s2member_subscr_id", $current_user->ID) : "";
100
- $subscr_gateway = ($current_user) ? get_user_option ("s2member_subscr_gateway", $current_user->ID) : "";
101
- $custom = ($current_user) ? get_user_option ("s2member_custom", $current_user->ID) : "";
102
- $custom_fields = ($current_user) ? get_user_option ("s2member_custom_fields", $current_user->ID) : array ();
103
- $paid_registration_times = ($current_user) ? get_user_option ("s2member_paid_registration_times", $current_user->ID) : array ();
104
- $login_redirection_url = c_ws_plugin__s2member_login_redirects::login_redirection_url ($current_user);
 
 
 
105
  /**/
106
  eval ('foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;');
107
  do_action ("ws_plugin__s2member_during_constants", get_defined_vars ());
@@ -109,26 +47,27 @@ if (!class_exists ("c_ws_plugin__s2member_constants"))
109
  /**/
110
  define ("S2MEMBER_VERSION", ($c[] = WS_PLUGIN__S2MEMBER_VERSION));
111
  /**/
112
- define ("S2MEMBER_CURRENT_USER_IS_LOGGED_IN", ($c[] = (($current_user) ? true : false)));
113
- define ("S2MEMBER_CURRENT_USER_IS_LOGGED_IN_AS_MEMBER", ($c[] = ( ($current_user && $level >= 1) ? true : false)));
114
- define ("S2MEMBER_CURRENT_USER_ACCESS_LEVEL", ($c[] = (int)$level));
115
  define ("S2MEMBER_CURRENT_USER_ACCESS_LABEL", ($c[] = (string)$GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["level" . $level . "_label"]));
116
- define ("S2MEMBER_CURRENT_USER_SUBSCR_ID", ($c[] = ( ($current_user && $subscr_id) ? (string)$subscr_id : "")));
117
- define ("S2MEMBER_CURRENT_USER_SUBSCR_OR_WP_ID", ($c[] = (($current_user) ? (($subscr_id) ? (string)$subscr_id : (string)$current_user->ID) : "")));
118
- define ("S2MEMBER_CURRENT_USER_SUBSCR_GATEWAY", ($c[] = (($current_user) ? (string)$subscr_gateway : "")));
119
- define ("S2MEMBER_CURRENT_USER_CUSTOM", ($c[] = (string)$custom));
120
- define ("S2MEMBER_CURRENT_USER_REGISTRATION_TIME", ($c[] = ( ($current_user && $current_user->user_registered) ? (int)strtotime ($current_user->user_registered) : 0)));
121
- define ("S2MEMBER_CURRENT_USER_PAID_REGISTRATION_TIME", ($c[] = ( ($current_user && (int)$paid_registration_times["level"]) ? (int)$paid_registration_times["level"] : 0)));
122
- define ("S2MEMBER_CURRENT_USER_PAID_REGISTRATION_DAYS", ($c[] = ( ($current_user && (int)$paid_registration_times["level"]) ? (int)floor ((strtotime ("now") - (int)$paid_registration_times["level"]) / 86400) : 0)));
123
- define ("S2MEMBER_CURRENT_USER_REGISTRATION_DAYS", ($c[] = ( ($current_user && $current_user->user_registered) ? (int)floor ((strtotime ("now") - strtotime ($current_user->user_registered)) / 86400) : 0)));
124
- define ("S2MEMBER_CURRENT_USER_DISPLAY_NAME", ($c[] = (($current_user) ? (string)$current_user->display_name : "")));
125
- define ("S2MEMBER_CURRENT_USER_FIRST_NAME", ($c[] = (($current_user) ? (string)$current_user->first_name : "")));
126
- define ("S2MEMBER_CURRENT_USER_LAST_NAME", ($c[] = (($current_user) ? (string)$current_user->last_name : "")));
127
- define ("S2MEMBER_CURRENT_USER_LOGIN", ($c[] = (($current_user) ? (string)$current_user->user_login : "")));
128
- define ("S2MEMBER_CURRENT_USER_EMAIL", ($c[] = (($current_user) ? (string)$current_user->user_email : "")));
129
  define ("S2MEMBER_CURRENT_USER_IP", ($c[] = (string)$_SERVER["REMOTE_ADDR"]));
130
- define ("S2MEMBER_CURRENT_USER_ID", ($c[] = (($current_user) ? (int)$current_user->ID : 0)));
131
- define ("S2MEMBER_CURRENT_USER_FIELDS", ($c[] = (($current_user) ? json_encode (array_merge (array ("id" => S2MEMBER_CURRENT_USER_ID, "ip" => S2MEMBER_CURRENT_USER_IP, "email" => S2MEMBER_CURRENT_USER_EMAIL, "login" => S2MEMBER_CURRENT_USER_LOGIN, "first_name" => S2MEMBER_CURRENT_USER_FIRST_NAME, "last_name" => S2MEMBER_CURRENT_USER_LAST_NAME, "display_name" => S2MEMBER_CURRENT_USER_DISPLAY_NAME, "subscr_id" => S2MEMBER_CURRENT_USER_SUBSCR_ID, "subscr_or_wp_id" => S2MEMBER_CURRENT_USER_SUBSCR_OR_WP_ID, "subscr_gateway" => S2MEMBER_CURRENT_USER_SUBSCR_GATEWAY, "custom" => S2MEMBER_CURRENT_USER_CUSTOM), (array)$custom_fields)) : json_encode (array ()))));
 
132
  /**/
133
  define ("S2MEMBER_CURRENT_USER_DOWNLOADS_ALLOWED", ($c[] = (int)$file_downloads["allowed"]));
134
  define ("S2MEMBER_CURRENT_USER_DOWNLOADS_ALLOWED_IS_UNLIMITED", ($c[] = ( ($file_downloads["allowed"] >= 999999999) ? true : false)));
@@ -141,10 +80,10 @@ if (!class_exists ("c_ws_plugin__s2member_constants"))
141
  /**/
142
  define ("S2MEMBER_CURRENT_USER_PROFILE_MODIFICATION_PAGE_URL", ($c[] = site_url ("/?s2member_profile=1")));
143
  define ("S2MEMBER_FILE_DOWNLOAD_LIMIT_EXCEEDED_PAGE_URL", ($c[] = (string)$links["file_download_limit_exceeded_page"]));
144
- define ("S2MEMBER_MEMBERSHIP_OPTIONS_PAGE_URL", ($c[] = (string)$links["membership_options_page"]));
145
  define ("S2MEMBER_LOGIN_WELCOME_PAGE_URL", ($c[] = (($login_redirection_url) ? (string)$login_redirection_url : (string)$links["login_welcome_page"])));
146
- define ("S2MEMBER_LOGOUT_PAGE_URL", ($c[] = (string)wp_logout_url ()));
147
- define ("S2MEMBER_LOGIN_PAGE_URL", ($c[] = (string)wp_login_url ()));
148
  /**/
149
  define ("S2MEMBER_LEVEL0_LABEL", ($c[] = (string)$GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["level0_label"]));
150
  define ("S2MEMBER_LEVEL1_LABEL", ($c[] = (string)$GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["level1_label"]));
19
  class c_ws_plugin__s2member_constants
20
  {
21
  /*
22
+ Defines several API Constants for s2Member.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
23
  Note that these are duplicated into the JavaScript API as well.
24
  Attach to: add_action("init");
25
  */
27
  {
28
  do_action ("ws_plugin__s2member_before_constants", get_defined_vars ());
29
  /**/
30
+ $links = c_ws_plugin__s2member_cache::cached_page_links ();
31
+ /**/
32
+ $user = (is_user_logged_in ()) ? wp_get_current_user () : false;
33
+ /**/
34
+ $level = c_ws_plugin__s2member_user_access::user_access_level ($user);
35
+ $file_downloads = c_ws_plugin__s2member_files::user_downloads ($user);
36
+ $login_redirection_url = c_ws_plugin__s2member_login_redirects::login_redirection_url ($user);
37
+ /**/
38
+ $custom = ($user) ? get_user_option ("s2member_custom", $user->ID) : "";
39
+ $subscr_id = ($user) ? get_user_option ("s2member_subscr_id", $user->ID) : "";
40
+ $subscr_gateway = ($user) ? get_user_option ("s2member_subscr_gateway", $user->ID) : "";
41
+ $custom_fields = ($user) ? get_user_option ("s2member_custom_fields", $user->ID) : array ();
42
+ $paid_registration_times = ($user) ? get_user_option ("s2member_paid_registration_times", $user->ID) : array ();
43
  /**/
44
  eval ('foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;');
45
  do_action ("ws_plugin__s2member_during_constants", get_defined_vars ());
47
  /**/
48
  define ("S2MEMBER_VERSION", ($c[] = WS_PLUGIN__S2MEMBER_VERSION));
49
  /**/
50
+ define ("S2MEMBER_CURRENT_USER_IS_LOGGED_IN", ($c[] = (($user) ? true : false)));
51
+ define ("S2MEMBER_CURRENT_USER_IS_LOGGED_IN_AS_MEMBER", ($c[] = ( ($user && $level >= 1) ? true : false)));
52
+ define ("S2MEMBER_CURRENT_USER_ACCESS_LEVEL", ($c[] = (int)$level)); /* Negative -1 through max Membership Level number. */
53
  define ("S2MEMBER_CURRENT_USER_ACCESS_LABEL", ($c[] = (string)$GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["level" . $level . "_label"]));
54
+ define ("S2MEMBER_CURRENT_USER_SUBSCR_ID", ($c[] = ( ($user && $subscr_id) ? (string)$subscr_id : ""))); /* Paid Subscr. ID. */
55
+ define ("S2MEMBER_CURRENT_USER_SUBSCR_OR_WP_ID", ($c[] = (($user) ? (($subscr_id) ? (string)$subscr_id : (string)$user->ID) : "")));
56
+ define ("S2MEMBER_CURRENT_USER_SUBSCR_GATEWAY", ($c[] = (($user) ? (string)$subscr_gateway : ""))); /* Payment Gateway. */
57
+ define ("S2MEMBER_CURRENT_USER_CUSTOM", ($c[] = (($user) ? (string)$custom : ""))); /* Starts w/ domain name. */
58
+ define ("S2MEMBER_CURRENT_USER_REGISTRATION_TIME", ($c[] = ( ($user && $user->user_registered) ? (int)strtotime ($user->user_registered) : 0)));
59
+ define ("S2MEMBER_CURRENT_USER_PAID_REGISTRATION_TIME", ($c[] = ( ($user && (int)$paid_registration_times["level"]) ? (int)$paid_registration_times["level"] : 0)));
60
+ define ("S2MEMBER_CURRENT_USER_PAID_REGISTRATION_DAYS", ($c[] = ( ($user && (int)$paid_registration_times["level"]) ? (int)floor ((strtotime ("now") - (int)$paid_registration_times["level"]) / 86400) : 0)));
61
+ define ("S2MEMBER_CURRENT_USER_REGISTRATION_DAYS", ($c[] = ( ($user && $user->user_registered) ? (int)floor ((strtotime ("now") - strtotime ($user->user_registered)) / 86400) : 0)));
62
+ define ("S2MEMBER_CURRENT_USER_DISPLAY_NAME", ($c[] = (($user) ? (string)$user->display_name : "")));
63
+ define ("S2MEMBER_CURRENT_USER_FIRST_NAME", ($c[] = (($user) ? (string)$user->first_name : "")));
64
+ define ("S2MEMBER_CURRENT_USER_LAST_NAME", ($c[] = (($user) ? (string)$user->last_name : "")));
65
+ define ("S2MEMBER_CURRENT_USER_LOGIN", ($c[] = (($user) ? (string)$user->user_login : "")));
66
+ define ("S2MEMBER_CURRENT_USER_EMAIL", ($c[] = (($user) ? (string)$user->user_email : "")));
67
  define ("S2MEMBER_CURRENT_USER_IP", ($c[] = (string)$_SERVER["REMOTE_ADDR"]));
68
+ define ("S2MEMBER_CURRENT_USER_ID", ($c[] = (($user) ? (int)$user->ID : 0)));
69
+ /**/
70
+ define ("S2MEMBER_CURRENT_USER_FIELDS", ($c[] = (($user) ? json_encode (array_merge (array ("id" => S2MEMBER_CURRENT_USER_ID, "ip" => S2MEMBER_CURRENT_USER_IP, "email" => S2MEMBER_CURRENT_USER_EMAIL, "login" => S2MEMBER_CURRENT_USER_LOGIN, "first_name" => S2MEMBER_CURRENT_USER_FIRST_NAME, "last_name" => S2MEMBER_CURRENT_USER_LAST_NAME, "display_name" => S2MEMBER_CURRENT_USER_DISPLAY_NAME, "subscr_id" => S2MEMBER_CURRENT_USER_SUBSCR_ID, "subscr_or_wp_id" => S2MEMBER_CURRENT_USER_SUBSCR_OR_WP_ID, "subscr_gateway" => S2MEMBER_CURRENT_USER_SUBSCR_GATEWAY, "custom" => S2MEMBER_CURRENT_USER_CUSTOM), (array)$custom_fields)) : json_encode (array ()))));
71
  /**/
72
  define ("S2MEMBER_CURRENT_USER_DOWNLOADS_ALLOWED", ($c[] = (int)$file_downloads["allowed"]));
73
  define ("S2MEMBER_CURRENT_USER_DOWNLOADS_ALLOWED_IS_UNLIMITED", ($c[] = ( ($file_downloads["allowed"] >= 999999999) ? true : false)));
80
  /**/
81
  define ("S2MEMBER_CURRENT_USER_PROFILE_MODIFICATION_PAGE_URL", ($c[] = site_url ("/?s2member_profile=1")));
82
  define ("S2MEMBER_FILE_DOWNLOAD_LIMIT_EXCEEDED_PAGE_URL", ($c[] = (string)$links["file_download_limit_exceeded_page"]));
83
+ define ("S2MEMBER_MEMBERSHIP_OPTIONS_PAGE_URL", ($c[] = (string)$links["membership_options_page"])); /* Signup page. */
84
  define ("S2MEMBER_LOGIN_WELCOME_PAGE_URL", ($c[] = (($login_redirection_url) ? (string)$login_redirection_url : (string)$links["login_welcome_page"])));
85
+ define ("S2MEMBER_LOGOUT_PAGE_URL", ($c[] = (string)wp_logout_url ())); /* This triggers `wp_nonce_tick()`; watch out for dynamic changes. */
86
+ define ("S2MEMBER_LOGIN_PAGE_URL", ($c[] = (string)wp_login_url ())); /* Will not trigger `wp_nonce_tick()`, no worries in this case. */
87
  /**/
88
  define ("S2MEMBER_LEVEL0_LABEL", ($c[] = (string)$GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["level0_label"]));
89
  define ("S2MEMBER_LEVEL1_LABEL", ($c[] = (string)$GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["level1_label"]));
includes/classes/css-js-in.inc.php CHANGED
@@ -65,7 +65,7 @@ if (!class_exists ("c_ws_plugin__s2member_css_js_in"))
65
  header ("Cache-Control: max-age=604800");
66
  header ("Pragma: public");
67
  /**/
68
- $g = "var S2MEMBER_VERSION = '" . c_ws_plugin__s2member_utils_strings::esc_sq (S2MEMBER_VERSION) . "',"; /* Since 3.0. */
69
  /**/
70
  $g .= "S2MEMBER_CURRENT_USER_IS_LOGGED_IN = " . ((S2MEMBER_CURRENT_USER_IS_LOGGED_IN) ? "true" : "false") . ",";
71
  $g .= "S2MEMBER_CURRENT_USER_IS_LOGGED_IN_AS_MEMBER = " . ((S2MEMBER_CURRENT_USER_IS_LOGGED_IN_AS_MEMBER) ? "true" : "false") . ",";
65
  header ("Cache-Control: max-age=604800");
66
  header ("Pragma: public");
67
  /**/
68
+ $g = "var S2MEMBER_VERSION = '" . c_ws_plugin__s2member_utils_strings::esc_sq (S2MEMBER_VERSION) . "',";
69
  /**/
70
  $g .= "S2MEMBER_CURRENT_USER_IS_LOGGED_IN = " . ((S2MEMBER_CURRENT_USER_IS_LOGGED_IN) ? "true" : "false") . ",";
71
  $g .= "S2MEMBER_CURRENT_USER_IS_LOGGED_IN_AS_MEMBER = " . ((S2MEMBER_CURRENT_USER_IS_LOGGED_IN_AS_MEMBER) ? "true" : "false") . ",";
includes/classes/files-in.inc.php CHANGED
@@ -30,8 +30,6 @@ if (!class_exists ("c_ws_plugin__s2member_files_in"))
30
  {
31
  $excluded = apply_filters ("ws_plugin__s2member_check_file_download_access_excluded", false, get_defined_vars ());
32
  /**/
33
- $_GET["s2member_file_download_key"] = (!$_GET["s2member_file_download_key"] && $_GET["s2member_free_file_download_key"]) ? $_GET["s2member_free_file_download_key"] : $_GET["s2member_file_download_key"];
34
- /**/
35
  if (!$excluded && (!$_GET["s2member_file_download_key"] || ($_GET["s2member_file_download_key"] && ! ($file_download_key_is_valid = ($_GET["s2member_file_download_key"] === c_ws_plugin__s2member_files::file_download_key ($_GET["s2member_file_download"]) || $_GET["s2member_file_download_key"] === c_ws_plugin__s2member_files::file_download_key ($_GET["s2member_file_download"], true))))))
36
  {
37
  $_GET["s2member_file_download"] = trim ($_GET["s2member_file_download"], "/"); /* Trim slashes after Key comparison. */
@@ -142,13 +140,13 @@ if (!class_exists ("c_ws_plugin__s2member_files_in"))
142
  Send the file to the browser in chunks ( in support of larger files ).
143
  Be sure to turn off output compression, as it DOES get in the way.
144
  */
145
- set_time_limit (0); /* Unlimited. */
146
  @ini_set ("zlib.output_compression", 0);
147
  /**/
148
  header ("Accept-Ranges: none");
149
  header ("Content-Encoding: none");
150
  header ("Content-Type: " . $mimetype);
151
- header ("Transfer-Encoding: chunked");
152
  header ("Expires: " . gmdate ("D, d M Y H:i:s", strtotime ("-1 week")) . " GMT");
153
  header ("Last-Modified: " . gmdate ("D, d M Y H:i:s") . " GMT");
154
  header ("Cache-Control: no-cache, must-revalidate, max-age=0");
@@ -159,12 +157,14 @@ if (!class_exists ("c_ws_plugin__s2member_files_in"))
159
  /**/
160
  if ($length && apply_filters ("ws_plugin__s2member_stream_file_downloads", true, get_defined_vars ()) && ($stream = fopen ($file, "rb")))
161
  {
162
- @ob_end_clean (); /* End/clean output buffer. */
 
 
163
  /**/
164
  while (!feof ($stream) && ($chunk_size = strlen ($data = fread ($stream, 2097152))))
165
  eval ('echo dechex ($chunk_size) . "\r\n". $data . "\r\n"; @flush ();');
166
  /**/
167
- fclose($stream);
168
  /**/
169
  exit ("0\r\n\r\n");
170
  }
30
  {
31
  $excluded = apply_filters ("ws_plugin__s2member_check_file_download_access_excluded", false, get_defined_vars ());
32
  /**/
 
 
33
  if (!$excluded && (!$_GET["s2member_file_download_key"] || ($_GET["s2member_file_download_key"] && ! ($file_download_key_is_valid = ($_GET["s2member_file_download_key"] === c_ws_plugin__s2member_files::file_download_key ($_GET["s2member_file_download"]) || $_GET["s2member_file_download_key"] === c_ws_plugin__s2member_files::file_download_key ($_GET["s2member_file_download"], true))))))
34
  {
35
  $_GET["s2member_file_download"] = trim ($_GET["s2member_file_download"], "/"); /* Trim slashes after Key comparison. */
140
  Send the file to the browser in chunks ( in support of larger files ).
141
  Be sure to turn off output compression, as it DOES get in the way.
142
  */
143
+ @set_time_limit (0); /* Unlimited. */
144
  @ini_set ("zlib.output_compression", 0);
145
  /**/
146
  header ("Accept-Ranges: none");
147
  header ("Content-Encoding: none");
148
  header ("Content-Type: " . $mimetype);
149
+ header ("Content-Length: " . $length);
150
  header ("Expires: " . gmdate ("D, d M Y H:i:s", strtotime ("-1 week")) . " GMT");
151
  header ("Last-Modified: " . gmdate ("D, d M Y H:i:s") . " GMT");
152
  header ("Cache-Control: no-cache, must-revalidate, max-age=0");
157
  /**/
158
  if ($length && apply_filters ("ws_plugin__s2member_stream_file_downloads", true, get_defined_vars ()) && ($stream = fopen ($file, "rb")))
159
  {
160
+ header ("Transfer-Encoding: chunked"); /* Uses `Transfer-Encoding: chunked` for simulated streaming. */
161
+ /**/
162
+ eval ('while (@ob_end_clean ());'); /* End/clean all output buffers that may or may not exist. */
163
  /**/
164
  while (!feof ($stream) && ($chunk_size = strlen ($data = fread ($stream, 2097152))))
165
  eval ('echo dechex ($chunk_size) . "\r\n". $data . "\r\n"; @flush ();');
166
  /**/
167
+ fclose ($stream);
168
  /**/
169
  exit ("0\r\n\r\n");
170
  }
includes/classes/installation.inc.php CHANGED
@@ -162,7 +162,7 @@ if (!class_exists ("c_ws_plugin__s2member_installation"))
162
  /* Version 3.5 introduced a dismissal message regarding Screen Options in the list of Users/Members. */
163
  {
164
  $notice = '<strong>Note:</strong> s2Member adds some new data columns to your list of Users/Members. If your list gets overcrowded, please use the <strong>Screen Options</strong> tab <em>( upper right-hand corner )</em>. With WordPress® Screen Options, you can add/remove specific data columns; thereby making the most important data easier to read. For example, if you create Custom Registration Fields with s2Member, those Custom Fields will result in new data columns; which can cause your list of Users/Members to become nearly unreadable. So just use the Screen Options tab to clean things up.';
165
- c_ws_plugin__s2member_admin_notices::enqueue_admin_notice ($notice, "blog:users.php", false, false, true); /* Visible until dismissed. */
166
  }
167
  /**/
168
  $notice = '<strong>s2Member</strong> has been <strong>re-activated</strong>, with the latest version.<br />';
@@ -183,7 +183,7 @@ if (!class_exists ("c_ws_plugin__s2member_installation"))
183
  {
184
  $notice = '<strong>Note:</strong> s2Member adds some new data columns to your list of Users/Members. If your list gets overcrowded, please use the <strong>Screen Options</strong> tab <em>( upper right-hand corner )</em>. With WordPress® Screen Options, you can add/remove specific data columns; thereby making the most important data easier to read. For example, if you create Custom Registration Fields with s2Member, those Custom Fields will result in new data columns; which can cause your list of Users/Members to become nearly unreadable. So just use the Screen Options tab to clean things up.';
185
  /**/
186
- c_ws_plugin__s2member_admin_notices::enqueue_admin_notice ($notice, "blog:users.php", false, false, true); /* Remain visible until dismissed by the site owner. */
187
  /**/
188
  $notice = '<strong>s2Member</strong> v' . esc_html (WS_PLUGIN__S2MEMBER_VERSION) . ' has been <strong>activated</strong>. Nice work!<br />';
189
  $notice .= 'Have fun, <a href="' . esc_attr (admin_url ("/admin.php?page=ws-plugin--s2member-start")) . '">read the Quick Start Guide</a>, and make some money! :-)';
@@ -279,9 +279,9 @@ if (!class_exists ("c_ws_plugin__s2member_installation"))
279
  {
280
  if (file_exists ($htaccess = $files_dir . "/.htaccess"))
281
  if (is_writable ($htaccess))
282
- unlink ($htaccess);
283
  /**/
284
- @rmdir ($files_dir) . @rmdir (c_ws_plugin__s2member_utils_dirs::strip_dir_app_data ($files_dir));
285
  }
286
  /**/
287
  if (is_dir ($logs_dir = $GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["logs_dir"]))
@@ -289,9 +289,9 @@ if (!class_exists ("c_ws_plugin__s2member_installation"))
289
  foreach (scandir ($logs_dir) as $log_file)
290
  if (is_file ($log_file = $logs_dir . "/" . $log_file))
291
  if (is_writable ($log_file))
292
- unlink ($log_file);
293
  /**/
294
- @rmdir ($logs_dir) . @rmdir (c_ws_plugin__s2member_utils_dirs::strip_dir_app_data ($logs_dir));
295
  }
296
  /**/
297
  delete_option ("ws_plugin__s2member_cache");
162
  /* Version 3.5 introduced a dismissal message regarding Screen Options in the list of Users/Members. */
163
  {
164
  $notice = '<strong>Note:</strong> s2Member adds some new data columns to your list of Users/Members. If your list gets overcrowded, please use the <strong>Screen Options</strong> tab <em>( upper right-hand corner )</em>. With WordPress® Screen Options, you can add/remove specific data columns; thereby making the most important data easier to read. For example, if you create Custom Registration Fields with s2Member, those Custom Fields will result in new data columns; which can cause your list of Users/Members to become nearly unreadable. So just use the Screen Options tab to clean things up.';
165
+ c_ws_plugin__s2member_admin_notices::enqueue_admin_notice ($notice, "blog:users.php", false, false, true);
166
  }
167
  /**/
168
  $notice = '<strong>s2Member</strong> has been <strong>re-activated</strong>, with the latest version.<br />';
183
  {
184
  $notice = '<strong>Note:</strong> s2Member adds some new data columns to your list of Users/Members. If your list gets overcrowded, please use the <strong>Screen Options</strong> tab <em>( upper right-hand corner )</em>. With WordPress® Screen Options, you can add/remove specific data columns; thereby making the most important data easier to read. For example, if you create Custom Registration Fields with s2Member, those Custom Fields will result in new data columns; which can cause your list of Users/Members to become nearly unreadable. So just use the Screen Options tab to clean things up.';
185
  /**/
186
+ c_ws_plugin__s2member_admin_notices::enqueue_admin_notice ($notice, "blog:users.php", false, false, true);
187
  /**/
188
  $notice = '<strong>s2Member</strong> v' . esc_html (WS_PLUGIN__S2MEMBER_VERSION) . ' has been <strong>activated</strong>. Nice work!<br />';
189
  $notice .= 'Have fun, <a href="' . esc_attr (admin_url ("/admin.php?page=ws-plugin--s2member-start")) . '">read the Quick Start Guide</a>, and make some money! :-)';
279
  {
280
  if (file_exists ($htaccess = $files_dir . "/.htaccess"))
281
  if (is_writable ($htaccess))
282
+ unlink($htaccess);
283
  /**/
284
+ @rmdir($files_dir) . @rmdir (c_ws_plugin__s2member_utils_dirs::strip_dir_app_data ($files_dir));
285
  }
286
  /**/
287
  if (is_dir ($logs_dir = $GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["logs_dir"]))
289
  foreach (scandir ($logs_dir) as $log_file)
290
  if (is_file ($log_file = $logs_dir . "/" . $log_file))
291
  if (is_writable ($log_file))
292
+ unlink($log_file);
293
  /**/
294
+ @rmdir($logs_dir) . @rmdir (c_ws_plugin__s2member_utils_dirs::strip_dir_app_data ($logs_dir));
295
  }
296
  /**/
297
  delete_option ("ws_plugin__s2member_cache");
includes/classes/list-servers.inc.php CHANGED
@@ -19,8 +19,7 @@ if (!class_exists ("c_ws_plugin__s2member_list_servers"))
19
  class c_ws_plugin__s2member_list_servers
20
  {
21
  /*
22
- Function that determines whether or not any list
23
- servers have been integrated into the s2Member options.
24
  */
25
  public static function list_servers_integrated ()
26
  {
@@ -33,9 +32,9 @@ if (!class_exists ("c_ws_plugin__s2member_list_servers"))
33
  return apply_filters ("ws_plugin__s2member_list_servers_integrated", false, get_defined_vars ());
34
  }
35
  /*
36
- Function that processes List Server integrations for s2Member.
37
  */
38
- public static function process_list_servers ($role = FALSE, $level = FALSE, $email = FALSE, $fname = FALSE, $lname = FALSE, $ip = FALSE, $opt_in = FALSE, $user_id = FALSE)
39
  {
40
  global $current_site, $current_blog; /* For Multisite support. */
41
  /**/
@@ -43,10 +42,10 @@ if (!class_exists ("c_ws_plugin__s2member_list_servers"))
43
  do_action ("ws_plugin__s2member_before_process_list_servers", get_defined_vars ());
44
  unset ($__refs, $__v); /* Unset defined __refs, __v. */
45
  /**/
46
- if (strlen ($level) && is_email ($email) && $opt_in) /* Must have these. */
47
  {
48
  $email_configs_were_on = c_ws_plugin__s2member_email_configs::email_config_status (0);
49
- c_ws_plugin__s2member_email_configs::email_config_release (); /* Release Filters. */
50
  /**/
51
  if (($mailchimp_api_key = $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["mailchimp_api_key"]))
52
  if (($mailchimp_list_ids = $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["level" . $level . "_mailchimp_list_ids"]))
@@ -62,8 +61,10 @@ if (!class_exists ("c_ws_plugin__s2member_list_servers"))
62
  /**/
63
  if (($aweber_list_ids = $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["level" . $level . "_aweber_list_ids"]))
64
  {
 
 
65
  foreach (preg_split ("/[\r\n\t\s;,]+/", $aweber_list_ids) as $aweber_list_id)
66
- wp_mail ($aweber_list_id . "@aweber.com", apply_filters ("ws_plugin__s2member_aweber_sbj", "s2Member Subscription Request", get_defined_vars ()), apply_filters ("ws_plugin__s2member_aweber_msg", "s2Member Subscription Request\ns2Member w/ PayPal Email ID\nEMail Address: " . $email . "\nBuyer: " . $fname . " " . $lname . "\nFull Name: " . $fname . " " . $lname . "\nFirst Name: " . $fname . "\nLast Name: " . $lname . "\nIP Address: " . $ip . "\nUser ID: " . $user_id . "\nRole: " . $role . "\nLevel: " . $level . "\n - end.", get_defined_vars ()), "From: \"" . preg_replace ("/\"/", "", $fname . " " . $lname) . "\" <" . $email . ">\r\nContent-Type: text/plain; charset=utf-8");
67
  }
68
  /**/
69
  eval ('foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;');
@@ -81,9 +82,9 @@ if (!class_exists ("c_ws_plugin__s2member_list_servers"))
81
  return; /* Return for uniformity. */
82
  }
83
  /*
84
- Function that processes list server removals for s2Member.
85
  */
86
- public static function process_list_server_removals ($role = FALSE, $level = FALSE, $email = FALSE, $fname = FALSE, $lname = FALSE, $ip = FALSE, $opt_out = FALSE, $user_id = FALSE)
87
  {
88
  global $current_site, $current_blog; /* For Multisite support. */
89
  /**/
@@ -91,7 +92,7 @@ if (!class_exists ("c_ws_plugin__s2member_list_servers"))
91
  do_action ("ws_plugin__s2member_before_process_list_server_removals", get_defined_vars ());
92
  unset ($__refs, $__v); /* Unset defined __refs, __v. */
93
  /**/
94
- if (strlen ($level) && is_email ($email) && $opt_out) /* Must have these. */
95
  {
96
  $email_configs_were_on = c_ws_plugin__s2member_email_configs::email_config_status (0);
97
  c_ws_plugin__s2member_email_configs::email_config_release (); /* Release Filters. */
@@ -129,12 +130,12 @@ if (!class_exists ("c_ws_plugin__s2member_list_servers"))
129
  return; /* Return for uniformity. */
130
  }
131
  /*
132
- This function listens to Collective EOT/MOD Events processed internally by s2Member.
133
  This is only applicable when ["custom_reg_auto_opt_outs"] contains related Event(s).
134
- Attach to: add_action("ws_plugin__s2member_during_collective_eots");
135
- Attach to: add_action("ws_plugin__s2member_during_collective_mods");
136
  */
137
- public static function auto_process_list_server_removals ($user_id = FALSE, $vars = FALSE, $event = FALSE, $new_level = FALSE)
138
  {
139
  global $current_site, $current_blog; /* For Multisite support. */
140
  static $auto_processed = array (); /* Only process ONE time for each User ID. */
@@ -143,14 +144,14 @@ if (!class_exists ("c_ws_plugin__s2member_list_servers"))
143
  do_action ("ws_plugin__s2member_before_auto_process_list_server_removals", get_defined_vars ());
144
  unset ($__refs, $__v); /* Unset defined __refs, __v. */
145
  /**/
146
- if ($user_id && !in_array ($user_id, $auto_processed) && in_array ($event, $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["custom_reg_auto_opt_outs"]) && c_ws_plugin__s2member_list_servers::list_servers_integrated () && is_object ($user = new WP_User ($user_id)) && $user->ID)
147
  {
148
- if ((!strlen ($new_level) || (int)$new_level !== c_ws_plugin__s2member_user_access::user_access_level ($user)) && ($auto_processed[$user_id] = true))
149
  {
150
- c_ws_plugin__s2member_list_servers::process_list_server_removals (c_ws_plugin__s2member_user_access::user_access_role ($user), c_ws_plugin__s2member_user_access::user_access_level ($user), $user->user_email, $user->first_name, $user->last_name, false, true, $user_id);
151
  /**/
152
- if (strlen ($new_level) && apply_filters ("ws_plugin__s2member_auto_process_new_list_servers", true, get_defined_vars ())) /* Subscribe to new List(s)? */
153
- c_ws_plugin__s2member_list_servers::process_list_servers ("s2member_level" . $new_level, $new_level, $user->user_email, $user->first_name, $user->last_name, false, true, $user_id);
154
  }
155
  }
156
  /**/
19
  class c_ws_plugin__s2member_list_servers
20
  {
21
  /*
22
+ Determines whether or not any list servers have been integrated into the s2Member options.
 
23
  */
24
  public static function list_servers_integrated ()
25
  {
32
  return apply_filters ("ws_plugin__s2member_list_servers_integrated", false, get_defined_vars ());
33
  }
34
  /*
35
+ Processes List Server integrations for s2Member.
36
  */
37
+ public static function process_list_servers ($role = FALSE, $level = FALSE, $login = FALSE, $pass = FALSE, $email = FALSE, $fname = FALSE, $lname = FALSE, $ip = FALSE, $opt_in = FALSE, $user_id = FALSE)
38
  {
39
  global $current_site, $current_blog; /* For Multisite support. */
40
  /**/
42
  do_action ("ws_plugin__s2member_before_process_list_servers", get_defined_vars ());
43
  unset ($__refs, $__v); /* Unset defined __refs, __v. */
44
  /**/
45
+ if ($role && strlen ($level) && $login && is_email ($email) && $opt_in && $user_id)
46
  {
47
  $email_configs_were_on = c_ws_plugin__s2member_email_configs::email_config_status (0);
48
+ c_ws_plugin__s2member_email_configs::email_config_release (); /* Release. */
49
  /**/
50
  if (($mailchimp_api_key = $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["mailchimp_api_key"]))
51
  if (($mailchimp_list_ids = $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["level" . $level . "_mailchimp_list_ids"]))
61
  /**/
62
  if (($aweber_list_ids = $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["level" . $level . "_aweber_list_ids"]))
63
  {
64
+ $aweber_pass_inclusion = /* Off by default ( this poses a security risk ) » */ (apply_filters ("ws_plugin__s2member_aweber_pass_inclusion", false, get_defined_vars ()) && $pass) ? "\nPass: " . $pass : false;
65
+ /**/
66
  foreach (preg_split ("/[\r\n\t\s;,]+/", $aweber_list_ids) as $aweber_list_id)
67
+ wp_mail ($aweber_list_id . "@aweber.com", apply_filters ("ws_plugin__s2member_aweber_sbj", "s2Member Subscription Request", get_defined_vars ()), apply_filters ("ws_plugin__s2member_aweber_msg", "s2Member Subscription Request\ns2Member w/ PayPal Email ID\nEMail Address: " . $email . "\nBuyer: " . $fname . " " . $lname . "\nFull Name: " . $fname . " " . $lname . "\nFirst Name: " . $fname . "\nLast Name: " . $lname . "\nIP Address: " . $ip . "\nUser ID: " . $user_id . "\nLogin: " . $login . $aweber_pass_inclusion . "\nRole: " . $role . "\nLevel: " . $level . "\n - end.", get_defined_vars ()), "From: \"" . preg_replace ("/\"/", "", $fname . " " . $lname) . "\" <" . $email . ">\r\nContent-Type: text/plain; charset=utf-8");
68
  }
69
  /**/
70
  eval ('foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;');
82
  return; /* Return for uniformity. */
83
  }
84
  /*
85
+ Processes list server removals for s2Member.
86
  */
87
+ public static function process_list_server_removals ($role = FALSE, $level = FALSE, $login = FALSE, $pass = FALSE, $email = FALSE, $fname = FALSE, $lname = FALSE, $ip = FALSE, $opt_out = FALSE, $user_id = FALSE)
88
  {
89
  global $current_site, $current_blog; /* For Multisite support. */
90
  /**/
92
  do_action ("ws_plugin__s2member_before_process_list_server_removals", get_defined_vars ());
93
  unset ($__refs, $__v); /* Unset defined __refs, __v. */
94
  /**/
95
+ if ($role && strlen ($level) && $login && is_email ($email) && $opt_out && $user_id)
96
  {
97
  $email_configs_were_on = c_ws_plugin__s2member_email_configs::email_config_status (0);
98
  c_ws_plugin__s2member_email_configs::email_config_release (); /* Release Filters. */
130
  return; /* Return for uniformity. */
131
  }
132
  /*
133
+ Listens to Collective EOT/MOD Events processed internally by s2Member.
134
  This is only applicable when ["custom_reg_auto_opt_outs"] contains related Event(s).
135
+ Attach to: add_action("ws_plugin__s2member_during_collective_eots");
136
+ Attach to: add_action("ws_plugin__s2member_during_collective_mods");
137
  */
138
+ public static function auto_process_list_server_removals ($user_id = FALSE, $vars = FALSE, $event = FALSE, $_event_spec = FALSE, $_mod_new_level = FALSE)
139
  {
140
  global $current_site, $current_blog; /* For Multisite support. */
141
  static $auto_processed = array (); /* Only process ONE time for each User ID. */
144
  do_action ("ws_plugin__s2member_before_auto_process_list_server_removals", get_defined_vars ());
145
  unset ($__refs, $__v); /* Unset defined __refs, __v. */
146
  /**/
147
+ if ($user_id && !in_array ($user_id, $auto_processed) && (c_ws_plugin__s2member_utils_arrays::in_regex_array ($event, $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["custom_reg_auto_opt_outs"]) || c_ws_plugin__s2member_utils_arrays::in_regex_array ($_event_spec, $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["custom_reg_auto_opt_outs"])) && c_ws_plugin__s2member_list_servers::list_servers_integrated () && is_object ($user = new WP_User ($user_id)) && $user->ID)
148
  {
149
+ if (($_event_spec !== "modification" || ($_event_spec === "modification" && strlen ($_mod_new_level) && (int)$_mod_new_level !== c_ws_plugin__s2member_user_access::user_access_level ($user))) && ($auto_processed[$user_id] = true))
150
  {
151
+ c_ws_plugin__s2member_list_servers::process_list_server_removals (c_ws_plugin__s2member_user_access::user_access_role ($user), c_ws_plugin__s2member_user_access::user_access_level ($user), $user->user_login, false, $user->user_email, $user->first_name, $user->last_name, false, true, $user_id);
152
  /**/
153
+ if ($_event_spec === "modification" && strlen ($_mod_new_level) && apply_filters ("ws_plugin__s2member_auto_process_new_list_servers", true, get_defined_vars ())) /* Subscribe to new List(s)? */
154
+ c_ws_plugin__s2member_list_servers::process_list_servers ("s2member_level" . $_mod_new_level, $_mod_new_level, $user->user_login, false, $user->user_email, $user->first_name, $user->last_name, false, true, $user_id);
155
  }
156
  }
157
  /**/
includes/classes/login-redirects.inc.php CHANGED
@@ -28,9 +28,9 @@ if (!class_exists ("c_ws_plugin__s2member_login_redirects"))
28
  do_action ("ws_plugin__s2member_before_login_redirect", get_defined_vars ());
29
  unset ($__refs, $__v); /* Unset defined __refs, __v. */
30
  /**/
31
- $username = (!$username && is_object ($current_user = wp_get_current_user ())) ? $current_user->user_login : $username;
32
  /**/
33
- if ($username && is_object ($user = new WP_User ($username)) && ($user_id = $user->ID) && (!$user->has_cap ("edit_posts") || apply_filters ("ws_plugin__s2member_login_redirect", false, get_defined_vars ())))
34
  {
35
  if ($user->has_cap ("edit_posts") || strtolower ($username) === "demo" || c_ws_plugin__s2member_ip_restrictions::ip_restrictions_ok ($_SERVER["REMOTE_ADDR"], strtolower ($username)))
36
  {
@@ -38,7 +38,7 @@ if (!class_exists ("c_ws_plugin__s2member_login_redirects"))
38
  {
39
  if ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["custom_reg_password"]) /* Using custom Passwords? */
40
  {
41
- delete_user_setting ("default_password_nag"); /* setcookie(). */
42
  update_user_option ($user_id, "default_password_nag", false, true);
43
  }
44
  /**/
@@ -47,7 +47,7 @@ if (!class_exists ("c_ws_plugin__s2member_login_redirects"))
47
  unset ($__refs, $__v); /* Unset defined __refs, __v. */
48
  /**/
49
  if ($special_redirection_url = c_ws_plugin__s2member_login_redirects::login_redirection_url ($user))
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"]));
28
  do_action ("ws_plugin__s2member_before_login_redirect", get_defined_vars ());
29
  unset ($__refs, $__v); /* Unset defined __refs, __v. */
30
  /**/
31
+ $username = (!$username && is_object ($user = wp_get_current_user ())) ? $user->user_login : $username;
32
  /**/
33
+ if ($username && (is_object ($user) || is_object ($user = new WP_User ($username))) && ($user_id = $user->ID) && (!$user->has_cap ("edit_posts") || apply_filters ("ws_plugin__s2member_login_redirect", false, get_defined_vars ())))
34
  {
35
  if ($user->has_cap ("edit_posts") || strtolower ($username) === "demo" || c_ws_plugin__s2member_ip_restrictions::ip_restrictions_ok ($_SERVER["REMOTE_ADDR"], strtolower ($username)))
36
  {
38
  {
39
  if ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["custom_reg_password"]) /* Using custom Passwords? */
40
  {
41
+ delete_user_setting ("default_password_nag"); /* `setcookie()` */
42
  update_user_option ($user_id, "default_password_nag", false, true);
43
  }
44
  /**/
47
  unset ($__refs, $__v); /* Unset defined __refs, __v. */
48
  /**/
49
  if ($special_redirection_url = c_ws_plugin__s2member_login_redirects::login_redirection_url ($user))
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"]));
includes/classes/menu-pages.inc.php CHANGED
@@ -19,7 +19,7 @@ if (!class_exists ("c_ws_plugin__s2member_menu_pages"))
19
  class c_ws_plugin__s2member_menu_pages
20
  {
21
  /*
22
- Function that saves all options from any page.
23
  Options can also be passed in directly.
24
  Can also be self-verified.
25
  */
@@ -95,7 +95,7 @@ if (!class_exists ("c_ws_plugin__s2member_menu_pages"))
95
  return $updated_all_options; /* Return status update. */
96
  }
97
  /*
98
- Add the options menus & sub-menus.
99
  Attach to: add_action("admin_menu");
100
  */
101
  public static function add_admin_options ()
@@ -167,7 +167,7 @@ if (!class_exists ("c_ws_plugin__s2member_menu_pages"))
167
  return; /* Return for uniformity. */
168
  }
169
  /*
170
- Add the options menus & sub-menus.
171
  Attach to: add_action("network_admin_menu");
172
  */
173
  public static function add_network_admin_options ()
@@ -260,7 +260,7 @@ if (!class_exists ("c_ws_plugin__s2member_menu_pages"))
260
  return; /* Return for uniformity. */
261
  }
262
  /*
263
- Function for building and handling the Main Multisite Options page.
264
  */
265
  public static function mms_options_page ()
266
  {
@@ -278,7 +278,7 @@ if (!class_exists ("c_ws_plugin__s2member_menu_pages"))
278
  return; /* Return for uniformity. */
279
  }
280
  /*
281
- Function for building and handling the General Options page.
282
  */
283
  public static function options_page ()
284
  {
@@ -295,7 +295,7 @@ if (!class_exists ("c_ws_plugin__s2member_menu_pages"))
295
  return; /* Return for uniformity. */
296
  }
297
  /*
298
- Function for building and handling the Paypal Options page.
299
  */
300
  public static function paypal_ops_page ()
301
  {
@@ -337,7 +337,7 @@ if (!class_exists ("c_ws_plugin__s2member_menu_pages"))
337
  return; /* Return for uniformity. */
338
  }
339
  /*
340
- Function for building and handling the Download Options page.
341
  */
342
  public static function down_ops_page ()
343
  {
@@ -373,7 +373,7 @@ if (!class_exists ("c_ws_plugin__s2member_menu_pages"))
373
  return; /* Return for uniformity. */
374
  }
375
  /*
376
- Function for building and handling the API Tracking options page.
377
  */
378
  public static function trk_ops_page ()
379
  {
@@ -390,7 +390,7 @@ if (!class_exists ("c_ws_plugin__s2member_menu_pages"))
390
  return; /* Return for uniformity. */
391
  }
392
  /*
393
- Function for building and handling the API List Server options page.
394
  */
395
  public static function els_ops_page ()
396
  {
@@ -407,7 +407,7 @@ if (!class_exists ("c_ws_plugin__s2member_menu_pages"))
407
  return; /* Return for uniformity. */
408
  }
409
  /*
410
- Function for building and handling the API Notifications page.
411
  */
412
  public static function api_ops_page ()
413
  {
@@ -424,7 +424,7 @@ if (!class_exists ("c_ws_plugin__s2member_menu_pages"))
424
  return; /* Return for uniformity. */
425
  }
426
  /*
427
- Function for building the PayPal Button Generator page.
428
  */
429
  public static function paypal_buttons_page ()
430
  {
@@ -442,7 +442,7 @@ if (!class_exists ("c_ws_plugin__s2member_menu_pages"))
442
  return; /* Return for uniformity. */
443
  }
444
  /*
445
- Function for building the API Scripting page.
446
  */
447
  public static function scripting_page ()
448
  {
@@ -457,7 +457,7 @@ if (!class_exists ("c_ws_plugin__s2member_menu_pages"))
457
  return; /* Return for uniformity. */
458
  }
459
  /*
460
- Function for building the Bridge Integrations page.
461
  */
462
  public static function bridges_page ()
463
  {
@@ -476,8 +476,9 @@ if (!class_exists ("c_ws_plugin__s2member_menu_pages"))
476
  if (preg_match ("/^Install/i", $post["ws_plugin__s2member_bridge_bbpress_action"]))
477
  {
478
  $min = (string)$post["ws_plugin__s2member_bridge_bbpress_min_level"];
 
479
  /**/
480
- if (($file = file_get_contents (dirname (dirname (__FILE__)) . "/dropins/bridges/_s2member-bbpress-bridge.php")) && ($file = preg_replace ("/%%min%%/i", c_ws_plugin__s2member_utils_strings::esc_dq ($min), $file)) && file_put_contents ($plugins_dir . "/_s2member-bbpress-bridge.php", $file))
481
  c_ws_plugin__s2member_admin_notices::display_admin_notice ("The bbPress® Bridge/plugin has been <strong>installed successfully</strong>.");
482
  /**/
483
  else /* Otherwise, something unexpected. The site owner will need to install the bbPress® plugin manually. */
@@ -492,7 +493,7 @@ if (!class_exists ("c_ws_plugin__s2member_menu_pages"))
492
  c_ws_plugin__s2member_admin_notices::display_admin_notice ("Unknown error. Please try again, or un-install manually.", true);
493
  /**/
494
  else /* Otherwise, everything looks good. The plugin file has been removed successfully. */
495
- c_ws_plugin__s2member_admin_notices::display_admin_notice ("The bbPress® Bridge/plugin has been successfully <strong>un-installed</strong>.");
496
  }
497
  else
498
  c_ws_plugin__s2member_admin_notices::display_admin_notice ("The bbPress® Bridge/plugin is already un-installed.", true);
@@ -505,10 +506,10 @@ if (!class_exists ("c_ws_plugin__s2member_menu_pages"))
505
  c_ws_plugin__s2member_admin_notices::display_admin_notice ("The directory you specified does NOT exist. Please try again, or install manually.", true);
506
  }
507
  /**/
508
- if (!is_dir ($plugins_dir_guess = $_SERVER["DOCUMENT_ROOT"] . "/bbpress/my-plugins"))
509
- if (!is_dir ($plugins_dir_guess = $_SERVER["DOCUMENT_ROOT"] . "/forums/my-plugins"))
510
- if (!is_dir ($plugins_dir_guess = $_SERVER["DOCUMENT_ROOT"] . "/bbpress/bb-plugins"))
511
- if (!is_dir ($plugins_dir_guess = $_SERVER["DOCUMENT_ROOT"] . "/forums/bb-plugins"))
512
  $plugins_dir_guess = ($plugins_dir) ? $plugins_dir : $plugins_dir_guess;
513
  /**/
514
  $_bridge_bbpress_plugins_dir_guess = ($plugins_dir) ? $plugins_dir : $plugins_dir_guess;
@@ -520,7 +521,7 @@ if (!class_exists ("c_ws_plugin__s2member_menu_pages"))
520
  return; /* Return for uniformity. */
521
  }
522
  /*
523
- Function for building the s2Member Info page.
524
  */
525
  public static function info_page ()
526
  {
@@ -535,7 +536,7 @@ if (!class_exists ("c_ws_plugin__s2member_menu_pages"))
535
  return; /* Return for uniformity. */
536
  }
537
  /*
538
- Function for building and handling the Quick Start page.
539
  */
540
  public static function start_page ()
541
  {
19
  class c_ws_plugin__s2member_menu_pages
20
  {
21
  /*
22
+ Saves all options from any page.
23
  Options can also be passed in directly.
24
  Can also be self-verified.
25
  */
95
  return $updated_all_options; /* Return status update. */
96
  }
97
  /*
98
+ Adds the options menus & sub-menus.
99
  Attach to: add_action("admin_menu");
100
  */
101
  public static function add_admin_options ()
167
  return; /* Return for uniformity. */
168
  }
169
  /*
170
+ Adds the options menus & sub-menus.
171
  Attach to: add_action("network_admin_menu");
172
  */
173
  public static function add_network_admin_options ()
260
  return; /* Return for uniformity. */
261
  }
262
  /*
263
+ Builds and handles the Main Multisite Options page.
264
  */
265
  public static function mms_options_page ()
266
  {
278
  return; /* Return for uniformity. */
279
  }
280
  /*
281
+ Builds and handles the General Options page.
282
  */
283
  public static function options_page ()
284
  {
295
  return; /* Return for uniformity. */
296
  }
297
  /*
298
+ Builds and handles the Paypal Options page.
299
  */
300
  public static function paypal_ops_page ()
301
  {
337
  return; /* Return for uniformity. */
338
  }
339
  /*
340
+ Builds and handles the Download Options page.
341
  */
342
  public static function down_ops_page ()
343
  {
373
  return; /* Return for uniformity. */
374
  }
375
  /*
376
+ Builds and handles the API Tracking options page.
377
  */
378
  public static function trk_ops_page ()
379
  {
390
  return; /* Return for uniformity. */
391
  }
392
  /*
393
+ Builds and handles the API List Server options page.
394
  */
395
  public static function els_ops_page ()
396
  {
407
  return; /* Return for uniformity. */
408
  }
409
  /*
410
+ Builds and handles the API Notifications page.
411
  */
412
  public static function api_ops_page ()
413
  {
424
  return; /* Return for uniformity. */
425
  }
426
  /*
427
+ Builds and handles the PayPal Button Generator page.
428
  */
429
  public static function paypal_buttons_page ()
430
  {
442
  return; /* Return for uniformity. */
443
  }
444
  /*
445
+ Builds and handles the API Scripting page.
446
  */
447
  public static function scripting_page ()
448
  {
457
  return; /* Return for uniformity. */
458
  }
459
  /*
460
+ Builds and handles the Bridge Integrations page.
461
  */
462
  public static function bridges_page ()
463
  {
476
  if (preg_match ("/^Install/i", $post["ws_plugin__s2member_bridge_bbpress_action"]))
477
  {
478
  $min = (string)$post["ws_plugin__s2member_bridge_bbpress_min_level"];
479
+ $ovg = (string)$post["ws_plugin__s2member_bridge_bbpress_ovg"];
480
  /**/
481
+ if (($file = file_get_contents (dirname (dirname (__FILE__)) . "/dropins/bridges/_s2member-bbpress-bridge.php")) && ($file = preg_replace ("/%%min%%/i", c_ws_plugin__s2member_utils_strings::esc_dq ($min), preg_replace ("/%%ovg%%/i", c_ws_plugin__s2member_utils_strings::esc_dq ($ovg), $file))) && file_put_contents ($plugins_dir . "/_s2member-bbpress-bridge.php", $file))
482
  c_ws_plugin__s2member_admin_notices::display_admin_notice ("The bbPress® Bridge/plugin has been <strong>installed successfully</strong>.");
483
  /**/
484
  else /* Otherwise, something unexpected. The site owner will need to install the bbPress® plugin manually. */
493
  c_ws_plugin__s2member_admin_notices::display_admin_notice ("Unknown error. Please try again, or un-install manually.", true);
494
  /**/
495
  else /* Otherwise, everything looks good. The plugin file has been removed successfully. */
496
+ c_ws_plugin__s2member_admin_notices::display_admin_notice ("The bbPress® Bridge/plugin has been successfully <strong>uninstalled</strong>.");
497
  }
498
  else
499
  c_ws_plugin__s2member_admin_notices::display_admin_notice ("The bbPress® Bridge/plugin is already un-installed.", true);
506
  c_ws_plugin__s2member_admin_notices::display_admin_notice ("The directory you specified does NOT exist. Please try again, or install manually.", true);
507
  }
508
  /**/
509
+ if (!is_dir ($plugins_dir_guess = untrailingslashit ($_SERVER["DOCUMENT_ROOT"]) . "/bbpress/my-plugins"))
510
+ if (!is_dir ($plugins_dir_guess = untrailingslashit ($_SERVER["DOCUMENT_ROOT"]) . "/forums/my-plugins"))
511
+ if (!is_dir ($plugins_dir_guess = untrailingslashit ($_SERVER["DOCUMENT_ROOT"]) . "/bbpress/bb-plugins"))
512
+ if (!is_dir ($plugins_dir_guess = untrailingslashit ($_SERVER["DOCUMENT_ROOT"]) . "/forums/bb-plugins"))
513
  $plugins_dir_guess = ($plugins_dir) ? $plugins_dir : $plugins_dir_guess;
514
  /**/
515
  $_bridge_bbpress_plugins_dir_guess = ($plugins_dir) ? $plugins_dir : $plugins_dir_guess;
521
  return; /* Return for uniformity. */
522
  }
523
  /*
524
+ Builds and handles the s2Member Info page.
525
  */
526
  public static function info_page ()
527
  {
536
  return; /* Return for uniformity. */
537
  }
538
  /*
539
+ Builds and handles the Quick Start page.
540
  */
541
  public static function start_page ()
542
  {
includes/classes/op-notices.inc.php CHANGED
@@ -60,7 +60,7 @@ if (!class_exists ("c_ws_plugin__s2member_op_notices"))
60
  {
61
  if (version_compare (get_bloginfo ("version"), "3.1-RC", ">="))
62
  {
63
- $notice = "<em>* Note: The s2Member plugin has control over two options on this page.<br /><code>Allow Open Registration = " . esc_html (get_site_option ("registration")) . "</code> and <code>Add New Users = " . esc_html (get_site_option ("add_new_users")) . "</code>.<br />Please check: <code>s2Member -> Multisite ( Config )</code>.";
64
  /**/
65
  $js = '<script type="text/javascript">';
66
  $js .= "jQuery('input[name=registration], input#add_new_users').attr('disabled', 'disabled');";
60
  {
61
  if (version_compare (get_bloginfo ("version"), "3.1-RC", ">="))
62
  {
63
+ $notice = "<em>* Note: The s2Member plugin has control over two options on this page.<br /><code>Allow Open Registration = " . esc_html (get_site_option ("registration")) . "</code> and <code>Add New Users = " . esc_html (get_site_option ("add_new_users")) . "</code>.<br />Please check: <code>s2Member -> Multisite ( Config )</code>.";
64
  /**/
65
  $js = '<script type="text/javascript">';
66
  $js .= "jQuery('input[name=registration], input#add_new_users').attr('disabled', 'disabled');";
includes/classes/option-forces.inc.php CHANGED
@@ -117,26 +117,29 @@ if (!class_exists ("c_ws_plugin__s2member_option_forces"))
117
  /**/
118
  $by_default = $users_can_register = $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["mms_registration_grants"];
119
  /**/
120
- if (!is_multisite () || !c_ws_plugin__s2member_utils_conds::is_multisite_farm () || !is_main_site ()) /* NOT a Blog Farm. */
 
 
 
121
  return apply_filters ("ws_plugin__s2member_check_mms_register_access", ($users_can_register = "none"), get_defined_vars ());
122
  /**/
123
- else if (!is_admin () && $users_can_register !== "all") /* Do NOT run these security checks on option pages; it's confusing to a site owner. */
124
  {
125
  if (is_super_admin () || current_user_can ("create_users") || ( ($subscr_gateway = c_ws_plugin__s2member_utils_encryption::decrypt ($_COOKIE["s2member_subscr_gateway"])) && ($subscr_id = c_ws_plugin__s2member_utils_encryption::decrypt ($_COOKIE["s2member_subscr_id"])) && preg_match ("/^" . preg_quote (preg_replace ("/\:([0-9]+)$/", "", $_SERVER["HTTP_HOST"]), "/") . "/i", ($custom = c_ws_plugin__s2member_utils_encryption::decrypt ($_COOKIE["s2member_custom"]))) && preg_match ("/^[1-4](\:|$)([\+a-z_0-9,]+)?(\:)?([0-9]+ [A-Z])?$/", ($level = c_ws_plugin__s2member_utils_encryption::decrypt ($_COOKIE["s2member_level"]))) && ! ($exists = $wpdb->get_var ("SELECT `user_id` FROM `" . $wpdb->usermeta . "` WHERE `meta_key` = '" . $wpdb->prefix . "s2member_subscr_id' AND `meta_value` = '" . $wpdb->escape ($subscr_id) . "' LIMIT 1"))))
126
  {
127
- if (is_super_admin () || current_user_can ("create_users"))
128
  {
129
  return apply_filters ("ws_plugin__s2member_check_mms_register_access", ($users_can_register = "all"), get_defined_vars ());
130
  }
131
  else if ($subscr_gateway && $subscr_id && $custom && $level) /* A paying Customer? Cookies already authenticated above. */
132
  {
133
- list ($level) = preg_split ("/\:/", $level, 1); /* Parse out the level now. */
134
  /**/
135
- if ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["mms_registration_blogs_level" . $level])
136
  {
137
  return apply_filters ("ws_plugin__s2member_check_mms_register_access", ($users_can_register = "all"), get_defined_vars ());
138
  }
139
- else /* Otherwise, we MUST allow them to create an account; they paid for it! */
140
  {
141
  return apply_filters ("ws_plugin__s2member_check_mms_register_access", ($users_can_register = "user"), get_defined_vars ());
142
  }
117
  /**/
118
  $by_default = $users_can_register = $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["mms_registration_grants"];
119
  /**/
120
+ if (defined ("BP_VERSION") && is_multisite () && /* BP Multisite / but NOT offering Blogs? */ !c_ws_plugin__s2member_utils_conds::is_multisite_farm ())
121
+ return apply_filters ("ws_plugin__s2member_check_mms_register_access", ($users_can_register = ( (c_ws_plugin__s2member_option_forces::check_register_access ()) ? "user" : "none")), get_defined_vars ());
122
+ /**/
123
+ else if (!is_multisite () || !c_ws_plugin__s2member_utils_conds::is_multisite_farm () || !is_main_site ()) /* Blog Farm? */
124
  return apply_filters ("ws_plugin__s2member_check_mms_register_access", ($users_can_register = "none"), get_defined_vars ());
125
  /**/
126
+ else if (!is_admin () && $users_can_register !== "all") /* Do NOT run these checks on option pages; it's confusing to a site owner. */
127
  {
128
  if (is_super_admin () || current_user_can ("create_users") || ( ($subscr_gateway = c_ws_plugin__s2member_utils_encryption::decrypt ($_COOKIE["s2member_subscr_gateway"])) && ($subscr_id = c_ws_plugin__s2member_utils_encryption::decrypt ($_COOKIE["s2member_subscr_id"])) && preg_match ("/^" . preg_quote (preg_replace ("/\:([0-9]+)$/", "", $_SERVER["HTTP_HOST"]), "/") . "/i", ($custom = c_ws_plugin__s2member_utils_encryption::decrypt ($_COOKIE["s2member_custom"]))) && preg_match ("/^[1-4](\:|$)([\+a-z_0-9,]+)?(\:)?([0-9]+ [A-Z])?$/", ($level = c_ws_plugin__s2member_utils_encryption::decrypt ($_COOKIE["s2member_level"]))) && ! ($exists = $wpdb->get_var ("SELECT `user_id` FROM `" . $wpdb->usermeta . "` WHERE `meta_key` = '" . $wpdb->prefix . "s2member_subscr_id' AND `meta_value` = '" . $wpdb->escape ($subscr_id) . "' LIMIT 1"))))
129
  {
130
+ if (is_super_admin () || current_user_can ("create_users")) /* Either a Super Administrator, or an Administrator that can create. */
131
  {
132
  return apply_filters ("ws_plugin__s2member_check_mms_register_access", ($users_can_register = "all"), get_defined_vars ());
133
  }
134
  else if ($subscr_gateway && $subscr_id && $custom && $level) /* A paying Customer? Cookies already authenticated above. */
135
  {
136
+ list ($level) = preg_split ("/\:/", $level, 1); /* Parse out the Membership Level now. We'll need this below. */
137
  /**/
138
+ if ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["mms_registration_blogs_level" . $level]) /* Blog(s) allowed? */
139
  {
140
  return apply_filters ("ws_plugin__s2member_check_mms_register_access", ($users_can_register = "all"), get_defined_vars ());
141
  }
142
+ else /* Otherwise, we MUST allow them to at least create an account; they paid for it! Defaults to `user`. */
143
  {
144
  return apply_filters ("ws_plugin__s2member_check_mms_register_access", ($users_can_register = "user"), get_defined_vars ());
145
  }
includes/classes/paypal-notify-in.inc.php CHANGED
@@ -40,7 +40,7 @@ if (!class_exists ("c_ws_plugin__s2member_paypal_notify_in"))
40
  /**/
41
  if ($_GET["s2member_paypal_notify"] && ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["paypal_business"] || $_GET["s2member_paypal_proxy"]))
42
  {
43
- ignore_user_abort(true); /* Important. Continue processing even if/when the connection is broken by the sending party. */
44
  /**/
45
  include_once ABSPATH . "wp-admin/includes/admin.php"; /* Get administrative functions. Needed for `wp_delete_user()`. */
46
  /**/
@@ -403,7 +403,7 @@ if (!class_exists ("c_ws_plugin__s2member_paypal_notify_in"))
403
  /**/
404
  eval ('foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;');
405
  do_action ("ws_plugin__s2member_during_paypal_notify_during_before_subscr_signup_w_update_vars", get_defined_vars ());
406
- do_action ("ws_plugin__s2member_during_collective_mods", $user_id, get_defined_vars (), "ipn-upgrade-downgrade", $paypal["level"]);
407
  unset ($__refs, $__v); /* Unset defined __refs, __v. */
408
  /**/
409
  $fields = get_user_option ("s2member_custom_fields", $user_id);
@@ -861,7 +861,7 @@ if (!class_exists ("c_ws_plugin__s2member_paypal_notify_in"))
861
  /**/
862
  eval ('foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;');
863
  do_action ("ws_plugin__s2member_during_paypal_notify_during_before_subscr_modify", get_defined_vars ());
864
- do_action ("ws_plugin__s2member_during_collective_mods", $user_id, get_defined_vars (), "ipn-upgrade-downgrade", $paypal["level"]);
865
  unset ($__refs, $__v); /* Unset defined __refs, __v. */
866
  /**/
867
  $fields = get_user_option ("s2member_custom_fields", $user_id);
@@ -1312,9 +1312,12 @@ if (!class_exists ("c_ws_plugin__s2member_paypal_notify_in"))
1312
  {
1313
  $processing = $during = true; /* Yes, we ARE processing this. */
1314
  /**/
 
 
 
1315
  eval ('foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;');
1316
  do_action ("ws_plugin__s2member_during_paypal_notify_during_subscr_eot_before_demote", get_defined_vars ());
1317
- do_action ("ws_plugin__s2member_during_collective_eots", $user_id, get_defined_vars (), "ipn-refund-reversal-demotion");
1318
  unset ($__refs, $__v); /* Unset defined __refs, __v. */
1319
  /**/
1320
  $demotion_role = c_ws_plugin__s2member_option_forces::force_demotion_role ("subscriber");
@@ -1351,7 +1354,7 @@ if (!class_exists ("c_ws_plugin__s2member_paypal_notify_in"))
1351
  {
1352
  foreach (preg_split ("/[\r\n\t]+/", $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["eot_del_notification_urls"]) as $url) /* Handle EOT Notifications. */
1353
  /**/
1354
- 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)))
1355
  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)))
1356
  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)))
1357
  if (($url = preg_replace ("/%%user_email%%/i", c_ws_plugin__s2member_utils_strings::esc_ds (urlencode ($user->user_email)), $url)))
@@ -1375,6 +1378,7 @@ if (!class_exists ("c_ws_plugin__s2member_paypal_notify_in"))
1375
  $msg = $sbj = "( s2Member / API Notification Email ) - EOT/Deletion";
1376
  $msg .= "\n\n"; /* Spacing in the message body. */
1377
  /**/
 
1378
  $msg .= "subscr_id: %%subscr_id%%\n";
1379
  $msg .= "user_first_name: %%user_first_name%%\n";
1380
  $msg .= "user_last_name: %%user_last_name%%\n";
@@ -1398,7 +1402,7 @@ if (!class_exists ("c_ws_plugin__s2member_paypal_notify_in"))
1398
  $msg .= "cv8: %%cv8%%\n";
1399
  $msg .= "cv9: %%cv9%%";
1400
  /**/
1401
- 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)))
1402
  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)))
1403
  if (($msg = preg_replace ("/%%user_full_name%%/i", c_ws_plugin__s2member_utils_strings::esc_ds (trim ($user->first_name . " " . $user->last_name)), $msg)))
1404
  if (($msg = preg_replace ("/%%user_email%%/i", c_ws_plugin__s2member_utils_strings::esc_ds ($user->user_email), $msg)))
@@ -1427,11 +1431,17 @@ if (!class_exists ("c_ws_plugin__s2member_paypal_notify_in"))
1427
  {
1428
  $processing = $during = true; /* Yes, we ARE processing this. */
1429
  /**/
 
 
 
1430
  eval ('foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;');
1431
  do_action ("ws_plugin__s2member_during_paypal_notify_during_subscr_eot_before_delete", get_defined_vars ());
1432
- do_action ("ws_plugin__s2member_during_collective_eots", $user_id, get_defined_vars (), "ipn-refund-reversal-deletion");
1433
  unset ($__refs, $__v); /* Unset defined __refs, __v. */
1434
  /**/
 
 
 
1435
  if (is_multisite ()) /* Multisite does NOT actually delete; ONLY removes. */
1436
  {
1437
  remove_user_from_blog ($user_id, $current_blog->blog_id);
@@ -1441,7 +1451,7 @@ if (!class_exists ("c_ws_plugin__s2member_paypal_notify_in"))
1441
  /**/
1442
  else /* Otherwise, we can actually delete them. */
1443
  /* This will automatically trigger `eot_del_notification_urls` as well. */
1444
- wp_delete_user($user_id); /* `c_ws_plugin__s2member_user_deletions::handle_user_deletions()` */
1445
  /**/
1446
  $paypal["s2member_log"][] = "This Member's account has been " . ( (is_multisite ()) ? "removed" : "deleted") . ".";
1447
  /**/
40
  /**/
41
  if ($_GET["s2member_paypal_notify"] && ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["paypal_business"] || $_GET["s2member_paypal_proxy"]))
42
  {
43
+ @ignore_user_abort (true); /* Important. Continue processing even if/when the connection is broken by the sending party. */
44
  /**/
45
  include_once ABSPATH . "wp-admin/includes/admin.php"; /* Get administrative functions. Needed for `wp_delete_user()`. */
46
  /**/
403
  /**/
404
  eval ('foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;');
405
  do_action ("ws_plugin__s2member_during_paypal_notify_during_before_subscr_signup_w_update_vars", get_defined_vars ());
406
+ do_action ("ws_plugin__s2member_during_collective_mods", $user_id, get_defined_vars (), "ipn-upgrade-downgrade", "modification", $paypal["level"]);
407
  unset ($__refs, $__v); /* Unset defined __refs, __v. */
408
  /**/
409
  $fields = get_user_option ("s2member_custom_fields", $user_id);
861
  /**/
862
  eval ('foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;');
863
  do_action ("ws_plugin__s2member_during_paypal_notify_during_before_subscr_modify", get_defined_vars ());
864
+ do_action ("ws_plugin__s2member_during_collective_mods", $user_id, get_defined_vars (), "ipn-upgrade-downgrade", "modification", $paypal["level"]);
865
  unset ($__refs, $__v); /* Unset defined __refs, __v. */
866
  /**/
867
  $fields = get_user_option ("s2member_custom_fields", $user_id);
1312
  {
1313
  $processing = $during = true; /* Yes, we ARE processing this. */
1314
  /**/
1315
+ $eot_del_type = ($is_refund_or_reversal) ? "ipn-refund-reversal-demotion" : "ipn-cancellation-expiration-demotion";
1316
+ $eot_del_type_spec = ($is_refund_or_reversal) ? "refund-reversal" : "cancellation-expiration";
1317
+ /**/
1318
  eval ('foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;');
1319
  do_action ("ws_plugin__s2member_during_paypal_notify_during_subscr_eot_before_demote", get_defined_vars ());
1320
+ do_action ("ws_plugin__s2member_during_collective_eots", $user_id, get_defined_vars (), $eot_del_type, $eot_del_type_spec);
1321
  unset ($__refs, $__v); /* Unset defined __refs, __v. */
1322
  /**/
1323
  $demotion_role = c_ws_plugin__s2member_option_forces::force_demotion_role ("subscriber");
1354
  {
1355
  foreach (preg_split ("/[\r\n\t]+/", $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["eot_del_notification_urls"]) as $url) /* Handle EOT Notifications. */
1356
  /**/
1357
+ if (($url = preg_replace ("/%%cv([0-9]+)%%/ei", 'urlencode(trim($cv[$1]))', $url)) && ($url = preg_replace ("/%%eot_del_type%%/i", c_ws_plugin__s2member_utils_strings::esc_ds (urlencode ($eot_del_type)), $url)) && ($url = preg_replace ("/%%subscr_id%%/i", c_ws_plugin__s2member_utils_strings::esc_ds (urlencode ($paypal["subscr_id"])), $url)))
1358
  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)))
1359
  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)))
1360
  if (($url = preg_replace ("/%%user_email%%/i", c_ws_plugin__s2member_utils_strings::esc_ds (urlencode ($user->user_email)), $url)))
1378
  $msg = $sbj = "( s2Member / API Notification Email ) - EOT/Deletion";
1379
  $msg .= "\n\n"; /* Spacing in the message body. */
1380
  /**/
1381
+ $msg .= "eot_del_type: %%eot_del_type%%\n";
1382
  $msg .= "subscr_id: %%subscr_id%%\n";
1383
  $msg .= "user_first_name: %%user_first_name%%\n";
1384
  $msg .= "user_last_name: %%user_last_name%%\n";
1402
  $msg .= "cv8: %%cv8%%\n";
1403
  $msg .= "cv9: %%cv9%%";
1404
  /**/
1405
+ if (($msg = preg_replace ("/%%cv([0-9]+)%%/ei", 'trim($cv[$1])', $msg)) && ($msg = preg_replace ("/%%eot_del_type%%/i", c_ws_plugin__s2member_utils_strings::esc_ds ($eot_del_type), $msg)) && ($msg = preg_replace ("/%%subscr_id%%/i", c_ws_plugin__s2member_utils_strings::esc_ds ($paypal["subscr_id"]), $msg)))
1406
  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)))
1407
  if (($msg = preg_replace ("/%%user_full_name%%/i", c_ws_plugin__s2member_utils_strings::esc_ds (trim ($user->first_name . " " . $user->last_name)), $msg)))
1408
  if (($msg = preg_replace ("/%%user_email%%/i", c_ws_plugin__s2member_utils_strings::esc_ds ($user->user_email), $msg)))
1431
  {
1432
  $processing = $during = true; /* Yes, we ARE processing this. */
1433
  /**/
1434
+ $eot_del_type = ($is_refund_or_reversal) ? "ipn-refund-reversal-deletion" : "ipn-cancellation-expiration-deletion";
1435
+ $eot_del_type_spec = ($is_refund_or_reversal) ? "refund-reversal" : "cancellation-expiration";
1436
+ /**/
1437
  eval ('foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;');
1438
  do_action ("ws_plugin__s2member_during_paypal_notify_during_subscr_eot_before_delete", get_defined_vars ());
1439
+ do_action ("ws_plugin__s2member_during_collective_eots", $user_id, get_defined_vars (), $eot_del_type, $eot_del_type_spec);
1440
  unset ($__refs, $__v); /* Unset defined __refs, __v. */
1441
  /**/
1442
+ $GLOBALS["ws_plugin__s2member_eot_del_type"] = $eot_del_type;
1443
+ $GLOBALS["ws_plugin__s2member_eot_del_type_spec"] = $eot_del_type_spec;
1444
+ /**/
1445
  if (is_multisite ()) /* Multisite does NOT actually delete; ONLY removes. */
1446
  {
1447
  remove_user_from_blog ($user_id, $current_blog->blog_id);
1451
  /**/
1452
  else /* Otherwise, we can actually delete them. */
1453
  /* This will automatically trigger `eot_del_notification_urls` as well. */
1454
+ wp_delete_user ($user_id); /* `c_ws_plugin__s2member_user_deletions::handle_user_deletions()` */
1455
  /**/
1456
  $paypal["s2member_log"][] = "This Member's account has been " . ( (is_multisite ()) ? "removed" : "deleted") . ".";
1457
  /**/
includes/classes/paypal-return-in.inc.php CHANGED
@@ -47,7 +47,7 @@ if (!class_exists ("c_ws_plugin__s2member_paypal_return_in"))
47
  email address. In cases where an alternate PayPal® address is being paid, validation was not possible. */
48
  $paypal["s2member_log"][] = "s2Member originating domain ( _SERVER[HTTP_HOST] ) validated.";
49
  /*
50
- Custom conditionals can be applied by filters.
51
  */
52
  eval ('foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;');
53
  if (!apply_filters ("ws_plugin__s2member_during_paypal_return_conditionals", false, get_defined_vars ()))
@@ -98,7 +98,7 @@ if (!class_exists ("c_ws_plugin__s2member_paypal_return_in"))
98
  /**/
99
  $paypal["s2member_log"][] = "Redirecting Customer to the Specific Post/Page.";
100
  /**/
101
- wp_redirect ($sp_access_url); /* Redirect Customer immediately. */
102
  }
103
  else /* Otherwise, the ID must have been invalid. Or the Post/Page was deleted. */
104
  {
@@ -201,12 +201,24 @@ if (!class_exists ("c_ws_plugin__s2member_paypal_return_in"))
201
  do_action ("ws_plugin__s2member_during_paypal_return_during_subscr_signup_w_update_vars", get_defined_vars ());
202
  unset ($__refs, $__v); /* Unset defined __refs, __v. */
203
  /**/
204
- $paypal["s2member_log"][] = "Redirecting Customer to the Login Page. They need to log back in after this modification.";
205
- /**/
206
- echo '<script type="text/javascript">' . "\n";
207
- echo "alert('Thank you! You\\'ve been updated to:\\n\\n" . esc_js ($paypal["item_name"]) . "\\n\\nPlease log back in now.');" . "\n";
208
- echo "window.location = '" . esc_js (wp_login_url ()) . "';" . "\n";
209
- echo '</script>' . "\n";
 
 
 
 
 
 
 
 
 
 
 
 
210
  }
211
  else
212
  {
@@ -264,15 +276,15 @@ if (!class_exists ("c_ws_plugin__s2member_paypal_return_in"))
264
  /**/
265
  if (is_multisite () && c_ws_plugin__s2member_utils_conds::is_multisite_farm () && is_main_site ())
266
  {
267
- echo '<script type="text/javascript">' . "\n";
268
- echo "alert('Thank you! Your account has been approved.\\nThe next step is to Register.\\n\\nPlease click OK to Register now.');" . "\n";/**/
269
- echo "window.location = '" . esc_js (c_ws_plugin__s2member_utils_urls::wp_signup_url ()) . "';" . "\n";
270
  echo '</script>' . "\n";
271
  }
272
  else /* Otherwise, this is NOT a Multisite install. Or it is, but the Super Administrator is NOT selling Blog creation. */
273
  {
274
- echo '<script type="text/javascript">' . "\n";
275
- echo "alert('Thank you! Your account has been approved.\\nThe next step is to Register a Username.\\n\\nPlease click OK to Register now.');" . "\n";/**/
276
  echo "window.location = '" . esc_js (c_ws_plugin__s2member_utils_urls::wp_register_url ()) . "';" . "\n";
277
  echo '</script>' . "\n";
278
  }
@@ -349,12 +361,24 @@ if (!class_exists ("c_ws_plugin__s2member_paypal_return_in"))
349
  do_action ("ws_plugin__s2member_during_paypal_return_during_subscr_modify", get_defined_vars ());
350
  unset ($__refs, $__v); /* Unset defined __refs, __v. */
351
  /**/
352
- $paypal["s2member_log"][] = "Redirecting Customer to the Login Page. They need to log back in after this modification.";
353
- /**/
354
- echo '<script type="text/javascript">' . "\n";
355
- echo "alert('Thank you! You\\'ve been updated to:\\n\\n" . esc_js ($paypal["item_name"]) . "\\n\\nPlease log back in now.');" . "\n";
356
- echo "window.location = '" . esc_js (wp_login_url ()) . "';";
357
- echo '</script>' . "\n";
 
 
 
 
 
 
 
 
 
 
 
 
358
  }
359
  else
360
  {
@@ -436,7 +460,7 @@ if (!class_exists ("c_ws_plugin__s2member_paypal_return_in"))
436
  unset ($__refs, $__v); /* Unset defined __refs, __v. */
437
  }
438
  }
439
- else if (!isset ($_GET["tx"]) && (empty ($_POST) || $_POST["auth"]))
440
  {
441
  eval ('foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;');
442
  do_action ("ws_plugin__s2member_during_paypal_return_before_no_return_data", get_defined_vars ());
47
  email address. In cases where an alternate PayPal® address is being paid, validation was not possible. */
48
  $paypal["s2member_log"][] = "s2Member originating domain ( _SERVER[HTTP_HOST] ) validated.";
49
  /*
50
+ Custom conditionals can be applied by Filters.
51
  */
52
  eval ('foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;');
53
  if (!apply_filters ("ws_plugin__s2member_during_paypal_return_conditionals", false, get_defined_vars ()))
98
  /**/
99
  $paypal["s2member_log"][] = "Redirecting Customer to the Specific Post/Page.";
100
  /**/
101
+ wp_redirect($sp_access_url); /* Redirect Customer to the Specific Post/Page. */
102
  }
103
  else /* Otherwise, the ID must have been invalid. Or the Post/Page was deleted. */
104
  {
201
  do_action ("ws_plugin__s2member_during_paypal_return_during_subscr_signup_w_update_vars", get_defined_vars ());
202
  unset ($__refs, $__v); /* Unset defined __refs, __v. */
203
  /**/
204
+ if ($redirection_url_after_modification = apply_filters ("ws_plugin__s2member_redirection_url_after_modification", false, get_defined_vars ()))
205
+ {
206
+ $paypal["s2member_log"][] = "Redirecting this Member to a custom URL after modification: " . $redirection_url_after_modification;
207
+ /**/
208
+ echo '<script type="text/javascript">' . "\n";
209
+ echo "alert('Thank you! You\\'ve been updated to:\\n\\n" . esc_js ($paypal["item_name"]) . "');" . "\n";
210
+ echo "window.location = '" . esc_js ($redirection_url_after_modification) . "';" . "\n";
211
+ echo '</script>' . "\n";
212
+ }
213
+ else /* Else, use standard/default handling in this scenario. Have the Customer log in again. */
214
+ {
215
+ $paypal["s2member_log"][] = "Redirecting Customer to the Login Page. They need to log back in.";
216
+ /**/
217
+ echo '<script type="text/javascript">' . "\n";
218
+ echo "alert('Thank you! You\\'ve been updated to:\\n\\n" . esc_js ($paypal["item_name"]) . "');" . "\n";
219
+ echo "window.location = '" . esc_js (wp_login_url ()) . "';" . "\n";
220
+ echo '</script>' . "\n";
221
+ }
222
  }
223
  else
224
  {
276
  /**/
277
  if (is_multisite () && c_ws_plugin__s2member_utils_conds::is_multisite_farm () && is_main_site ())
278
  {
279
+ echo '<script type="text/javascript">' . "\n"; /* This default location can be Filtered in WP with: `wp_signup_location`. */
280
+ echo "alert('Thank you! Your account has been approved.\\nThe next step is to Register.\\n\\nPlease click OK to Register now.');" . "\n";
281
+ echo "window.location = '" . esc_js (c_ws_plugin__s2member_utils_urls::wp_signup_url ()) . "';" . "\n"; /* Filterable. */
282
  echo '</script>' . "\n";
283
  }
284
  else /* Otherwise, this is NOT a Multisite install. Or it is, but the Super Administrator is NOT selling Blog creation. */
285
  {
286
+ echo '<script type="text/javascript">' . "\n"; /* This location can be Filtered with: `wp_register_location`. */
287
+ echo "alert('Thank you! Your account has been approved.\\nThe next step is to Register a Username.\\n\\nPlease click OK to Register now.');" . "\n";
288
  echo "window.location = '" . esc_js (c_ws_plugin__s2member_utils_urls::wp_register_url ()) . "';" . "\n";
289
  echo '</script>' . "\n";
290
  }
361
  do_action ("ws_plugin__s2member_during_paypal_return_during_subscr_modify", get_defined_vars ());
362
  unset ($__refs, $__v); /* Unset defined __refs, __v. */
363
  /**/
364
+ if ($redirection_url_after_modification = apply_filters ("ws_plugin__s2member_redirection_url_after_modification", false, get_defined_vars ()))
365
+ {
366
+ $paypal["s2member_log"][] = "Redirecting this Member to a custom URL after modification: " . $redirection_url_after_modification;
367
+ /**/
368
+ echo '<script type="text/javascript">' . "\n";
369
+ echo "alert('Thank you! You\\'ve been updated to:\\n\\n" . esc_js ($paypal["item_name"]) . "');" . "\n";
370
+ echo "window.location = '" . esc_js ($redirection_url_after_modification) . "';";
371
+ echo '</script>' . "\n";
372
+ }
373
+ else /* Else, use standard/default handling in this scenario. Have the Customer log in again. */
374
+ {
375
+ $paypal["s2member_log"][] = "Redirecting Customer to the Login Page. They need to log back in.";
376
+ /**/
377
+ echo '<script type="text/javascript">' . "\n";
378
+ echo "alert('Thank you! You\\'ve been updated to:\\n\\n" . esc_js ($paypal["item_name"]) . "');" . "\n";
379
+ echo "window.location = '" . esc_js (wp_login_url ()) . "';";
380
+ echo '</script>' . "\n";
381
+ }
382
  }
383
  else
384
  {
460
  unset ($__refs, $__v); /* Unset defined __refs, __v. */
461
  }
462
  }
463
+ else if (!isset ($_GET["tx"])) /* No Return-Data from PayPal® at all? */
464
  {
465
  eval ('foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;');
466
  do_action ("ws_plugin__s2member_during_paypal_return_before_no_return_data", get_defined_vars ());
includes/classes/register-access.inc.php CHANGED
@@ -32,8 +32,12 @@ if (!class_exists ("c_ws_plugin__s2member_register_access"))
32
  $register = c_ws_plugin__s2member_utils_encryption::encrypt ("subscr_gateway_subscr_id_custom_item_number_time:.:|:.:" . $subscr_gateway . ":.:|:.:" . $subscr_id . ":.:|:.:" . $custom . ":.:|:.:" . $item_number . ":.:|:.:" . strtotime ("now"));
33
  $register_link = site_url ("/?s2member_register=" . urlencode ($register));
34
  /**/
35
- if ($shrink && ($tinyurl = c_ws_plugin__s2member_utils_urls::remote ("http://tinyurl.com/api-create.php?url=" . rawurlencode ($register_link))))
 
 
 
36
  return apply_filters ("ws_plugin__s2member_register_link_gen", $tinyurl . "#" . $_SERVER["HTTP_HOST"], get_defined_vars ());
 
37
  else /* Else use the long one; tinyURL will fail when/if their server is down periodically. */
38
  return apply_filters ("ws_plugin__s2member_register_link_gen", $register_link, get_defined_vars ());
39
  }
32
  $register = c_ws_plugin__s2member_utils_encryption::encrypt ("subscr_gateway_subscr_id_custom_item_number_time:.:|:.:" . $subscr_gateway . ":.:|:.:" . $subscr_id . ":.:|:.:" . $custom . ":.:|:.:" . $item_number . ":.:|:.:" . strtotime ("now"));
33
  $register_link = site_url ("/?s2member_register=" . urlencode ($register));
34
  /**/
35
+ if ($shrink && ($_alternative = apply_filters ("ws_plugin__s2member_register_link_gen_alternative", $register_link, get_defined_vars ())) && strlen ($_alternative) < strlen ($register_link))
36
+ return apply_filters ("ws_plugin__s2member_register_link_gen", $_alternative, get_defined_vars ());
37
+ /**/
38
+ else if ($shrink && ($tinyurl = c_ws_plugin__s2member_utils_urls::remote ("http://tinyurl.com/api-create.php?url=" . rawurlencode ($register_link))))
39
  return apply_filters ("ws_plugin__s2member_register_link_gen", $tinyurl . "#" . $_SERVER["HTTP_HOST"], get_defined_vars ());
40
+ /**/
41
  else /* Else use the long one; tinyURL will fail when/if their server is down periodically. */
42
  return apply_filters ("ws_plugin__s2member_register_link_gen", $register_link, get_defined_vars ());
43
  }
includes/classes/registrations.inc.php CHANGED
@@ -337,8 +337,8 @@ if (!class_exists ("c_ws_plugin__s2member_registrations"))
337
  if (!is_admin () && ($post["ws_plugin__s2member_custom_reg_field_s2member_subscr_gateway"] || $post["ws_plugin__s2member_custom_reg_field_s2member_subscr_id"] || $post["ws_plugin__s2member_custom_reg_field_s2member_custom"] || $post["ws_plugin__s2member_custom_reg_field_s2member_ccaps"] || $post["ws_plugin__s2member_custom_reg_field_s2member_auto_eot_time"] || $post["ws_plugin__s2member_custom_reg_field_s2member_notes"]))
338
  exit ("s2Member security violation. You attempted to POST administrative variables that will NOT be trusted in a NON-administrative zone!");
339
  /**/
340
- $_pm = array_merge ((array)$post, (array)$meta); /* Merge these two data sources together now; ALWAYS after the security routine above ^. */
341
- unset ($post, $meta); /* These can be unset now; no longer needed ( we use $_pm instead, it's a combination of the two arrays ). */
342
  /**/
343
  if (!is_admin () /* Only run this particular routine whenever a Member Level [1-4] is registering themselves with paid authorization cookies in their browser. */
344
  && ($subscr_gateway = c_ws_plugin__s2member_utils_encryption::decrypt ($_COOKIE["s2member_subscr_gateway"])) && ($subscr_id = c_ws_plugin__s2member_utils_encryption::decrypt ($_COOKIE["s2member_subscr_id"])) && preg_match ("/^" . preg_quote (preg_replace ("/\:([0-9]+)$/", "", $_SERVER["HTTP_HOST"]), "/") . "/i", ($custom = c_ws_plugin__s2member_utils_encryption::decrypt ($_COOKIE["s2member_custom"]))) && preg_match ("/^[1-4](\:|$)([\+a-z_0-9,]+)?(\:)?([0-9]+ [A-Z])?$/", ($level = c_ws_plugin__s2member_utils_encryption::decrypt ($_COOKIE["s2member_level"])))/**/
@@ -353,7 +353,7 @@ if (!class_exists ("c_ws_plugin__s2member_registrations"))
353
  /**/
354
  $current_role = c_ws_plugin__s2member_user_access::user_access_role ($user);
355
  list ($level, $ccaps, $eotper) = preg_split ("/\:/", $level, 3);
356
- $role = "s2member_level" . $level; /* Level 1-4. */
357
  /**/
358
  $email = $user->user_email;
359
  $login = $user->user_login;
@@ -363,26 +363,26 @@ if (!class_exists ("c_ws_plugin__s2member_registrations"))
363
  if ($eotper) /* If a specific EOT Period has been attached; calculate that now. */
364
  $auto_eot_time = c_ws_plugin__s2member_utils_time::auto_eot_time ("", "", "", $eotper);
365
  /**/
366
- $notes = $_pm["ws_plugin__s2member_custom_reg_field_s2member_notes"];
367
  /**/
368
  $opt_in = (!$GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["custom_reg_opt_in"]) ? true : false;
369
- $opt_in = (!$opt_in && $_pm["ws_plugin__s2member_custom_reg_field_opt_in"]) ? true : $opt_in;
370
  /**/
371
  if (! ($fname = $user->first_name))
372
- if ($_pm["ws_plugin__s2member_custom_reg_field_first_name"])
373
- $fname = $_pm["ws_plugin__s2member_custom_reg_field_first_name"];
374
  /**/
375
  if (!$fname) /* Also try BuddyPress. */
376
- if ($_pm["field_1"]) /* BuddyPress. */
377
- $fname = trim (preg_replace ("/ (.*)$/", "", $_pm["field_1"]));
378
  /**/
379
  if (! ($lname = $user->last_name))
380
- if ($_pm["ws_plugin__s2member_custom_reg_field_last_name"])
381
- $lname = $_pm["ws_plugin__s2member_custom_reg_field_last_name"];
382
  /**/
383
  if (!$lname) /* Also try BuddyPress. */
384
- if ($_pm["field_1"] && preg_match ("/^(.+?) (.+)$/", $_pm["field_1"]))
385
- $lname = trim (preg_replace ("/^(.+?) (.+)$/", "$2", $_pm["field_1"]));
386
  /**/
387
  $name = trim ($fname . " " . $lname); /* Both names. */
388
  /**/
@@ -391,8 +391,8 @@ if (!class_exists ("c_ws_plugin__s2member_registrations"))
391
  $pass = $GLOBALS["ws_plugin__s2member_generate_password_return"];
392
  /**/
393
  if (!$pass) /* Also try BuddyPress Password. */
394
- if ($_pm["signup_password"]) /* BuddyPress. */
395
- $pass = $_pm["signup_password"];
396
  /**/
397
  if ($pass) /* No Password nag. Update this globally. */
398
  {
@@ -441,8 +441,8 @@ if (!class_exists ("c_ws_plugin__s2member_registrations"))
441
  $field_var = preg_replace ("/[^a-z0-9]/i", "_", strtolower ($field["id"]));
442
  $field_id_class = preg_replace ("/_/", "-", $field_var);
443
  /**/
444
- if (isset ($_pm["ws_plugin__s2member_custom_reg_field_" . $field_var]))
445
- $fields[$field_var] = $_pm["ws_plugin__s2member_custom_reg_field_" . $field_var];
446
  }
447
  /**/
448
  update_user_option ($user_id, "s2member_custom_fields", $fields);
@@ -477,52 +477,54 @@ if (!class_exists ("c_ws_plugin__s2member_registrations"))
477
  }
478
  /**/
479
  else if (!is_admin ()) /* Otherwise, if we are NOT inside the Dashboard during the creation of this account. */
480
- { /*
481
- This routine could be processed through `wp-login.php?action=register`, `wp-activate.php`, or `/activate` via BuddyPress`.
482
  This may also be processed through a standard BuddyPress installation, or another plugin calling `user_register`.
483
  If processed through `wp-activate.php`, it could've originated inside the admin, via `user-new.php`.
484
  */
485
  $processed = "yes"; /* Mark this as yes, to indicate that a routine was processed. */
486
  /**/
487
- $role = ($current_role = c_ws_plugin__s2member_user_access::user_access_role ($user));
 
 
488
  $role = (!$role) ? get_option ("default_role") : $role; /* Otherwise default. */
489
  /**/
490
- $level = (preg_match ("/^(administrator|editor|author|contributor)$/i", $role)) ? "4" : $level;
 
491
  $level = (!$level && preg_match ("/^s2member_level[1-4]$/i", $role)) ? preg_replace ("/^s2member_level/", "", $role) : $level;
492
  $level = (!$level && preg_match ("/^subscriber$/i", $role)) ? "0" : $level;
493
  $level = (!$level) ? "0" : $level;
494
  /**/
495
- $ccaps = $_pm["ws_plugin__s2member_custom_reg_field_s2member_ccaps"];
496
  /**/
497
  $email = $user->user_email;
498
  $login = $user->user_login;
499
  $ip = $_SERVER["REMOTE_ADDR"];
500
- $custom = $_pm["ws_plugin__s2member_custom_reg_field_s2member_custom"];
501
- $subscr_id = $_pm["ws_plugin__s2member_custom_reg_field_s2member_subscr_id"];
502
- $subscr_gateway = $_pm["ws_plugin__s2member_custom_reg_field_s2member_subscr_gateway"];
503
- $cv = preg_split ("/\|/", $_pm["ws_plugin__s2member_custom_reg_field_s2member_custom"]);
504
  /**/
505
- $auto_eot_time = ($eot = $_pm["ws_plugin__s2member_custom_reg_field_s2member_auto_eot_time"]) ? strtotime ($eot) : "";
506
- $notes = $_pm["ws_plugin__s2member_custom_reg_field_s2member_notes"];
507
  /**/
508
  $opt_in = (!$GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["custom_reg_opt_in"]) ? true : false;
509
- $opt_in = (!$opt_in && $_pm["ws_plugin__s2member_custom_reg_field_opt_in"]) ? true : $opt_in;
510
  /**/
511
  if (! ($fname = $user->first_name))
512
- if ($_pm["ws_plugin__s2member_custom_reg_field_first_name"])
513
- $fname = $_pm["ws_plugin__s2member_custom_reg_field_first_name"];
514
  /**/
515
  if (!$fname) /* Also try BuddyPress. */
516
- if ($_pm["field_1"]) /* BuddyPress. */
517
- $fname = trim (preg_replace ("/ (.*)$/", "", $_pm["field_1"]));
518
  /**/
519
  if (! ($lname = $user->last_name))
520
- if ($_pm["ws_plugin__s2member_custom_reg_field_last_name"])
521
- $lname = $_pm["ws_plugin__s2member_custom_reg_field_last_name"];
522
  /**/
523
  if (!$lname) /* Also try BuddyPress. */
524
- if ($_pm["field_1"] && preg_match ("/^(.+?) (.+)$/", $_pm["field_1"]))
525
- $lname = trim (preg_replace ("/^(.+?) (.+)$/", "$2", $_pm["field_1"]));
526
  /**/
527
  $name = trim ($fname . " " . $lname); /* Both names. */
528
  /**/
@@ -531,8 +533,8 @@ if (!class_exists ("c_ws_plugin__s2member_registrations"))
531
  $pass = $GLOBALS["ws_plugin__s2member_generate_password_return"];
532
  /**/
533
  if (!$pass) /* Also try BuddyPress Password. */
534
- if ($_pm["signup_password"]) /* BuddyPress. */
535
- $pass = $_pm["signup_password"];
536
  /**/
537
  if ($pass) /* No Password nag. Update this globally. */
538
  {
@@ -581,8 +583,8 @@ if (!class_exists ("c_ws_plugin__s2member_registrations"))
581
  $field_var = preg_replace ("/[^a-z0-9]/i", "_", strtolower ($field["id"]));
582
  $field_id_class = preg_replace ("/_/", "-", $field_var);
583
  /**/
584
- if (isset ($_pm["ws_plugin__s2member_custom_reg_field_" . $field_var]))
585
- $fields[$field_var] = $_pm["ws_plugin__s2member_custom_reg_field_" . $field_var];
586
  }
587
  /**/
588
  update_user_option ($user_id, "s2member_custom_fields", $fields);
@@ -607,36 +609,39 @@ if (!class_exists ("c_ws_plugin__s2member_registrations"))
607
  */
608
  $processed = "yes"; /* Mark this as yes, to indicate that a routine was processed. */
609
  /**/
610
- $role = ($current_role = c_ws_plugin__s2member_user_access::user_access_role ($user));
 
 
611
  $role = (!$role) ? get_option ("default_role") : $role; /* Otherwise default. */
612
  /**/
613
- $level = (preg_match ("/^(administrator|editor|author|contributor)$/i", $role)) ? "4" : $level;
 
614
  $level = (!$level && preg_match ("/^s2member_level[1-4]$/i", $role)) ? preg_replace ("/^s2member_level/", "", $role) : $level;
615
  $level = (!$level && preg_match ("/^subscriber$/i", $role)) ? "0" : $level;
616
  $level = (!$level) ? "0" : $level;
617
  /**/
618
- $ccaps = $_pm["ws_plugin__s2member_custom_reg_field_s2member_ccaps"];
619
  /**/
620
  $email = $user->user_email;
621
  $login = $user->user_login;
622
  $ip = ""; /* N/Applicable. */
623
- $custom = $_pm["ws_plugin__s2member_custom_reg_field_s2member_custom"];
624
- $subscr_id = $_pm["ws_plugin__s2member_custom_reg_field_s2member_subscr_id"];
625
- $subscr_gateway = $_pm["ws_plugin__s2member_custom_reg_field_s2member_subscr_gateway"];
626
- $cv = preg_split ("/\|/", $_pm["ws_plugin__s2member_custom_reg_field_s2member_custom"]);
627
  /**/
628
- $auto_eot_time = ($eot = $_pm["ws_plugin__s2member_custom_reg_field_s2member_auto_eot_time"]) ? strtotime ($eot) : "";
629
- $notes = $_pm["ws_plugin__s2member_custom_reg_field_s2member_notes"];
630
  /**/
631
- $opt_in = ($_pm["ws_plugin__s2member_custom_reg_field_opt_in"]) ? true : false;
632
  /**/
633
  if (! ($fname = $user->first_name)) /* `Users -> Add New`. */
634
- if ($_pm["ws_plugin__s2member_custom_reg_field_first_name"])
635
- $fname = $_pm["ws_plugin__s2member_custom_reg_field_first_name"];
636
  /**/
637
  if (! ($lname = $user->last_name)) /* `Users -> Add New`. */
638
- if ($_pm["ws_plugin__s2member_custom_reg_field_last_name"])
639
- $lname = $_pm["ws_plugin__s2member_custom_reg_field_last_name"];
640
  /**/
641
  $name = trim ($fname . " " . $lname); /* Both names. */
642
  /**/
@@ -645,8 +650,8 @@ if (!class_exists ("c_ws_plugin__s2member_registrations"))
645
  $pass = $GLOBALS["ws_plugin__s2member_generate_password_return"];
646
  /**/
647
  if (!$pass) /* Also try the `Users -> Add New` form. */
648
- if ($_pm["pass1"]) /* Field in user-new.php. */
649
- $pass = $_pm["pass1"];
650
  /**/
651
  if ($pass) /* No Password nag. Update this globally. */
652
  {
@@ -695,8 +700,8 @@ if (!class_exists ("c_ws_plugin__s2member_registrations"))
695
  $field_var = preg_replace ("/[^a-z0-9]/i", "_", strtolower ($field["id"]));
696
  $field_id_class = preg_replace ("/_/", "-", $field_var);
697
  /**/
698
- if (isset ($_pm["ws_plugin__s2member_custom_reg_field_" . $field_var]))
699
- $fields[$field_var] = $_pm["ws_plugin__s2member_custom_reg_field_" . $field_var];
700
  }
701
  /**/
702
  update_user_option ($user_id, "s2member_custom_fields", $fields);
@@ -723,22 +728,24 @@ if (!class_exists ("c_ws_plugin__s2member_registrations"))
723
  if (($url = preg_replace ("/%%cv([0-9]+)%%/ei", 'urlencode(trim($cv[$1]))', $url)))
724
  if (($url = preg_replace ("/%%role%%/i", c_ws_plugin__s2member_utils_strings::esc_ds (urlencode ($role)), $url)))
725
  if (($url = preg_replace ("/%%level%%/i", c_ws_plugin__s2member_utils_strings::esc_ds (urlencode ($level)), $url)))
726
- if (($url = preg_replace ("/%%user_first_name%%/i", c_ws_plugin__s2member_utils_strings::esc_ds (urlencode ($fname)), $url)))
727
- if (($url = preg_replace ("/%%user_last_name%%/i", c_ws_plugin__s2member_utils_strings::esc_ds (urlencode ($lname)), $url)))
728
- if (($url = preg_replace ("/%%user_full_name%%/i", c_ws_plugin__s2member_utils_strings::esc_ds (urlencode ($name)), $url)))
729
- if (($url = preg_replace ("/%%user_email%%/i", c_ws_plugin__s2member_utils_strings::esc_ds (urlencode ($email)), $url)))
730
- if (($url = preg_replace ("/%%user_login%%/i", c_ws_plugin__s2member_utils_strings::esc_ds (urlencode ($login)), $url)))
731
- if (($url = preg_replace ("/%%user_pass%%/i", c_ws_plugin__s2member_utils_strings::esc_ds (urlencode ($pass)), $url)))
732
- if (($url = preg_replace ("/%%user_id%%/i", c_ws_plugin__s2member_utils_strings::esc_ds (urlencode ($user_id)), $url)))
733
- {
734
- if (is_array ($fields) && !empty ($fields))
735
- foreach ($fields as $var => $val) /* Custom Registration Fields. */
736
- if (! ($url = preg_replace ("/%%" . preg_quote ($var, "/") . "%%/i", c_ws_plugin__s2member_utils_strings::esc_ds (urlencode (maybe_serialize ($val))), $url)))
737
- break;
738
- /**/
739
- if (($url = trim (preg_replace ("/%%(.+?)%%/i", "", $url))))
740
- c_ws_plugin__s2member_utils_urls::remote ($url);
741
- }
 
 
742
  /**/
743
  if ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["registration_notification_recipients"])
744
  {
@@ -747,6 +754,8 @@ if (!class_exists ("c_ws_plugin__s2member_registrations"))
747
  /**/
748
  $msg .= "role: %%role%%\n";
749
  $msg .= "level: %%level%%\n";
 
 
750
  $msg .= "user_first_name: %%user_first_name%%\n";
751
  $msg .= "user_last_name: %%user_last_name%%\n";
752
  $msg .= "user_full_name: %%user_full_name%%\n";
@@ -773,23 +782,25 @@ if (!class_exists ("c_ws_plugin__s2member_registrations"))
773
  if (($msg = preg_replace ("/%%cv([0-9]+)%%/ei", 'trim($cv[$1])', $msg)))
774
  if (($msg = preg_replace ("/%%role%%/i", c_ws_plugin__s2member_utils_strings::esc_ds ($role), $msg)))
775
  if (($msg = preg_replace ("/%%level%%/i", c_ws_plugin__s2member_utils_strings::esc_ds ($level), $msg)))
776
- if (($msg = preg_replace ("/%%user_first_name%%/i", c_ws_plugin__s2member_utils_strings::esc_ds ($fname), $msg)))
777
- if (($msg = preg_replace ("/%%user_last_name%%/i", c_ws_plugin__s2member_utils_strings::esc_ds ($lname), $msg)))
778
- if (($msg = preg_replace ("/%%user_full_name%%/i", c_ws_plugin__s2member_utils_strings::esc_ds ($name), $msg)))
779
- if (($msg = preg_replace ("/%%user_email%%/i", c_ws_plugin__s2member_utils_strings::esc_ds ($email), $msg)))
780
- if (($msg = preg_replace ("/%%user_login%%/i", c_ws_plugin__s2member_utils_strings::esc_ds ($login), $msg)))
781
- if (($msg = preg_replace ("/%%user_pass%%/i", c_ws_plugin__s2member_utils_strings::esc_ds ($pass), $msg)))
782
- if (($msg = preg_replace ("/%%user_id%%/i", c_ws_plugin__s2member_utils_strings::esc_ds ($user_id), $msg)))
783
- {
784
- if (is_array ($fields) && !empty ($fields))
785
- foreach ($fields as $var => $val) /* Custom Registration Fields. */
786
- if (! ($msg = preg_replace ("/%%" . preg_quote ($var, "/") . "%%/i", c_ws_plugin__s2member_utils_strings::esc_ds (maybe_serialize ($val)), $msg)))
787
- break;
788
- /**/
789
- if (($msg = trim (preg_replace ("/%%(.+?)%%/i", "", $msg))))
790
- foreach (c_ws_plugin__s2member_utils_strings::trim_deep (preg_split ("/;+/", $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["registration_notification_recipients"])) as $recipient)
791
- ($recipient) ? wp_mail ($recipient, apply_filters ("ws_plugin__s2member_registration_notification_email_sbj", $sbj, get_defined_vars ()), apply_filters ("ws_plugin__s2member_registration_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;
792
- }
 
 
793
  }
794
  /**/
795
  if ($url = $GLOBALS["ws_plugin__s2member_registration_return_url"])
@@ -797,30 +808,38 @@ if (!class_exists ("c_ws_plugin__s2member_registrations"))
797
  if (($url = preg_replace ("/%%cv([0-9]+)%%/ei", 'urlencode(trim($cv[$1]))', $url)))
798
  if (($url = preg_replace ("/%%role%%/i", c_ws_plugin__s2member_utils_strings::esc_ds (urlencode ($role)), $url)))
799
  if (($url = preg_replace ("/%%level%%/i", c_ws_plugin__s2member_utils_strings::esc_ds (urlencode ($level)), $url)))
800
- if (($url = preg_replace ("/%%user_first_name%%/i", c_ws_plugin__s2member_utils_strings::esc_ds (urlencode ($fname)), $url)))
801
- if (($url = preg_replace ("/%%user_last_name%%/i", c_ws_plugin__s2member_utils_strings::esc_ds (urlencode ($lname)), $url)))
802
- if (($url = preg_replace ("/%%user_full_name%%/i", c_ws_plugin__s2member_utils_strings::esc_ds (urlencode ($name)), $url)))
803
- if (($url = preg_replace ("/%%user_email%%/i", c_ws_plugin__s2member_utils_strings::esc_ds (urlencode ($email)), $url)))
804
- if (($url = preg_replace ("/%%user_login%%/i", c_ws_plugin__s2member_utils_strings::esc_ds (urlencode ($login)), $url)))
805
- if (($url = preg_replace ("/%%user_pass%%/i", c_ws_plugin__s2member_utils_strings::esc_ds (urlencode ($pass)), $url)))
806
- if (($url = preg_replace ("/%%user_id%%/i", c_ws_plugin__s2member_utils_strings::esc_ds (urlencode ($user_id)), $url)))
807
- {
808
- if (is_array ($fields) && !empty ($fields))
809
- foreach ($fields as $var => $val) /* Custom Registration Fields. */
810
- if (! ($url = preg_replace ("/%%" . preg_quote ($var, "/") . "%%/i", c_ws_plugin__s2member_utils_strings::esc_ds (urlencode (maybe_serialize ($val))), $url)))
811
- break;
812
- /**/
813
- if (($url = trim ($url))) /* Preserve remaining Replacements. */
814
- /* Because the parent routine may perform replacements too. */
815
- $GLOBALS["ws_plugin__s2member_registration_return_url"] = $url;
816
- }
817
- /**/
818
- c_ws_plugin__s2member_list_servers::process_list_servers ($role, $level, $email, $fname, $lname, $ip, $opt_in, $user_id);
819
- /**/
820
- setcookie ("s2member_subscr_gateway", "", time () + 31556926, "/");
821
- setcookie ("s2member_subscr_id", "", time () + 31556926, "/");
822
- setcookie ("s2member_custom", "", time () + 31556926, "/");
823
- setcookie ("s2member_level", "", time () + 31556926, "/");
 
 
 
 
 
 
 
 
824
  /**/
825
  eval ('foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;');
826
  do_action ("ws_plugin__s2member_during_configure_user_registration", get_defined_vars ());
337
  if (!is_admin () && ($post["ws_plugin__s2member_custom_reg_field_s2member_subscr_gateway"] || $post["ws_plugin__s2member_custom_reg_field_s2member_subscr_id"] || $post["ws_plugin__s2member_custom_reg_field_s2member_custom"] || $post["ws_plugin__s2member_custom_reg_field_s2member_ccaps"] || $post["ws_plugin__s2member_custom_reg_field_s2member_auto_eot_time"] || $post["ws_plugin__s2member_custom_reg_field_s2member_notes"]))
338
  exit ("s2Member security violation. You attempted to POST administrative variables that will NOT be trusted in a NON-administrative zone!");
339
  /**/
340
+ $_pmr = array_merge ((array)$post, (array)$meta, (array)$GLOBALS["ws_plugin__s2member_registration_vars"]); /* Merge these together. */
341
+ unset ($post, $meta, $GLOBALS["ws_plugin__s2member_registration_vars"]); /* These vars can all be unset now; we have them all now inside $_pmr. */
342
  /**/
343
  if (!is_admin () /* Only run this particular routine whenever a Member Level [1-4] is registering themselves with paid authorization cookies in their browser. */
344
  && ($subscr_gateway = c_ws_plugin__s2member_utils_encryption::decrypt ($_COOKIE["s2member_subscr_gateway"])) && ($subscr_id = c_ws_plugin__s2member_utils_encryption::decrypt ($_COOKIE["s2member_subscr_id"])) && preg_match ("/^" . preg_quote (preg_replace ("/\:([0-9]+)$/", "", $_SERVER["HTTP_HOST"]), "/") . "/i", ($custom = c_ws_plugin__s2member_utils_encryption::decrypt ($_COOKIE["s2member_custom"]))) && preg_match ("/^[1-4](\:|$)([\+a-z_0-9,]+)?(\:)?([0-9]+ [A-Z])?$/", ($level = c_ws_plugin__s2member_utils_encryption::decrypt ($_COOKIE["s2member_level"])))/**/
353
  /**/
354
  $current_role = c_ws_plugin__s2member_user_access::user_access_role ($user);
355
  list ($level, $ccaps, $eotper) = preg_split ("/\:/", $level, 3);
356
+ $role = "s2member_level" . $level; /* Membership Level. */
357
  /**/
358
  $email = $user->user_email;
359
  $login = $user->user_login;
363
  if ($eotper) /* If a specific EOT Period has been attached; calculate that now. */
364
  $auto_eot_time = c_ws_plugin__s2member_utils_time::auto_eot_time ("", "", "", $eotper);
365
  /**/
366
+ $notes = $_pmr["ws_plugin__s2member_custom_reg_field_s2member_notes"];
367
  /**/
368
  $opt_in = (!$GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["custom_reg_opt_in"]) ? true : false;
369
+ $opt_in = (!$opt_in && $_pmr["ws_plugin__s2member_custom_reg_field_opt_in"]) ? true : $opt_in;
370
  /**/
371
  if (! ($fname = $user->first_name))
372
+ if ($_pmr["ws_plugin__s2member_custom_reg_field_first_name"])
373
+ $fname = $_pmr["ws_plugin__s2member_custom_reg_field_first_name"];
374
  /**/
375
  if (!$fname) /* Also try BuddyPress. */
376
+ if ($_pmr["field_1"]) /* BuddyPress. */
377
+ $fname = trim (preg_replace ("/ (.*)$/", "", $_pmr["field_1"]));
378
  /**/
379
  if (! ($lname = $user->last_name))
380
+ if ($_pmr["ws_plugin__s2member_custom_reg_field_last_name"])
381
+ $lname = $_pmr["ws_plugin__s2member_custom_reg_field_last_name"];
382
  /**/
383
  if (!$lname) /* Also try BuddyPress. */
384
+ if ($_pmr["field_1"] && preg_match ("/^(.+?) (.+)$/", $_pmr["field_1"]))
385
+ $lname = trim (preg_replace ("/^(.+?) (.+)$/", "$2", $_pmr["field_1"]));
386
  /**/
387
  $name = trim ($fname . " " . $lname); /* Both names. */
388
  /**/
391
  $pass = $GLOBALS["ws_plugin__s2member_generate_password_return"];
392
  /**/
393
  if (!$pass) /* Also try BuddyPress Password. */
394
+ if ($_pmr["signup_password"]) /* BuddyPress. */
395
+ $pass = $_pmr["signup_password"];
396
  /**/
397
  if ($pass) /* No Password nag. Update this globally. */
398
  {
441
  $field_var = preg_replace ("/[^a-z0-9]/i", "_", strtolower ($field["id"]));
442
  $field_id_class = preg_replace ("/_/", "-", $field_var);
443
  /**/
444
+ if (isset ($_pmr["ws_plugin__s2member_custom_reg_field_" . $field_var]))
445
+ $fields[$field_var] = $_pmr["ws_plugin__s2member_custom_reg_field_" . $field_var];
446
  }
447
  /**/
448
  update_user_option ($user_id, "s2member_custom_fields", $fields);
477
  }
478
  /**/
479
  else if (!is_admin ()) /* Otherwise, if we are NOT inside the Dashboard during the creation of this account. */
480
+ { /* This routine could be processed through `wp-login.php?action=register`, `wp-activate.php`, or `/activate` via BuddyPress`.
 
481
  This may also be processed through a standard BuddyPress installation, or another plugin calling `user_register`.
482
  If processed through `wp-activate.php`, it could've originated inside the admin, via `user-new.php`.
483
  */
484
  $processed = "yes"; /* Mark this as yes, to indicate that a routine was processed. */
485
  /**/
486
+ $current_role = c_ws_plugin__s2member_user_access::user_access_role ($user);
487
+ $role = ($level = $_pmr["ws_plugin__s2member_custom_reg_field_s2member_level"]) ? "s2member_level" . $level : $role;
488
+ $role = (!$role && $current_role) ? $current_role : $role; /* Use existing Role? */
489
  $role = (!$role) ? get_option ("default_role") : $role; /* Otherwise default. */
490
  /**/
491
+ $level = $_pmr["ws_plugin__s2member_custom_reg_field_s2member_level"];
492
+ $level = (!$level && preg_match ("/^(administrator|editor|author|contributor)$/i", $role)) ? "4" : $level;
493
  $level = (!$level && preg_match ("/^s2member_level[1-4]$/i", $role)) ? preg_replace ("/^s2member_level/", "", $role) : $level;
494
  $level = (!$level && preg_match ("/^subscriber$/i", $role)) ? "0" : $level;
495
  $level = (!$level) ? "0" : $level;
496
  /**/
497
+ $ccaps = $_pmr["ws_plugin__s2member_custom_reg_field_s2member_ccaps"];
498
  /**/
499
  $email = $user->user_email;
500
  $login = $user->user_login;
501
  $ip = $_SERVER["REMOTE_ADDR"];
502
+ $custom = $_pmr["ws_plugin__s2member_custom_reg_field_s2member_custom"];
503
+ $subscr_id = $_pmr["ws_plugin__s2member_custom_reg_field_s2member_subscr_id"];
504
+ $subscr_gateway = $_pmr["ws_plugin__s2member_custom_reg_field_s2member_subscr_gateway"];
505
+ $cv = preg_split ("/\|/", $_pmr["ws_plugin__s2member_custom_reg_field_s2member_custom"]);
506
  /**/
507
+ $auto_eot_time = ($eot = $_pmr["ws_plugin__s2member_custom_reg_field_s2member_auto_eot_time"]) ? strtotime ($eot) : "";
508
+ $notes = $_pmr["ws_plugin__s2member_custom_reg_field_s2member_notes"];
509
  /**/
510
  $opt_in = (!$GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["custom_reg_opt_in"]) ? true : false;
511
+ $opt_in = (!$opt_in && $_pmr["ws_plugin__s2member_custom_reg_field_opt_in"]) ? true : $opt_in;
512
  /**/
513
  if (! ($fname = $user->first_name))
514
+ if ($_pmr["ws_plugin__s2member_custom_reg_field_first_name"])
515
+ $fname = $_pmr["ws_plugin__s2member_custom_reg_field_first_name"];
516
  /**/
517
  if (!$fname) /* Also try BuddyPress. */
518
+ if ($_pmr["field_1"]) /* BuddyPress. */
519
+ $fname = trim (preg_replace ("/ (.*)$/", "", $_pmr["field_1"]));
520
  /**/
521
  if (! ($lname = $user->last_name))
522
+ if ($_pmr["ws_plugin__s2member_custom_reg_field_last_name"])
523
+ $lname = $_pmr["ws_plugin__s2member_custom_reg_field_last_name"];
524
  /**/
525
  if (!$lname) /* Also try BuddyPress. */
526
+ if ($_pmr["field_1"] && preg_match ("/^(.+?) (.+)$/", $_pmr["field_1"]))
527
+ $lname = trim (preg_replace ("/^(.+?) (.+)$/", "$2", $_pmr["field_1"]));
528
  /**/
529
  $name = trim ($fname . " " . $lname); /* Both names. */
530
  /**/
533
  $pass = $GLOBALS["ws_plugin__s2member_generate_password_return"];
534
  /**/
535
  if (!$pass) /* Also try BuddyPress Password. */
536
+ if ($_pmr["signup_password"]) /* BuddyPress. */
537
+ $pass = $_pmr["signup_password"];
538
  /**/
539
  if ($pass) /* No Password nag. Update this globally. */
540
  {
583
  $field_var = preg_replace ("/[^a-z0-9]/i", "_", strtolower ($field["id"]));
584
  $field_id_class = preg_replace ("/_/", "-", $field_var);
585
  /**/
586
+ if (isset ($_pmr["ws_plugin__s2member_custom_reg_field_" . $field_var]))
587
+ $fields[$field_var] = $_pmr["ws_plugin__s2member_custom_reg_field_" . $field_var];
588
  }
589
  /**/
590
  update_user_option ($user_id, "s2member_custom_fields", $fields);
609
  */
610
  $processed = "yes"; /* Mark this as yes, to indicate that a routine was processed. */
611
  /**/
612
+ $current_role = c_ws_plugin__s2member_user_access::user_access_role ($user);
613
+ $role = ($level = $_pmr["ws_plugin__s2member_custom_reg_field_s2member_level"]) ? "s2member_level" . $level : $role;
614
+ $role = (!$role && $current_role) ? $current_role : $role; /* Use existing Role? */
615
  $role = (!$role) ? get_option ("default_role") : $role; /* Otherwise default. */
616
  /**/
617
+ $level = $_pmr["ws_plugin__s2member_custom_reg_field_s2member_level"];
618
+ $level = (!$level && preg_match ("/^(administrator|editor|author|contributor)$/i", $role)) ? "4" : $level;
619
  $level = (!$level && preg_match ("/^s2member_level[1-4]$/i", $role)) ? preg_replace ("/^s2member_level/", "", $role) : $level;
620
  $level = (!$level && preg_match ("/^subscriber$/i", $role)) ? "0" : $level;
621
  $level = (!$level) ? "0" : $level;
622
  /**/
623
+ $ccaps = $_pmr["ws_plugin__s2member_custom_reg_field_s2member_ccaps"];
624
  /**/
625
  $email = $user->user_email;
626
  $login = $user->user_login;
627
  $ip = ""; /* N/Applicable. */
628
+ $custom = $_pmr["ws_plugin__s2member_custom_reg_field_s2member_custom"];
629
+ $subscr_id = $_pmr["ws_plugin__s2member_custom_reg_field_s2member_subscr_id"];
630
+ $subscr_gateway = $_pmr["ws_plugin__s2member_custom_reg_field_s2member_subscr_gateway"];
631
+ $cv = preg_split ("/\|/", $_pmr["ws_plugin__s2member_custom_reg_field_s2member_custom"]);
632
  /**/
633
+ $auto_eot_time = ($eot = $_pmr["ws_plugin__s2member_custom_reg_field_s2member_auto_eot_time"]) ? strtotime ($eot) : "";
634
+ $notes = $_pmr["ws_plugin__s2member_custom_reg_field_s2member_notes"];
635
  /**/
636
+ $opt_in = ($_pmr["ws_plugin__s2member_custom_reg_field_opt_in"]) ? true : false;
637
  /**/
638
  if (! ($fname = $user->first_name)) /* `Users -> Add New`. */
639
+ if ($_pmr["ws_plugin__s2member_custom_reg_field_first_name"])
640
+ $fname = $_pmr["ws_plugin__s2member_custom_reg_field_first_name"];
641
  /**/
642
  if (! ($lname = $user->last_name)) /* `Users -> Add New`. */
643
+ if ($_pmr["ws_plugin__s2member_custom_reg_field_last_name"])
644
+ $lname = $_pmr["ws_plugin__s2member_custom_reg_field_last_name"];
645
  /**/
646
  $name = trim ($fname . " " . $lname); /* Both names. */
647
  /**/
650
  $pass = $GLOBALS["ws_plugin__s2member_generate_password_return"];
651
  /**/
652
  if (!$pass) /* Also try the `Users -> Add New` form. */
653
+ if ($_pmr["pass1"]) /* Field in user-new.php. */
654
+ $pass = $_pmr["pass1"];
655
  /**/
656
  if ($pass) /* No Password nag. Update this globally. */
657
  {
700
  $field_var = preg_replace ("/[^a-z0-9]/i", "_", strtolower ($field["id"]));
701
  $field_id_class = preg_replace ("/_/", "-", $field_var);
702
  /**/
703
+ if (isset ($_pmr["ws_plugin__s2member_custom_reg_field_" . $field_var]))
704
+ $fields[$field_var] = $_pmr["ws_plugin__s2member_custom_reg_field_" . $field_var];
705
  }
706
  /**/
707
  update_user_option ($user_id, "s2member_custom_fields", $fields);
728
  if (($url = preg_replace ("/%%cv([0-9]+)%%/ei", 'urlencode(trim($cv[$1]))', $url)))
729
  if (($url = preg_replace ("/%%role%%/i", c_ws_plugin__s2member_utils_strings::esc_ds (urlencode ($role)), $url)))
730
  if (($url = preg_replace ("/%%level%%/i", c_ws_plugin__s2member_utils_strings::esc_ds (urlencode ($level)), $url)))
731
+ if (($url = preg_replace ("/%%ccaps%%/i", c_ws_plugin__s2member_utils_strings::esc_ds (urlencode ($ccaps)), $url)))
732
+ if (($url = preg_replace ("/%%auto_eot_time%%/i", c_ws_plugin__s2member_utils_strings::esc_ds (urlencode ($auto_eot_time)), $url)))
733
+ if (($url = preg_replace ("/%%user_first_name%%/i", c_ws_plugin__s2member_utils_strings::esc_ds (urlencode ($fname)), $url)))
734
+ if (($url = preg_replace ("/%%user_last_name%%/i", c_ws_plugin__s2member_utils_strings::esc_ds (urlencode ($lname)), $url)))
735
+ if (($url = preg_replace ("/%%user_full_name%%/i", c_ws_plugin__s2member_utils_strings::esc_ds (urlencode ($name)), $url)))
736
+ if (($url = preg_replace ("/%%user_email%%/i", c_ws_plugin__s2member_utils_strings::esc_ds (urlencode ($email)), $url)))
737
+ if (($url = preg_replace ("/%%user_login%%/i", c_ws_plugin__s2member_utils_strings::esc_ds (urlencode ($login)), $url)))
738
+ if (($url = preg_replace ("/%%user_pass%%/i", c_ws_plugin__s2member_utils_strings::esc_ds (urlencode ($pass)), $url)))
739
+ if (($url = preg_replace ("/%%user_id%%/i", c_ws_plugin__s2member_utils_strings::esc_ds (urlencode ($user_id)), $url)))
740
+ {
741
+ if (is_array ($fields) && !empty ($fields))
742
+ foreach ($fields as $var => $val) /* Custom Registration Fields. */
743
+ if (! ($url = preg_replace ("/%%" . preg_quote ($var, "/") . "%%/i", c_ws_plugin__s2member_utils_strings::esc_ds (urlencode (maybe_serialize ($val))), $url)))
744
+ break;
745
+ /**/
746
+ if (($url = trim (preg_replace ("/%%(.+?)%%/i", "", $url))))
747
+ c_ws_plugin__s2member_utils_urls::remote ($url);
748
+ }
749
  /**/
750
  if ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["registration_notification_recipients"])
751
  {
754
  /**/
755
  $msg .= "role: %%role%%\n";
756
  $msg .= "level: %%level%%\n";
757
+ $msg .= "ccaps: %%ccaps%%\n";
758
+ $msg .= "auto_eot_time: %%auto_eot_time%%\n";
759
  $msg .= "user_first_name: %%user_first_name%%\n";
760
  $msg .= "user_last_name: %%user_last_name%%\n";
761
  $msg .= "user_full_name: %%user_full_name%%\n";
782
  if (($msg = preg_replace ("/%%cv([0-9]+)%%/ei", 'trim($cv[$1])', $msg)))
783
  if (($msg = preg_replace ("/%%role%%/i", c_ws_plugin__s2member_utils_strings::esc_ds ($role), $msg)))
784
  if (($msg = preg_replace ("/%%level%%/i", c_ws_plugin__s2member_utils_strings::esc_ds ($level), $msg)))
785
+ if (($msg = preg_replace ("/%%ccaps%%/i", c_ws_plugin__s2member_utils_strings::esc_ds ($ccaps), $msg)))
786
+ if (($msg = preg_replace ("/%%auto_eot_time%%/i", c_ws_plugin__s2member_utils_strings::esc_ds ($auto_eot_time), $msg)))
787
+ if (($msg = preg_replace ("/%%user_first_name%%/i", c_ws_plugin__s2member_utils_strings::esc_ds ($fname), $msg)))
788
+ if (($msg = preg_replace ("/%%user_last_name%%/i", c_ws_plugin__s2member_utils_strings::esc_ds ($lname), $msg)))
789
+ if (($msg = preg_replace ("/%%user_full_name%%/i", c_ws_plugin__s2member_utils_strings::esc_ds ($name), $msg)))
790
+ if (($msg = preg_replace ("/%%user_email%%/i", c_ws_plugin__s2member_utils_strings::esc_ds ($email), $msg)))
791
+ if (($msg = preg_replace ("/%%user_login%%/i", c_ws_plugin__s2member_utils_strings::esc_ds ($login), $msg)))
792
+ if (($msg = preg_replace ("/%%user_pass%%/i", c_ws_plugin__s2member_utils_strings::esc_ds ($pass), $msg)))
793
+ if (($msg = preg_replace ("/%%user_id%%/i", c_ws_plugin__s2member_utils_strings::esc_ds ($user_id), $msg)))
794
+ {
795
+ if (is_array ($fields) && !empty ($fields))
796
+ foreach ($fields as $var => $val) /* Custom Registration Fields. */
797
+ if (! ($msg = preg_replace ("/%%" . preg_quote ($var, "/") . "%%/i", c_ws_plugin__s2member_utils_strings::esc_ds (maybe_serialize ($val)), $msg)))
798
+ break;
799
+ /**/
800
+ if (($msg = trim (preg_replace ("/%%(.+?)%%/i", "", $msg))))
801
+ foreach (c_ws_plugin__s2member_utils_strings::trim_deep (preg_split ("/;+/", $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["registration_notification_recipients"])) as $recipient)
802
+ ($recipient) ? wp_mail ($recipient, apply_filters ("ws_plugin__s2member_registration_notification_email_sbj", $sbj, get_defined_vars ()), apply_filters ("ws_plugin__s2member_registration_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;
803
+ }
804
  }
805
  /**/
806
  if ($url = $GLOBALS["ws_plugin__s2member_registration_return_url"])
808
  if (($url = preg_replace ("/%%cv([0-9]+)%%/ei", 'urlencode(trim($cv[$1]))', $url)))
809
  if (($url = preg_replace ("/%%role%%/i", c_ws_plugin__s2member_utils_strings::esc_ds (urlencode ($role)), $url)))
810
  if (($url = preg_replace ("/%%level%%/i", c_ws_plugin__s2member_utils_strings::esc_ds (urlencode ($level)), $url)))
811
+ if (($url = preg_replace ("/%%ccaps%%/i", c_ws_plugin__s2member_utils_strings::esc_ds (urlencode ($ccaps)), $url)))
812
+ if (($url = preg_replace ("/%%auto_eot_time%%/i", c_ws_plugin__s2member_utils_strings::esc_ds (urlencode ($auto_eot_time)), $url)))
813
+ if (($url = preg_replace ("/%%user_first_name%%/i", c_ws_plugin__s2member_utils_strings::esc_ds (urlencode ($fname)), $url)))
814
+ if (($url = preg_replace ("/%%user_last_name%%/i", c_ws_plugin__s2member_utils_strings::esc_ds (urlencode ($lname)), $url)))
815
+ if (($url = preg_replace ("/%%user_full_name%%/i", c_ws_plugin__s2member_utils_strings::esc_ds (urlencode ($name)), $url)))
816
+ if (($url = preg_replace ("/%%user_email%%/i", c_ws_plugin__s2member_utils_strings::esc_ds (urlencode ($email)), $url)))
817
+ if (($url = preg_replace ("/%%user_login%%/i", c_ws_plugin__s2member_utils_strings::esc_ds (urlencode ($login)), $url)))
818
+ if (($url = preg_replace ("/%%user_pass%%/i", c_ws_plugin__s2member_utils_strings::esc_ds (urlencode ($pass)), $url)))
819
+ if (($url = preg_replace ("/%%user_id%%/i", c_ws_plugin__s2member_utils_strings::esc_ds (urlencode ($user_id)), $url)))
820
+ {
821
+ if (is_array ($fields) && !empty ($fields))
822
+ foreach ($fields as $var => $val) /* Custom Registration Fields. */
823
+ if (! ($url = preg_replace ("/%%" . preg_quote ($var, "/") . "%%/i", c_ws_plugin__s2member_utils_strings::esc_ds (urlencode (maybe_serialize ($val))), $url)))
824
+ break;
825
+ /**/
826
+ if (($url = trim ($url))) /* Preserve remaining Replacements. */
827
+ /* Because the parent routine may perform replacements too. */
828
+ $GLOBALS["ws_plugin__s2member_registration_return_url"] = $url;
829
+ }
830
+ /**/
831
+ c_ws_plugin__s2member_list_servers::process_list_servers ($role, $level, $login, $pass, $email, $fname, $lname, $ip, $opt_in, $user_id);
832
+ /*
833
+ Suppress errors here in case this routine is fired in unexpected locations; or with odd output buffering techniques.
834
+ @TODO: It may also be impossible to delete cookies when fired inside: `/wp-activate.php`.
835
+ */
836
+ if (!headers_sent ()) /* Only if headers are NOT yet sent. */
837
+ {
838
+ @setcookie ("s2member_subscr_gateway", "", time () + 31556926, "/");
839
+ @setcookie ("s2member_subscr_id", "", time () + 31556926, "/");
840
+ @setcookie ("s2member_custom", "", time () + 31556926, "/");
841
+ @setcookie ("s2member_level", "", time () + 31556926, "/");
842
+ }
843
  /**/
844
  eval ('foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;');
845
  do_action ("ws_plugin__s2member_during_configure_user_registration", get_defined_vars ());
includes/classes/sp-access.inc.php CHANGED
@@ -32,7 +32,10 @@ if (!class_exists ("c_ws_plugin__s2member_sp_access"))
32
  $sp_access = c_ws_plugin__s2member_utils_encryption::encrypt ("sp_time_hours:.:|:.:" . $sp_ids . ":.:|:.:" . strtotime ("now") . ":.:|:.:" . $hours);
33
  $sp_access_link = add_query_arg ("s2member_sp_access", urlencode ($sp_access), get_permalink ($leading_id));
34
  /**/
35
- if ($shrink && ($tinyurl = c_ws_plugin__s2member_utils_urls::remote ("http://tinyurl.com/api-create.php?url=" . rawurlencode ($sp_access_link))))
 
 
 
36
  return apply_filters ("ws_plugin__s2member_sp_access_link_gen", $tinyurl . "#" . $_SERVER["HTTP_HOST"], get_defined_vars ());
37
  /**/
38
  else /* Else use the long one; tinyURL will fail when/if their server is down periodically. */
32
  $sp_access = c_ws_plugin__s2member_utils_encryption::encrypt ("sp_time_hours:.:|:.:" . $sp_ids . ":.:|:.:" . strtotime ("now") . ":.:|:.:" . $hours);
33
  $sp_access_link = add_query_arg ("s2member_sp_access", urlencode ($sp_access), get_permalink ($leading_id));
34
  /**/
35
+ if ($shrink && ($_alternative = apply_filters ("ws_plugin__s2member_sp_access_link_gen_alternative", $sp_access_link, get_defined_vars ())) && strlen ($_alternative) < strlen ($sp_access_link))
36
+ return apply_filters ("ws_plugin__s2member_sp_access_link_gen", $_alternative, get_defined_vars ());
37
+ /**/
38
+ else if ($shrink && ($tinyurl = c_ws_plugin__s2member_utils_urls::remote ("http://tinyurl.com/api-create.php?url=" . rawurlencode ($sp_access_link))))
39
  return apply_filters ("ws_plugin__s2member_sp_access_link_gen", $tinyurl . "#" . $_SERVER["HTTP_HOST"], get_defined_vars ());
40
  /**/
41
  else /* Else use the long one; tinyURL will fail when/if their server is down periodically. */
includes/classes/ssl-in.inc.php CHANGED
@@ -19,7 +19,7 @@ if (!class_exists ("c_ws_plugin__s2member_ssl_in"))
19
  class c_ws_plugin__s2member_ssl_in
20
  {
21
  /*
22
- Function that forces SSL on specific Posts/Pages.
23
  Attach to: add_action("template_redirect");
24
 
25
  Triggered by Custom Field:
@@ -58,39 +58,48 @@ if (!class_exists ("c_ws_plugin__s2member_ssl_in"))
58
  define ("_ws_plugin__s2member_force_ssl_port", $ssl_port);
59
  define ("_ws_plugin__s2member_force_ssl_host_port", $ssl_host_port);
60
  /**/
61
- /* Except these. We do NOT want to create a sitewide https conversion! */
62
  add_filter ("home_url", "_ws_plugin__s2member_force_non_ssl_scheme", 10, 3);
63
  add_filter ("network_home_url", "_ws_plugin__s2member_force_non_ssl_scheme", 10, 3);
64
  add_filter ("site_url", "_ws_plugin__s2member_force_non_ssl_scheme", 10, 3);
65
  add_filter ("network_site_url", "_ws_plugin__s2member_force_non_ssl_scheme", 10, 3);
66
- /**/
67
- if (!function_exists ("_ws_plugin__s2member_force_non_ssl_scheme"))
68
- {
69
- function _ws_plugin__s2member_force_non_ssl_scheme ($url = FALSE, $path = FALSE, $scheme = FALSE)
70
- {
71
- return ($scheme) ? $url : preg_replace ("/^https\:\/\//i", "http://", $url);
72
- }
73
- }
74
  /**/
75
  if (!function_exists ("_ws_plugin__s2member_force_ssl_buffer"))
76
  {
77
  function _ws_plugin__s2member_force_ssl_buffer ($buffer = FALSE)
78
  {
79
- $o_pcre = @ini_get ("pcre.backtrack_limit");
80
  /**/
81
- @ini_set ("pcre.backtrack_limit", 10000000);
82
  /**/
83
- $tags = array ("script", "style", "link", "img", "input", "iframe", "object", "embed");
84
- $tags = apply_filters ("_ws_plugin__s2member_force_ssl_buffer_tags_array", $tags, get_defined_vars ());
85
- $tags = array_unique (array_map ("strtolower", $tags)); /* This array should be lowercase / unique. */
86
  /**/
87
- $regex_tags = implode ("|", array_map ("preg_quote", $tags)); /* Prepare for regex. */
88
  /**/
89
- $buffer = ($regex_tags) ? preg_replace_callback ("/\<(" . $regex_tags . ")[^\>]+\>/i", "_ws_plugin__s2member_force_ssl_buffer_callback", $buffer) : $buffer;
90
- $buffer = (in_array ("script", $tags)) ? preg_replace_callback ("/\<script[^\>]*\>(.+?)\<\/script\>/is", "_ws_plugin__s2member_force_ssl_buffer_callback", $buffer) : $buffer;
91
- $buffer = (in_array ("style", $tags)) ? preg_replace_callback ("/\<style[^\>]*\>(.+?)\<\/style\>/is", "_ws_plugin__s2member_force_ssl_buffer_callback", $buffer) : $buffer;
 
92
  /**/
93
- @ini_set ("pcre.backtrack_limit", $o_pcre);
 
 
 
 
 
 
 
 
94
  /**/
95
  return apply_filters ("_ws_plugin__s2member_force_ssl_buffer", $buffer, get_defined_vars ());
96
  }
@@ -100,14 +109,51 @@ if (!class_exists ("c_ws_plugin__s2member_ssl_in"))
100
  {
101
  function _ws_plugin__s2member_force_ssl_buffer_callback ($m = FALSE)
102
  {
103
- $c = preg_replace ("/http\:\/\//i", "https://", $m[0]);
104
  /**/
105
  if (_ws_plugin__s2member_force_ssl_port && _ws_plugin__s2member_force_ssl_host && _ws_plugin__s2member_force_ssl_host_port) /* Need port conversions? */
106
- $c = preg_replace ("/\/" . preg_quote (_ws_plugin__s2member_force_ssl_host, "/") . "(\:[0-9]+)?\//i", "/" . _ws_plugin__s2member_force_ssl_host_port . "/", $c);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
107
  /**/
108
- $c = (strtolower ($m[1]) === "link" && preg_match ("/['\"]alternate['\"]/i", $m[0])) ? $m[0] : $c; /* Alternates are fine to leave like they are. */
109
  /**/
110
- return $c; /* Return string with conversions. */
111
  }
112
  }
113
  /**/
19
  class c_ws_plugin__s2member_ssl_in
20
  {
21
  /*
22
+ Forces SSL on specific Posts/Pages.
23
  Attach to: add_action("template_redirect");
24
 
25
  Triggered by Custom Field:
58
  define ("_ws_plugin__s2member_force_ssl_port", $ssl_port);
59
  define ("_ws_plugin__s2member_force_ssl_host_port", $ssl_host_port);
60
  /**/
61
+ /* Filter these. We do NOT want to create a sitewide https conversion! */
62
  add_filter ("home_url", "_ws_plugin__s2member_force_non_ssl_scheme", 10, 3);
63
  add_filter ("network_home_url", "_ws_plugin__s2member_force_non_ssl_scheme", 10, 3);
64
  add_filter ("site_url", "_ws_plugin__s2member_force_non_ssl_scheme", 10, 3);
65
  add_filter ("network_site_url", "_ws_plugin__s2member_force_non_ssl_scheme", 10, 3);
66
+ /*
67
+ These additional URLs are NOT Filtered by default; but can be if needed. Use these Filters. */
68
+ if (apply_filters ("_ws_plugin__s2member_force_non_ssl_scheme_plugins_url", false, get_defined_vars ()))
69
+ add_filter ("plugins_url", "_ws_plugin__s2member_force_non_ssl_scheme", 10, 2);
70
+ /*
71
+ These additional URLs are NOT Filtered by default; but can be if needed. Use these Filters. */
72
+ if (apply_filters ("_ws_plugin__s2member_force_non_ssl_scheme_content_url", false, get_defined_vars ()))
73
+ add_filter ("content_url", "_ws_plugin__s2member_force_non_ssl_scheme", 10, 2);
74
  /**/
75
  if (!function_exists ("_ws_plugin__s2member_force_ssl_buffer"))
76
  {
77
  function _ws_plugin__s2member_force_ssl_buffer ($buffer = FALSE)
78
  {
79
+ $o_pcre = @ini_get ("pcre.backtrack_limit"); /* Current configuration. */
80
  /**/
81
+ @ini_set ("pcre.backtrack_limit", 10000000); /* Expands abilities for this routine. */
82
  /**/
83
+ $ssl_tags = array ("script", "style", "link", "img", "input", "iframe", "object", "embed");
84
+ $ssl_tags = apply_filters ("_ws_plugin__s2member_force_ssl_buffer_tags_array", $ssl_tags, get_defined_vars ());
85
+ $ssl_tags = array_unique (array_map ("strtolower", $ssl_tags)); /* This array should be lowercase / unique. */
86
  /**/
87
+ $ssl_regex_tags = implode ("|", array_map ("preg_quote", $ssl_tags)); /* Prepare for regex. */
88
  /**/
89
+ $buffer = ($ssl_regex_tags) ? preg_replace_callback ("/\<(" . $ssl_regex_tags . ")(?![a-z_0-9\-])[^\>]+\>/i", "_ws_plugin__s2member_force_ssl_buffer_callback", $buffer) : $buffer;
90
+ $buffer = (in_array ("object", $ssl_tags)) ? preg_replace_callback ("/\<object(?![a-z_0-9\-])[^\>]*\>.*?\<\/object\>/is", "_ws_plugin__s2member_force_ssl_buffer_callback", $buffer) : $buffer;
91
+ $buffer = (in_array ("script", $ssl_tags)) ? preg_replace_callback ("/\<script(?![a-z_0-9\-])[^\>]*\>.*?\<\/script\>/is", "_ws_plugin__s2member_force_ssl_buffer_callback", $buffer) : $buffer;
92
+ $buffer = (in_array ("style", $ssl_tags)) ? preg_replace_callback ("/\<style(?![a-z_0-9\-])[^\>]*\>.*?\<\/style\>/is", "_ws_plugin__s2member_force_ssl_buffer_callback", $buffer) : $buffer;
93
  /**/
94
+ $non_ssl_tags = array ("a"); /* Tags that should NOT contain SSL-enabled links in them. Prevents site-wide conversions */
95
+ $non_ssl_tags = apply_filters ("_ws_plugin__s2member_force_non_ssl_buffer_tags_array", $non_ssl_tags, get_defined_vars ());
96
+ $non_ssl_tags = array_unique (array_map ("strtolower", $non_ssl_tags)); /* This array should be lowercase / unique. */
97
+ /**/
98
+ $non_ssl_regex_tags = implode ("|", array_map ("preg_quote", $non_ssl_tags)); /* Prepare for regex. */
99
+ /**/
100
+ $buffer = ($non_ssl_regex_tags) ? preg_replace_callback ("/\<(" . $non_ssl_regex_tags . ")(?![a-z_0-9\-])[^\>]+\>/i", "_ws_plugin__s2member_force_non_ssl_buffer_callback", $buffer) : $buffer;
101
+ /**/
102
+ @ini_set ("pcre.backtrack_limit", $o_pcre); /* Restores previous configuration value now. */
103
  /**/
104
  return apply_filters ("_ws_plugin__s2member_force_ssl_buffer", $buffer, get_defined_vars ());
105
  }
109
  {
110
  function _ws_plugin__s2member_force_ssl_buffer_callback ($m = FALSE)
111
  {
112
+ $s = preg_replace ("/http\:\/\//i", "https://", $m[0]); /* Conversion. */
113
  /**/
114
  if (_ws_plugin__s2member_force_ssl_port && _ws_plugin__s2member_force_ssl_host && _ws_plugin__s2member_force_ssl_host_port) /* Need port conversions? */
115
+ $s = preg_replace ("/\/" . preg_quote (_ws_plugin__s2member_force_ssl_host, "/") . "(\:[0-9]+)?\//i", "/" . _ws_plugin__s2member_force_ssl_host_port . "/", $s);
116
+ /**/
117
+ $s = (strtolower ($m[1]) === "link" && preg_match ("/['\"]alternate['\"]/i", $m[0])) ? $m[0] : $s; /* Alternates are fine to leave like they are. */
118
+ /**/
119
+ return $s; /* Return string with conversions. */
120
+ }
121
+ }
122
+ /**/
123
+ if (!function_exists ("_ws_plugin__s2member_force_non_ssl_buffer_callback"))
124
+ {
125
+ function _ws_plugin__s2member_force_non_ssl_buffer_callback ($m = FALSE)
126
+ {
127
+ $s = preg_replace ("/https\:\/\/" . preg_quote (_ws_plugin__s2member_force_ssl_host_port, "/") . "/i", "http://" . _ws_plugin__s2member_force_ssl_host, $m[0]);
128
+ /**/
129
+ $s = preg_replace ("/https\:\/\/" . preg_quote (_ws_plugin__s2member_force_ssl_host, "/") . "/i", "http://" . _ws_plugin__s2member_force_ssl_host, $s);
130
+ /*
131
+ Data gets converted to prevent a site-wide conversion over to SSL links.
132
+ */
133
+ return $s; /* Return string with conversions. */
134
+ }
135
+ }
136
+ /**/
137
+ if (!function_exists ("_ws_plugin__s2member_force_non_ssl_scheme"))
138
+ {
139
+ function _ws_plugin__s2member_force_non_ssl_scheme ($url = FALSE, $path = FALSE, $scheme = FALSE)
140
+ {
141
+ if (!in_array ($scheme, array ("http", "https"))) /* If NOT explicitly passed through. */
142
+ {
143
+ /* Allows for special exceptions to the rule of always forcing a non-SSL scheme. */
144
+ if (($scheme === "login_post" || $scheme === "rpc") && (force_ssl_login () || force_ssl_admin ()))
145
+ $scheme = "https";
146
+ else if ($scheme === "login" && force_ssl_admin ())
147
+ $scheme = "https";
148
+ else if ($scheme === "admin" && force_ssl_admin ())
149
+ $scheme = "https";
150
+ else /* Defaults to http. */
151
+ $scheme = "http";
152
+ }
153
  /**/
154
+ $scheme = apply_filters ("_ws_plugin__s2member_force_non_ssl_scheme", $scheme, get_defined_vars ());
155
  /**/
156
+ return preg_replace ("/^http(s)?\:\/\//i", $scheme . "://", $url);
157
  }
158
  }
159
  /**/
includes/classes/ssl.inc.php CHANGED
@@ -19,7 +19,7 @@ if (!class_exists ("c_ws_plugin__s2member_ssl"))
19
  class c_ws_plugin__s2member_ssl
20
  {
21
  /*
22
- Function that forces SSL on specific Posts/Pages.
23
  Attach to: add_action("template_redirect");
24
 
25
  Triggered by Custom Field:
19
  class c_ws_plugin__s2member_ssl
20
  {
21
  /*
22
+ Forces SSL on specific Posts/Pages.
23
  Attach to: add_action("template_redirect");
24
 
25
  Triggered by Custom Field:
includes/classes/user-deletions.inc.php CHANGED
@@ -76,9 +76,12 @@ if (!class_exists ("c_ws_plugin__s2member_user_deletions"))
76
  $subscr_id = get_user_option ("s2member_subscr_id", $user_id); /* And also, EVEN if this is empty. */
77
  $fields = get_user_option ("s2member_custom_fields", $user_id); /* Used in API Notifications. */
78
  /**/
 
 
 
79
  eval ('foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;');
80
  do_action ("ws_plugin__s2member_during_handle_user_before_deletions", get_defined_vars ());
81
- do_action ("ws_plugin__s2member_during_collective_eots", $user_id, get_defined_vars (), "user-removal-deletion");
82
  unset ($__refs, $__v); /* Unset defined __refs, __v. */
83
  /**/
84
  delete_user_option ($user_id, "s2member_custom"); /* Now we can remove these User options ( for this Blog ). */
@@ -99,7 +102,7 @@ if (!class_exists ("c_ws_plugin__s2member_user_deletions"))
99
  {
100
  foreach (preg_split ("/[\r\n\t]+/", $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["eot_del_notification_urls"]) as $url) /* Handle EOT Notifications on user deletion. */
101
  /**/
102
- 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 ($subscr_id)), $url)))
103
  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)))
104
  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)))
105
  if (($url = preg_replace ("/%%user_email%%/i", c_ws_plugin__s2member_utils_strings::esc_ds (urlencode ($user->user_email)), $url)))
@@ -123,6 +126,7 @@ if (!class_exists ("c_ws_plugin__s2member_user_deletions"))
123
  $msg = $sbj = "( s2Member / API Notification Email ) - EOT/Deletion";
124
  $msg .= "\n\n"; /* Spacing in the message body. */
125
  /**/
 
126
  $msg .= "subscr_id: %%subscr_id%%\n";
127
  $msg .= "user_first_name: %%user_first_name%%\n";
128
  $msg .= "user_last_name: %%user_last_name%%\n";
@@ -146,7 +150,7 @@ if (!class_exists ("c_ws_plugin__s2member_user_deletions"))
146
  $msg .= "cv8: %%cv8%%\n";
147
  $msg .= "cv9: %%cv9%%";
148
  /**/
149
- 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 ($subscr_id), $msg)))
150
  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)))
151
  if (($msg = preg_replace ("/%%user_full_name%%/i", c_ws_plugin__s2member_utils_strings::esc_ds (trim ($user->first_name . " " . $user->last_name)), $msg)))
152
  if (($msg = preg_replace ("/%%user_email%%/i", c_ws_plugin__s2member_utils_strings::esc_ds ($user->user_email), $msg)))
76
  $subscr_id = get_user_option ("s2member_subscr_id", $user_id); /* And also, EVEN if this is empty. */
77
  $fields = get_user_option ("s2member_custom_fields", $user_id); /* Used in API Notifications. */
78
  /**/
79
+ $eot_del_type = ($GLOBALS["ws_plugin__s2member_eot_del_type"]) ? $GLOBALS["ws_plugin__s2member_eot_del_type"] : "user-removal-deletion";
80
+ $eot_del_type_spec = ($GLOBALS["ws_plugin__s2member_eot_del_type_spec"]) ? $GLOBALS["ws_plugin__s2member_eot_del_type_spec"] : "removal-deletion";
81
+ /**/
82
  eval ('foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;');
83
  do_action ("ws_plugin__s2member_during_handle_user_before_deletions", get_defined_vars ());
84
+ do_action ("ws_plugin__s2member_during_collective_eots", $user_id, get_defined_vars (), "user-removal-deletion", $eot_del_type_spec);
85
  unset ($__refs, $__v); /* Unset defined __refs, __v. */
86
  /**/
87
  delete_user_option ($user_id, "s2member_custom"); /* Now we can remove these User options ( for this Blog ). */
102
  {
103
  foreach (preg_split ("/[\r\n\t]+/", $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["eot_del_notification_urls"]) as $url) /* Handle EOT Notifications on user deletion. */
104
  /**/
105
+ if (($url = preg_replace ("/%%cv([0-9]+)%%/ei", 'urlencode(trim($cv[$1]))', $url)) && ($url = preg_replace ("/%%eot_del_type%%/i", c_ws_plugin__s2member_utils_strings::esc_ds (urlencode ($eot_del_type)), $url)) && ($url = preg_replace ("/%%subscr_id%%/i", c_ws_plugin__s2member_utils_strings::esc_ds (urlencode ($subscr_id)), $url)))
106
  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)))
107
  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)))
108
  if (($url = preg_replace ("/%%user_email%%/i", c_ws_plugin__s2member_utils_strings::esc_ds (urlencode ($user->user_email)), $url)))
126
  $msg = $sbj = "( s2Member / API Notification Email ) - EOT/Deletion";
127
  $msg .= "\n\n"; /* Spacing in the message body. */
128
  /**/
129
+ $msg .= "eot_del_type: %%eot_del_type%%\n";
130
  $msg .= "subscr_id: %%subscr_id%%\n";
131
  $msg .= "user_first_name: %%user_first_name%%\n";
132
  $msg .= "user_last_name: %%user_last_name%%\n";
150
  $msg .= "cv8: %%cv8%%\n";
151
  $msg .= "cv9: %%cv9%%";
152
  /**/
153
+ if (($msg = preg_replace ("/%%cv([0-9]+)%%/ei", 'trim($cv[$1])', $msg)) && ($msg = preg_replace ("/%%eot_del_type%%/i", c_ws_plugin__s2member_utils_strings::esc_ds ($eot_del_type), $msg)) && ($msg = preg_replace ("/%%subscr_id%%/i", c_ws_plugin__s2member_utils_strings::esc_ds ($subscr_id), $msg)))
154
  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)))
155
  if (($msg = preg_replace ("/%%user_full_name%%/i", c_ws_plugin__s2member_utils_strings::esc_ds (trim ($user->first_name . " " . $user->last_name)), $msg)))
156
  if (($msg = preg_replace ("/%%user_email%%/i", c_ws_plugin__s2member_utils_strings::esc_ds ($user->user_email), $msg)))
includes/classes/user-securities.inc.php CHANGED
@@ -19,25 +19,21 @@ if (!class_exists ("c_ws_plugin__s2member_user_securities"))
19
  class c_ws_plugin__s2member_user_securities
20
  {
21
  /*
22
- Alters `map_meta_cap()` on a Multisite Blog Farm.
23
- Attach to: add_filter("map_meta_cap");
24
  */
25
- public static function ms_map_meta_cap ($caps = FALSE, $cap = FALSE, $user_id = FALSE)
26
  {
27
  eval ('foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;');
28
- do_action ("ws_plugin__s2member_before_ms_map_meta_cap", get_defined_vars ());
29
  unset ($__refs, $__v); /* Unset defined __refs, __v. */
30
  /**/
31
- if (is_multisite () && c_ws_plugin__s2member_utils_conds::is_multisite_farm () && !is_super_admin ())
32
- {
33
- if (in_array ($cap, array_keys ($map = array ("edit_user" => "edit_users", "edit_users" => "edit_users"))))
34
- {
35
- if (is_object ($user = new WP_User ($user_id)) && $user->has_cap ("administrator"))
36
- $caps = array ($map[$cap]);
37
- }
38
- }
39
  /**/
40
- return apply_filters ("ws_plugin__s2member_ms_map_meta_cap", $caps, get_defined_vars ());
41
  }
42
  /*
43
  Alters this Filter inside `/wp-admin/user-edit.php`.
@@ -51,9 +47,9 @@ if (!class_exists ("c_ws_plugin__s2member_user_securities"))
51
  do_action ("ws_plugin__s2member_before_ms_allow_edits", get_defined_vars ());
52
  unset ($__refs, $__v); /* Unset defined __refs, __v. */
53
  /**/
54
- if (is_multisite () && c_ws_plugin__s2member_utils_conds::is_multisite_farm () /* Admins can edit their Users. */
55
- && (is_super_admin () || (current_user_can ("administrator") && $user_id && is_user_member_of_blog ($user_id))))
56
- $allow = true; /* Yes, allow Administrators to edit User Profiles. */
57
  /**/
58
  return apply_filters ("ws_plugin__s2member_ms_allow_edits", $allow, get_defined_vars ());
59
  }
@@ -62,23 +58,23 @@ if (!class_exists ("c_ws_plugin__s2member_user_securities"))
62
 
63
  Demo accounts ( where the Username MUST be "demo" ), will NOT be allowed to change their Password.
64
  Any other restrictions you need to impose must be done through custom programming, using s2Member's Conditionals.
65
- See `s2Member -> API Scripting`.
66
 
67
  Attach to: add_filter("show_password_fields");
68
  */
69
  public static function hide_password_fields ($show = TRUE, $user = FALSE)
70
  {
71
- global $current_user; /* Need the $current_user global var. */
72
- /**/
73
  eval ('foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;');
74
  do_action ("ws_plugin__s2member_before_hide_password_fields", get_defined_vars ());
75
  unset ($__refs, $__v); /* Unset defined __refs, __v. */
76
  /**/
77
- if (is_multisite () && c_ws_plugin__s2member_utils_conds::is_multisite_farm () && !is_super_admin () && is_object ($user) && is_object ($current_user) && $user->ID !== $current_user->ID)
78
- $show = false;
 
 
79
  /**/
80
- else if (is_object ($user) && $user->user_login === "demo") /* Lock Password on Demo accounts. */
81
- $show = false;
82
  /**/
83
  return apply_filters ("ws_plugin__s2member_hide_password_fields", $show, get_defined_vars ());
84
  }
19
  class c_ws_plugin__s2member_user_securities
20
  {
21
  /*
22
+ Alters `WP_User->has_cap()` on a Multisite Blog Farm.
23
+ Attach to: add_filter("user_has_cap");
24
  */
25
+ public static function ms_user_capabilities ($capabilities = FALSE, $caps_map = FALSE, $args = FALSE)
26
  {
27
  eval ('foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;');
28
+ do_action ("ws_plugin__s2member_before_ms_user_capabilities", get_defined_vars ());
29
  unset ($__refs, $__v); /* Unset defined __refs, __v. */
30
  /**/
31
+ if (is_multisite () && c_ws_plugin__s2member_utils_conds::is_multisite_farm ())
32
+ if ((is_super_admin () || $capabilities["administrator"]) && ($args[0] === "edit_user" || $args[0] === "edit_users"))
33
+ if ($args[0] === "edit_users" || ($args[0] === "edit_user" && $args[2] && ((int)$args[1] === (int)$args[2] || is_user_member_of_blog ($args[2]))))
34
+ $capabilities = array_merge ($capabilities, array ("edit_users" => 1, "do_not_allow" => 1));
 
 
 
 
35
  /**/
36
+ return apply_filters ("ws_plugin__s2member_ms_user_capabilities", $capabilities, get_defined_vars ());
37
  }
38
  /*
39
  Alters this Filter inside `/wp-admin/user-edit.php`.
47
  do_action ("ws_plugin__s2member_before_ms_allow_edits", get_defined_vars ());
48
  unset ($__refs, $__v); /* Unset defined __refs, __v. */
49
  /**/
50
+ if (is_multisite () && c_ws_plugin__s2member_utils_conds::is_multisite_farm ())
51
+ if (is_super_admin () || (current_user_can ("administrator") && $user_id && is_user_member_of_blog ($user_id)))
52
+ $allow = true; /* Yes, allow Administrators to edit User Profiles. */
53
  /**/
54
  return apply_filters ("ws_plugin__s2member_ms_allow_edits", $allow, get_defined_vars ());
55
  }
58
 
59
  Demo accounts ( where the Username MUST be "demo" ), will NOT be allowed to change their Password.
60
  Any other restrictions you need to impose must be done through custom programming, using s2Member's Conditionals.
61
+ See `s2Member -> API Scripting`.
62
 
63
  Attach to: add_filter("show_password_fields");
64
  */
65
  public static function hide_password_fields ($show = TRUE, $user = FALSE)
66
  {
 
 
67
  eval ('foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;');
68
  do_action ("ws_plugin__s2member_before_hide_password_fields", get_defined_vars ());
69
  unset ($__refs, $__v); /* Unset defined __refs, __v. */
70
  /**/
71
+ if ($show && is_multisite () && c_ws_plugin__s2member_utils_conds::is_multisite_farm ())
72
+ if (!is_super_admin () && is_object ($user) && is_object ($current_user = wp_get_current_user ()))
73
+ if ($user->ID !== $current_user->ID)
74
+ $show = false;
75
  /**/
76
+ if ($show && is_object ($user) && $user->user_login === "demo") /* Lock Password on Demos. */
77
+ $show = false; /* Lock Password on Demos. */
78
  /**/
79
  return apply_filters ("ws_plugin__s2member_hide_password_fields", $show, get_defined_vars ());
80
  }
includes/classes/users-list-in.inc.php CHANGED
@@ -403,7 +403,7 @@ if (!class_exists ("c_ws_plugin__s2member_users_list_in"))
403
  /**/
404
  update_user_option ($user_id, "s2member_custom_fields", $fields);
405
  /**/
406
- if ($level > 0) /* We ONLY process this if they are higher than Level#0. */
407
  {
408
  $pr_times = get_user_option ("s2member_paid_registration_times", $user_id);
409
  $pr_times["level"] = (!$pr_times["level"]) ? time () : $pr_times["level"]; /* Preserve. */
@@ -412,7 +412,7 @@ if (!class_exists ("c_ws_plugin__s2member_users_list_in"))
412
  }
413
  /**/
414
  if ($_p["ws_plugin__s2member_profile_opt_in"]) /* Should we process List Servers for this User? */
415
- c_ws_plugin__s2member_list_servers::process_list_servers (c_ws_plugin__s2member_user_access::user_access_role ($user), c_ws_plugin__s2member_user_access::user_access_level ($user), $user->user_email, $user->first_name, $user->last_name, "", true, $user_id);
416
  /**/
417
  if ($_p["ws_plugin__s2member_profile_ip_restrictions"]) /* Delete/reset IP Restrictions? */
418
  c_ws_plugin__s2member_ip_restrictions::delete_reset_specific_ip_restrictions (strtolower ($user->user_login));
403
  /**/
404
  update_user_option ($user_id, "s2member_custom_fields", $fields);
405
  /**/
406
+ if ($level > 0) /* We ONLY process this if they are higher than Level #0. */
407
  {
408
  $pr_times = get_user_option ("s2member_paid_registration_times", $user_id);
409
  $pr_times["level"] = (!$pr_times["level"]) ? time () : $pr_times["level"]; /* Preserve. */
412
  }
413
  /**/
414
  if ($_p["ws_plugin__s2member_profile_opt_in"]) /* Should we process List Servers for this User? */
415
+ c_ws_plugin__s2member_list_servers::process_list_servers (c_ws_plugin__s2member_user_access::user_access_role ($user), c_ws_plugin__s2member_user_access::user_access_level ($user), $user->user_login, $_p["pass1"], $user->user_email, $user->first_name, $user->last_name, false, true, $user_id);
416
  /**/
417
  if ($_p["ws_plugin__s2member_profile_ip_restrictions"]) /* Delete/reset IP Restrictions? */
418
  c_ws_plugin__s2member_ip_restrictions::delete_reset_specific_ip_restrictions (strtolower ($user->user_login));
includes/classes/users-list.inc.php CHANGED
@@ -136,7 +136,8 @@ if (!class_exists ("c_ws_plugin__s2member_users_list"))
136
  unset ($__refs, $__v); /* Unset defined __refs, __v. */
137
  /**/
138
  $cols["s2member_registration_time"] = "Registration Date"; /* Date they signed up. */
139
- $cols["s2member_paid_registration_times"] = "Paid Registr. Date"; /* Payment Times. */
 
140
  $cols["s2member_subscr_id"] = "Paid Subscr. ID"; /* Special field that is always applied. */
141
  /**/
142
  if (!is_multisite () || !c_ws_plugin__s2member_utils_conds::is_multisite_farm () || is_main_site ())
136
  unset ($__refs, $__v); /* Unset defined __refs, __v. */
137
  /**/
138
  $cols["s2member_registration_time"] = "Registration Date"; /* Date they signed up. */
139
+ if (apply_filters ("ws_plugin__s2member_users_list_cols_display_paid_registration_times", false))
140
+ $cols["s2member_paid_registration_times"] = "Paid Registr. Date"; /* Payment Times. */
141
  $cols["s2member_subscr_id"] = "Paid Subscr. ID"; /* Special field that is always applied. */
142
  /**/
143
  if (!is_multisite () || !c_ws_plugin__s2member_utils_conds::is_multisite_farm () || is_main_site ())
includes/classes/utils-arrays.inc.php CHANGED
@@ -19,7 +19,7 @@ if (!class_exists ("c_ws_plugin__s2member_utils_arrays"))
19
  class c_ws_plugin__s2member_utils_arrays
20
  {
21
  /*
22
- Function that extends array_unique to support multi-dimensional arrays.
23
  */
24
  public static function array_unique ($array = FALSE)
25
  {
@@ -45,20 +45,19 @@ if (!class_exists ("c_ws_plugin__s2member_utils_arrays"))
45
  }
46
  }
47
  /*
48
- Function that searches a multi-dimensional array using a regular expression match against array values.
49
  */
50
  public static function regex_in_array ($regex = FALSE, $array = FALSE)
51
  {
52
- if ($regex && is_array ($array))
53
  {
54
  foreach ($array as $value)
55
  {
56
- if (is_array ($value)) /* Recursive function call. */
57
  {
58
  if (c_ws_plugin__s2member_utils_arrays::regex_in_array ($regex, $value))
59
  return true;
60
  }
61
- /**/
62
  else if (is_string ($value)) /* Must be a string. */
63
  {
64
  if (@preg_match ($regex, $value))
@@ -71,6 +70,32 @@ if (!class_exists ("c_ws_plugin__s2member_utils_arrays"))
71
  else /* False. */
72
  return false;
73
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
74
  }
75
  }
76
  ?>
19
  class c_ws_plugin__s2member_utils_arrays
20
  {
21
  /*
22
+ Extends array_unique to support multi-dimensional arrays.
23
  */
24
  public static function array_unique ($array = FALSE)
25
  {
45
  }
46
  }
47
  /*
48
+ Searches a multi-dimensional array using a regular expression match against array values.
49
  */
50
  public static function regex_in_array ($regex = FALSE, $array = FALSE)
51
  {
52
+ if (is_string ($regex) && strlen ($regex) && is_array ($array))
53
  {
54
  foreach ($array as $value)
55
  {
56
+ if (is_array ($value)) /* Recursive function call? */
57
  {
58
  if (c_ws_plugin__s2member_utils_arrays::regex_in_array ($regex, $value))
59
  return true;
60
  }
 
61
  else if (is_string ($value)) /* Must be a string. */
62
  {
63
  if (@preg_match ($regex, $value))
70
  else /* False. */
71
  return false;
72
  }
73
+ /*
74
+ Searches a multi-dimensional array of regular expressions, to match against a string value.
75
+ */
76
+ public static function in_regex_array ($string = FALSE, $array = FALSE)
77
+ {
78
+ if (is_string ($string) && strlen ($string) && is_array ($array))
79
+ {
80
+ foreach ($array as $value)
81
+ {
82
+ if (is_array ($value)) /* Recursive function call. */
83
+ {
84
+ if (c_ws_plugin__s2member_utils_arrays::in_regex_array ($string, $value))
85
+ return true;
86
+ }
87
+ else if (is_string ($value)) /* Must be a string. */
88
+ {
89
+ if (@preg_match ($value, $string))
90
+ return true;
91
+ }
92
+ }
93
+ /**/
94
+ return false;
95
+ }
96
+ else /* False. */
97
+ return false;
98
+ }
99
  }
100
  }
101
  ?>
includes/classes/utils-dirs.inc.php CHANGED
@@ -24,7 +24,7 @@ if (!class_exists ("c_ws_plugin__s2member_utils_dirs"))
24
  */
25
  public static function basename_dirs ($dir_path = FALSE)
26
  {
27
- $dir_path = rtrim ($dir_path, DIRECTORY_SEPARATOR);
28
  /**/
29
  $dir_path = preg_replace ("/(" . preg_quote (DIRECTORY_SEPARATOR, "/") . "|\/)app_data$/i", "", $dir_path, 1, $app_data);
30
  /**/
@@ -35,7 +35,7 @@ if (!class_exists ("c_ws_plugin__s2member_utils_dirs"))
35
  */
36
  public static function strip_dir_app_data ($dir_path = FALSE)
37
  {
38
- $dir_path = rtrim ($dir_path, DIRECTORY_SEPARATOR);
39
  /**/
40
  return preg_replace ("/(" . preg_quote (DIRECTORY_SEPARATOR, "/") . "|\/)app_data$/i", "", $dir_path, 1);
41
  }
24
  */
25
  public static function basename_dirs ($dir_path = FALSE)
26
  {
27
+ $dir_path = rtrim ($dir_path, DIRECTORY_SEPARATOR . "/");
28
  /**/
29
  $dir_path = preg_replace ("/(" . preg_quote (DIRECTORY_SEPARATOR, "/") . "|\/)app_data$/i", "", $dir_path, 1, $app_data);
30
  /**/
35
  */
36
  public static function strip_dir_app_data ($dir_path = FALSE)
37
  {
38
+ $dir_path = rtrim ($dir_path, DIRECTORY_SEPARATOR . "/");
39
  /**/
40
  return preg_replace ("/(" . preg_quote (DIRECTORY_SEPARATOR, "/") . "|\/)app_data$/i", "", $dir_path, 1);
41
  }
includes/classes/utils-urls.inc.php CHANGED
@@ -19,46 +19,46 @@ if (!class_exists ("c_ws_plugin__s2member_utils_urls"))
19
  class c_ws_plugin__s2member_utils_urls
20
  {
21
  /*
22
- Function that builds a WordPress® signup URL /wp-signup.php.
23
  */
24
  public static function wp_signup_url () /* With Filters. */
25
  {
26
  return apply_filters ("wp_signup_location", site_url ("/wp-signup.php"));
27
  }
28
  /*
29
- Function that builds a WordPress® registration URL /wp-login.php?action=register.
30
  */
31
  public static function wp_register_url ($redirect_to = FALSE)
32
  {
33
- return add_query_arg ("action", urlencode ("register"), wp_login_url ($redirect_to));
 
34
  }
35
  /*
36
- Function that handles a remote request.
37
- This extends wp_remote_request() through the `WP_Http` class.
38
  */
39
  public static function remote ($url = FALSE, $post_vars = FALSE, $args = array ())
40
  {
41
- static $http_response_filtered = false; /* Filter once. */
42
  /**/
43
- $args = (!is_array ($args)) ? array (): $args;
 
44
  /**/
45
  if (!$http_response_filtered && ($http_response_filtered = true))
46
  add_filter ("http_response", "c_ws_plugin__s2member_utils_urls::_remote_gz_variations");
47
  /**/
48
- if ($url) /* Obviously, we must have a URL to do anything. */
49
  {
50
  if (preg_match ("/^https/i", $url) && strtolower (substr (PHP_OS, 0, 3)) === "win")
51
- add_filter ("use_curl_transport", "__return_false");
52
  /**/
53
  if ((is_array ($post_vars) || is_string ($post_vars)) && !empty ($post_vars))
54
- {
55
- $args["method"] = "POST";
56
- $args["body"] = $post_vars;
57
- }
58
  /**/
59
  $body = wp_remote_retrieve_body (wp_remote_request ($url, $args));
60
  /**/
61
- remove_filter ("use_curl_transport", "__return_false");
 
62
  /**/
63
  return $body; /* The body content received. */
64
  }
@@ -66,7 +66,7 @@ if (!class_exists ("c_ws_plugin__s2member_utils_urls"))
66
  return false; /* Else return false. */
67
  }
68
  /*
69
- A sort of callback function that filters the WP_Http response for additional gzinflate variations.
70
  Attach to: add_filter("http_response");
71
  */
72
  public static function _remote_gz_variations ($response = array ())
19
  class c_ws_plugin__s2member_utils_urls
20
  {
21
  /*
22
+ Builds a WordPress® signup URL /wp-signup.php.
23
  */
24
  public static function wp_signup_url () /* With Filters. */
25
  {
26
  return apply_filters ("wp_signup_location", site_url ("/wp-signup.php"));
27
  }
28
  /*
29
+ Builds a WordPress® registration URL /wp-login.php?action=register.
30
  */
31
  public static function wp_register_url ($redirect_to = FALSE)
32
  {
33
+ return apply_filters ("wp_register_location", /* « NOT a core Filter; we're anticipating this. */
34
+ add_query_arg ("action", urlencode ("register"), wp_login_url ($redirect_to)), get_defined_vars ());
35
  }
36
  /*
37
+ Responsible for remote communications processed by this plugin.
38
+ `wp_remote_request()` through the `WP_Http` class.
39
  */
40
  public static function remote ($url = FALSE, $post_vars = FALSE, $args = array ())
41
  {
42
+ static $http_response_filtered = false; /* Apply GZ filters only once. */
43
  /**/
44
+ $args = (!is_array ($args)) ? array (): $args; /* Disable SSL verifications. */
45
+ $args["sslverify"] = (!isset ($args["sslverify"])) ? false : $args["sslverify"];
46
  /**/
47
  if (!$http_response_filtered && ($http_response_filtered = true))
48
  add_filter ("http_response", "c_ws_plugin__s2member_utils_urls::_remote_gz_variations");
49
  /**/
50
+ if ($url) /* Obviously, we must have a valid URL before we do anything at all here. */
51
  {
52
  if (preg_match ("/^https/i", $url) && strtolower (substr (PHP_OS, 0, 3)) === "win")
53
+ add_filter ("use_curl_transport", "__return_false", ($curl_disabled = 1352));
54
  /**/
55
  if ((is_array ($post_vars) || is_string ($post_vars)) && !empty ($post_vars))
56
+ $args = array_merge ($args, array ("method" => "POST", "body" => $post_vars));
 
 
 
57
  /**/
58
  $body = wp_remote_retrieve_body (wp_remote_request ($url, $args));
59
  /**/
60
+ if ($curl_was_disabled_by_this_routine_with_1352_priority = $curl_disabled)
61
+ remove_filter ("use_curl_transport", "__return_false", 1352);
62
  /**/
63
  return $body; /* The body content received. */
64
  }
66
  return false; /* Else return false. */
67
  }
68
  /*
69
+ Filters the WP_Http response for additional gzinflate variations.
70
  Attach to: add_filter("http_response");
71
  */
72
  public static function _remote_gz_variations ($response = array ())
includes/dropins/bridges/_s2member-bbpress-bridge.php CHANGED
@@ -1,12 +1,12 @@
1
  <?php
2
  /*
3
- Version: 1.0.2
4
- Stable tag: 1.0.2
5
  Framework: WS-BB-DIP-1.0
6
 
7
- Tested up to: 1.0.2
8
- Requires at least: 1.0.2
9
- Requires: s2Member 3.2+, bbPress® 1.0.2+
10
 
11
  Copyright: © 2009 WebSharks, Inc.
12
  License: GNU General Public License
@@ -18,7 +18,7 @@ Donate link: http://www.primothemes.com/donate/
18
  Plugin Name: s2Member Bridge
19
  Pro Module / Prices: http://www.s2member.com/prices/
20
  Forum URI: http://www.primothemes.com/forums/viewforum.php?f=4
21
- Professional Installation URI: http://www.primothemes.com/forums/viewtopic.php?f=4&t=107
22
  Plugin URI: http://www.primothemes.com/post/product/s2member-membership-plugin-with-paypal/
23
  Description: Blocks all non-Member access to bbPress® forums. Only the login-page is available. Forum registration is redirected to your Membership Options Page for s2Member ( on your main WordPress® installation ). This way, a visitor can signup on your site, and gain Membership Access to your forums. This plugin will NOT work, until you've successfully integrated WordPress® into bbPress®. See: `bbPress® -> Settings -> WordPress® Integration`.
24
  Tags: membership, members, member, register, signup, paypal, pay pal, s2member, subscriber, members only, bbpress, bb press, forums, forum, buddypress, buddy press, buddy press compatible, shopping cart, checkout, api, options panel included, websharks framework, w3c validated code, multi widget support, includes extensive documentation, highly extensible
@@ -29,91 +29,175 @@ Direct access denial.
29
  if (realpath (__FILE__) === realpath ($_SERVER["SCRIPT_FILENAME"]))
30
  exit ("Do not access this file directly.");
31
  /*
32
- Filled by the s2Member installer. Or you can set this manually.
33
- - If this is NOT set, it defaults to 0 = ( Free Subscribers ).
 
34
  */
35
- define ("WS_PLUGIN__S2MEMBER_BRIDGE_BBPRESS_MIN_LEVEL", "%%min%%");
 
 
36
  /*
37
  Convert s2Member Roles into bbPress® "Members" on-the-fly.
38
  - Only when no bbPress® Role has been assigned yet.
39
  - This way a site owner can still modify Roles.
40
  */
41
- add_action ("bb_init", "ws_plugin__s2member_bridge_bbpress_roles");
42
  /**/
43
- function ws_plugin__s2member_bridge_bbpress_roles () /* On-the-fly. */
44
  {
45
- $wp_capabilities = bb_get_option ("wp_table_prefix") . "capabilities";
46
- /**/
47
- if (is_object ($user = bb_get_current_user ()) && $user->ID) /* Logged in? */
48
- /**/
49
- if (empty ($user->roles)) /* Only if/when no bbPress® Role is assigned. */
 
 
 
 
50
  /**/
51
- bb_give_user_default_role($user); /* Assign a default Role. */
 
52
  }
53
  /*
54
  Deny all access to the bbPress® registration page.
55
  This will leave the bbPress® login page available, as it should be.
56
- - Also deny all access to anyone that does NOT have permission to participate.
57
- In other words, anyone who is NOT at least a bbPress® Member Role.
58
- - Also deny access to s2Member Roles that are NOT at a high enough Level.
59
  */
60
- add_action ("bb_init", "ws_plugin__s2member_bridge_bbpress_access");
61
  /**/
62
- function ws_plugin__s2member_bridge_bbpress_access () /* Check Access. */
63
  {
64
- $min = (int)WS_PLUGIN__S2MEMBER_BRIDGE_BBPRESS_MIN_LEVEL; /* Or 0. */
65
- /**/
66
- $location = bb_get_location (); /* The current navigation location. */
67
- /**/
68
- $wp_capabilities = bb_get_option ("wp_table_prefix") . "capabilities";
69
- /**/
70
- if (!in_array ($location, array ("login-page", "register-page")))
71
  {
72
- if (!bb_is_user_logged_in () || !bb_current_user_can ("participate"))
 
 
 
 
 
 
 
 
 
73
  {
74
- if ($url = bb_get_option ("wp_siteurl")) /* WordPress® is integrated? */
75
  {
76
- $bbPress = bb_get_option ("uri"); /* bbPress® location. */
77
- /**/
78
- if (preg_match ("/^" . preg_quote ($bbPress, "/") . "/", $_SERVER["HTTP_REFERER"]))
79
- wp_redirect ($url, apply_filters ("ws_plugin__s2member_content_redirect_status", 301, get_defined_vars ()));
80
- /**/
81
- else /* Otherwise, trigger the Membership Options Page + s2member_level_req = $min. */
82
- wp_redirect ($url . "/?s2member_membership_options_page=1&s2member_seeking=bbpress&s2member_level_req=" . urlencode ($min), apply_filters ("ws_plugin__s2member_content_redirect_status", 301, get_defined_vars ()));
83
- /**/
84
- exit ();
85
- }
86
- }
87
- /**/
88
- else if (is_object ($user = bb_get_current_user ()) && $user->ID) /* Logged in? / Got User object? */
89
- /**/
90
- foreach ($user->$wp_capabilities as $wp_cap => $v) /* Looking for ^(subscriber|s2member_level[0-4])$. */
91
- /**/
92
- if (preg_match ("/^(subscriber|s2member_level[0-4])$/", $wp_cap)) /* Subscribers and/or s2Member Roles. */
93
- /**/
94
- if (($wp_cap === "subscriber" && $min > 0) || ($level = preg_replace ("/^s2member_level/", "", $wp_cap)) < $min)
95
- /**/
96
- if ($url = bb_get_option ("wp_siteurl")) /* Only if WordPress® is fully integrated? */
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
97
  {
98
- $bbPress = bb_get_option ("uri"); /* bbPress® location. */
99
  /**/
100
- if (preg_match ("/^" . preg_quote ($bbPress, "/") . "/", $_SERVER["HTTP_REFERER"]))
101
- wp_redirect ($url, apply_filters ("ws_plugin__s2member_content_redirect_status", 301, get_defined_vars ()));
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
102
  /**/
103
- else /* Otherwise, trigger the Membership Options Page + s2member_level_req = $min. */
104
- wp_redirect ($url . "/?s2member_membership_options_page=1&s2member_seeking=bbpress&s2member_level_req=" . urlencode ($min), apply_filters ("ws_plugin__s2member_content_redirect_status", 301, get_defined_vars ()));
105
  /**/
106
- exit ();
 
 
 
 
 
 
 
 
 
 
 
107
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
108
  }
109
- /**/
110
- else if (in_array ($location, array ("register-page"))) /* Send registration requests through WP. */
 
 
 
 
 
 
111
  {
112
- if ($url = bb_get_option ("wp_siteurl")) /* The Front Page on the WordPress® installation. */
 
 
113
  {
114
- wp_redirect ($url . "/?s2member_membership_options_page=1&s2member_seeking=bbpress&s2member_level_req=" . urlencode ($min), apply_filters ("ws_plugin__s2member_content_redirect_status", 301, get_defined_vars ()));
115
- exit (); /* Membership Options Page + s2member_level_req = $min. */
 
116
  }
 
 
117
  }
118
  }
119
  ?>
1
  <?php
2
  /*
3
+ Version: 1.0.3
4
+ Stable tag: 1.0.3
5
  Framework: WS-BB-DIP-1.0
6
 
7
+ Tested up to: 1.0.3
8
+ Requires at least: 1.0.3
9
+ Requires: s2Member 3.5.3+, bbPress® 1.0.3+
10
 
11
  Copyright: © 2009 WebSharks, Inc.
12
  License: GNU General Public License
18
  Plugin Name: s2Member Bridge
19
  Pro Module / Prices: http://www.s2member.com/prices/
20
  Forum URI: http://www.primothemes.com/forums/viewforum.php?f=4
21
+ Professional Installation URI: http://www.s2member.com/professional-installation/
22
  Plugin URI: http://www.primothemes.com/post/product/s2member-membership-plugin-with-paypal/
23
  Description: Blocks all non-Member access to bbPress® forums. Only the login-page is available. Forum registration is redirected to your Membership Options Page for s2Member ( on your main WordPress® installation ). This way, a visitor can signup on your site, and gain Membership Access to your forums. This plugin will NOT work, until you've successfully integrated WordPress® into bbPress®. See: `bbPress® -> Settings -> WordPress® Integration`.
24
  Tags: membership, members, member, register, signup, paypal, pay pal, s2member, subscriber, members only, bbpress, bb press, forums, forum, buddypress, buddy press, buddy press compatible, shopping cart, checkout, api, options panel included, websharks framework, w3c validated code, multi widget support, includes extensive documentation, highly extensible
29
  if (realpath (__FILE__) === realpath ($_SERVER["SCRIPT_FILENAME"]))
30
  exit ("Do not access this file directly.");
31
  /*
32
+ These are filled by the s2Member installer. Or you can set these manually.
33
+ - Participation Level = Member Level # required for participation.
34
+ - Open Viewing = 1 ( on ) or 0 ( off ).
35
  */
36
+ define ("WS_PLUGIN__S2MEMBER_BRIDGE_BBPRESS_ALLOW_OPEN_VIEWING", "%%ovg%%");
37
+ define ("WS_PLUGIN__S2MEMBER_BRIDGE_BBPRESS_MIN_PARTICIPATION_LEVEL", "%%min%%");
38
+ /* -------------------------------------------------------------------------- */
39
  /*
40
  Convert s2Member Roles into bbPress® "Members" on-the-fly.
41
  - Only when no bbPress® Role has been assigned yet.
42
  - This way a site owner can still modify Roles.
43
  */
44
+ add_action ("bb_init", "ws_plugin__s2member_bridge_bbpress_roles", 1);
45
  /**/
46
+ if (!function_exists ("ws_plugin__s2member_bridge_bbpress_roles"))
47
  {
48
+ function ws_plugin__s2member_bridge_bbpress_roles () /* On-the-fly. */
49
+ {
50
+ if (is_object ($user = bb_get_current_user ()) && $user->ID) /* Logged in? */
51
+ {
52
+ if (empty ($user->roles)) /* Only if/when no bbPress® Role is assigned. */
53
+ {
54
+ bb_give_user_default_role ($user); /* Assign default Role. */
55
+ }
56
+ }
57
  /**/
58
+ return; /* Return for uniformity. */
59
+ }
60
  }
61
  /*
62
  Deny all access to the bbPress® registration page.
63
  This will leave the bbPress® login page available, as it should be.
64
+ - This is also the overall bbPress® security gate for s2Member.
 
 
65
  */
66
+ add_action ("bb_init", "ws_plugin__s2member_bridge_bbpress_access", 1);
67
  /**/
68
+ if (!function_exists ("ws_plugin__s2member_bridge_bbpress_access"))
69
  {
70
+ function ws_plugin__s2member_bridge_bbpress_access ()
 
 
 
 
 
 
71
  {
72
+ $location = bb_get_location (); /* The current location. */
73
+ /**/
74
+ $wp_caps = bb_get_option ("wp_table_prefix") . "capabilities";
75
+ /**/
76
+ $ovg = (int)WS_PLUGIN__S2MEMBER_BRIDGE_BBPRESS_ALLOW_OPEN_VIEWING;
77
+ $min = (int)WS_PLUGIN__S2MEMBER_BRIDGE_BBPRESS_MIN_PARTICIPATION_LEVEL;
78
+ /**/
79
+ $open_viewing_possible = $ovg; /* Use this for additional clarity. */
80
+ /**/
81
+ if (!in_array ($location, array ("login-page", "register-page")))
82
  {
83
+ if ($url = bb_get_option ("wp_siteurl")) /* WordPress® integrated? */
84
  {
85
+ if (!$open_viewing_possible) /* If Open Viewing is NOT possible. */
86
+ {
87
+ if (!bb_is_user_logged_in () || !bb_current_user_can ("participate"))
88
+ {
89
+ $bbPress = bb_get_option ("url"); /* bbPress® URL location. */
90
+ /**/
91
+ if (preg_match ("/^" . preg_quote ($bbPress, "/") . "/", $_SERVER["HTTP_REFERER"]))
92
+ wp_redirect ($url, apply_filters ("ws_plugin__s2member_content_redirect_status", 301, get_defined_vars ()));
93
+ /**/
94
+ else /* Otherwise, trigger the Membership Options Page + s2member_level_req = $min. */
95
+ wp_redirect ($url . "/?s2member_membership_options_page=1&s2member_seeking=bbpress&s2member_level_req=" . urlencode ($min), apply_filters ("ws_plugin__s2member_content_redirect_status", 301, get_defined_vars ()));
96
+ /**/
97
+ exit (); /* Clean exit. */
98
+ }
99
+ else if (is_object ($user = bb_get_current_user ()) && $user->ID && isset ($user->$wp_caps) && is_array ($user->$wp_caps))
100
+ {
101
+ $wp_role = reset (array_keys ($user->$wp_caps)); /* Looking for ^(subscriber|s2member_level[0-9]+)$. */
102
+ /**/
103
+ if (preg_match ("/^(subscriber|s2member_level[0-9]+)$/", $wp_role)) /* Subscribers and/or s2 Roles. */
104
+ {
105
+ if (($wp_role === "subscriber" && $min > 0) || ($level = str_replace ("s2member_level", "", $wp_role)) < $min)
106
+ {
107
+ $bbPress = bb_get_option ("url"); /* bbPress® URL location. */
108
+ /**/
109
+ if (preg_match ("/^" . preg_quote ($bbPress, "/") . "/", $_SERVER["HTTP_REFERER"]))
110
+ wp_redirect ($url, apply_filters ("ws_plugin__s2member_content_redirect_status", 301, get_defined_vars ()));
111
+ /**/
112
+ else /* Otherwise, redirect this User to your Membership Options Page. */
113
+ wp_redirect ($url . "/?s2member_membership_options_page=1&s2member_seeking=bbpress&s2member_level_req=" . urlencode ($min), apply_filters ("ws_plugin__s2member_content_redirect_status", 301, get_defined_vars ()));
114
+ /**/
115
+ exit (); /* Clean exit. */
116
+ }
117
+ }
118
+ }
119
+ }
120
+ else if ($open_viewing_possible) /* Else, if Open Viewing IS possible. */
121
  {
122
+ add_filter ("bb_current_user_can", "_ws_plugin__s2member_bridge_bbpress_access_caps", 10, 2);
123
  /**/
124
+ if (!function_exists ("_ws_plugin__s2member_bridge_bbpress_access_caps"))
125
+ {
126
+ function _ws_plugin__s2member_bridge_bbpress_access_caps ($can = FALSE, $cap = FALSE)
127
+ {
128
+ $wp_caps = bb_get_option ("wp_table_prefix") . "capabilities";
129
+ /**/
130
+ $min = (int)WS_PLUGIN__S2MEMBER_BRIDGE_BBPRESS_MIN_PARTICIPATION_LEVEL;
131
+ /**/
132
+ if (!bb_is_user_logged_in ()) /* If/when they're NOT logged in; read-only. */
133
+ {
134
+ return ($cap === "read") ? true : false; /* Read-only access. */
135
+ }
136
+ else if (is_object ($user = bb_get_current_user ()) && $user->ID && isset ($user->$wp_caps) && is_array ($user->$wp_caps))
137
+ {
138
+ $wp_role = reset (array_keys ($user->$wp_caps)); /* Looking for ^(subscriber|s2member_level[0-9]+)$. */
139
+ /**/
140
+ if (preg_match ("/^(subscriber|s2member_level[0-9]+)$/", $wp_role)) /* Subscribers and/or s2 Roles. */
141
+ {
142
+ if (($wp_role === "subscriber" && $min > 0) || ($level = str_replace ("s2member_level", "", $wp_role)) < $min)
143
+ {
144
+ return ($cap === "read") ? true : false;
145
+ }
146
+ }
147
+ }
148
+ /* Whatever bbPress® says. */
149
+ return $can; /* Default. */
150
+ }
151
+ }
152
  /**/
153
+ add_action ("post_post_form", "_ws_plugin__s2member_bridge_bbpress_access_post_form");
 
154
  /**/
155
+ if (!function_exists ("_ws_plugin__s2member_bridge_bbpress_access_post_form"))
156
+ {
157
+ function _ws_plugin__s2member_bridge_bbpress_access_post_form ()
158
+ {
159
+ $min = (int)WS_PLUGIN__S2MEMBER_BRIDGE_BBPRESS_MIN_PARTICIPATION_LEVEL;
160
+ /**/
161
+ if (bb_is_user_logged_in () && !bb_current_user_can ("participate")) /* Unable to participate? */
162
+ {
163
+ echo '<p class="upgrade-line">Your Membership needs to be <a href="' . esc_attr (bb_get_option ("wp_siteurl") . "/?s2member_membership_options_page=1&s2member_seeking=bbpress&s2member_level_req=" . urlencode ($min)) . '" class="upgrade-link">upgraded</a> before you can Post.</p>';
164
+ }
165
+ }
166
+ }
167
  }
168
+ }
169
+ }
170
+ else if (in_array ($location, array ("register-page"))) /* Send registration requests through WP. */
171
+ {
172
+ if ($url = bb_get_option ("wp_siteurl")) /* This will redirect registrants to your Membership Options Page. */
173
+ {
174
+ wp_redirect ($url . "/?s2member_membership_options_page=1&s2member_seeking=bbpress&s2member_level_req=" . urlencode ($min), apply_filters ("ws_plugin__s2member_content_redirect_status", 301, get_defined_vars ()));
175
+ /**/
176
+ exit (); /* Clean exit. */
177
+ }
178
+ }
179
+ /**/
180
+ return; /* Return for uniformity. */
181
  }
182
+ }
183
+ /* -------------------------------------------------------------------------- */
184
+ /*
185
+ API function for Role Conditionals in bbPress®.
186
+ */
187
+ if (!function_exists ("current_wp_user_is"))
188
+ {
189
+ function current_wp_user_is ($role = FALSE)
190
  {
191
+ $wp_caps = bb_get_option ("wp_table_prefix") . "capabilities";
192
+ /**/
193
+ if ($role && is_object ($user = bb_get_current_user ()) && $user->ID && isset ($user->$wp_caps) && is_array ($user->$wp_caps))
194
  {
195
+ $wp_role = reset (array_keys ($user->$wp_caps));
196
+ /**/
197
+ return ($wp_role === $role);
198
  }
199
+ else /* Nope. */
200
+ return false;
201
  }
202
  }
203
  ?>
includes/hooks.inc.php CHANGED
@@ -59,7 +59,7 @@ add_action ("wpmu_delete_user", "c_ws_plugin__s2member_user_deletions::handle_ms
59
  add_action ("remove_user_from_blog", "c_ws_plugin__s2member_user_deletions::handle_ms_user_deletions", 10, 2);
60
  /**/
61
  add_filter ("enable_edit_any_user_configuration", "c_ws_plugin__s2member_user_securities::ms_allow_edits");
62
- add_filter ("map_meta_cap", "c_ws_plugin__s2member_user_securities::ms_map_meta_cap", 10, 3);
63
  /**/
64
  add_filter ("pre_option_default_role", "c_ws_plugin__s2member_option_forces::force_default_role");
65
  add_filter ("pre_site_option_default_user_role", "c_ws_plugin__s2member_option_forces::force_mms_default_role");
@@ -137,8 +137,8 @@ add_action ("wp_ajax_ws_plugin__s2member_reg_access_link_via_ajax", "c_ws_plugin
137
  add_action ("wp_ajax_ws_plugin__s2member_delete_reset_all_ip_restrictions_via_ajax", "c_ws_plugin__s2member_ip_restrictions::delete_reset_all_ip_restrictions_via_ajax");
138
  add_action ("wp_ajax_ws_plugin__s2member_delete_reset_specific_ip_restrictions_via_ajax", "c_ws_plugin__s2member_ip_restrictions::delete_reset_specific_ip_restrictions_via_ajax");
139
  /**/
140
- add_action ("ws_plugin__s2member_during_collective_eots", "c_ws_plugin__s2member_list_servers::auto_process_list_server_removals", 10, 3);
141
- add_action ("ws_plugin__s2member_during_collective_mods", "c_ws_plugin__s2member_list_servers::auto_process_list_server_removals", 10, 4);
142
  /*
143
  Register the activation | de-activation routines.
144
  */
59
  add_action ("remove_user_from_blog", "c_ws_plugin__s2member_user_deletions::handle_ms_user_deletions", 10, 2);
60
  /**/
61
  add_filter ("enable_edit_any_user_configuration", "c_ws_plugin__s2member_user_securities::ms_allow_edits");
62
+ add_filter ("user_has_cap", "c_ws_plugin__s2member_user_securities::ms_user_capabilities", 10, 3);
63
  /**/
64
  add_filter ("pre_option_default_role", "c_ws_plugin__s2member_option_forces::force_default_role");
65
  add_filter ("pre_site_option_default_user_role", "c_ws_plugin__s2member_option_forces::force_mms_default_role");
137
  add_action ("wp_ajax_ws_plugin__s2member_delete_reset_all_ip_restrictions_via_ajax", "c_ws_plugin__s2member_ip_restrictions::delete_reset_all_ip_restrictions_via_ajax");
138
  add_action ("wp_ajax_ws_plugin__s2member_delete_reset_specific_ip_restrictions_via_ajax", "c_ws_plugin__s2member_ip_restrictions::delete_reset_specific_ip_restrictions_via_ajax");
139
  /**/
140
+ add_action ("ws_plugin__s2member_during_collective_eots", "c_ws_plugin__s2member_list_servers::auto_process_list_server_removals", 10, 4);
141
+ add_action ("ws_plugin__s2member_during_collective_mods", "c_ws_plugin__s2member_list_servers::auto_process_list_server_removals", 10, 5);
142
  /*
143
  Register the activation | de-activation routines.
144
  */
includes/menu-pages/api-ops.inc.php CHANGED
@@ -168,6 +168,8 @@ if (apply_filters ("ws_plugin__s2member_during_api_ops_page_during_left_sections
168
  echo '<ul>' . "\n";
169
  echo '<li><code>%%role%%</code> = The Role ID <code>( subscriber, s2member_level[1-4], administrator, editor, author, contributor )</code>.</li>' . "\n";
170
  echo '<li><code>%%level%%</code> = The Level number <code>( 0, 1, 2, 3, 4 )</code>. ( <em>deprecated, no longer recommended; use <code>%%role%%</code></em> )</li>' . "\n";
 
 
171
  echo '<li><code>%%user_first_name%%</code> = The First Name of the Member who registered their Username.</li>' . "\n";
172
  echo '<li><code>%%user_last_name%%</code> = The Last Name of the Member who registered their Username.</li>' . "\n";
173
  echo '<li><code>%%user_full_name%%</code> = The Full Name ( First &amp; Last ) of the Member who registered their Username.</li>' . "\n";
@@ -503,6 +505,7 @@ if (apply_filters ("ws_plugin__s2member_during_api_ops_page_during_left_sections
503
  echo 'EOT/Deletion Notifications take place silently behind-the-scene, using an HTTP connection.<br /><br />' . "\n";
504
  echo '<strong>You can also use these special Replacement Codes if you need them:</strong>' . "\n";
505
  echo '<ul>' . "\n";
 
506
  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";
507
  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";
508
  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";
168
  echo '<ul>' . "\n";
169
  echo '<li><code>%%role%%</code> = The Role ID <code>( subscriber, s2member_level[1-4], administrator, editor, author, contributor )</code>.</li>' . "\n";
170
  echo '<li><code>%%level%%</code> = The Level number <code>( 0, 1, 2, 3, 4 )</code>. ( <em>deprecated, no longer recommended; use <code>%%role%%</code></em> )</li>' . "\n";
171
+ echo '<li><code>%%ccaps%%</code> = Custom Capabilities. Ex: <code>music,videos,free_gift</code> ( <em>in comma-delimited format</em> ).</li>' . "\n";
172
+ echo '<li><code>%%auto_eot_time%%</code> = Auto-EOT Time ( if applicable ). Ex: <code>1299925670</code> ( <em>unix timestamp</em> ).</li>' . "\n";
173
  echo '<li><code>%%user_first_name%%</code> = The First Name of the Member who registered their Username.</li>' . "\n";
174
  echo '<li><code>%%user_last_name%%</code> = The Last Name of the Member who registered their Username.</li>' . "\n";
175
  echo '<li><code>%%user_full_name%%</code> = The Full Name ( First &amp; Last ) of the Member who registered their Username.</li>' . "\n";
505
  echo 'EOT/Deletion Notifications take place silently behind-the-scene, using an HTTP connection.<br /><br />' . "\n";
506
  echo '<strong>You can also use these special Replacement Codes if you need them:</strong>' . "\n";
507
  echo '<ul>' . "\n";
508
+ 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";
509
  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";
510
  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";
511
  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";
includes/menu-pages/bridges.inc.php CHANGED
@@ -40,8 +40,12 @@ if (apply_filters ("ws_plugin__s2member_during_bridges_page_during_left_sections
40
  echo '<h3>bbPress® Bridge Integration ( install/uninstall )</h3>' . "\n";
41
  echo '<p>If you\'re running <a href="http://bbpress.org/" target="_blank" rel="external">bbPress® forums</a>, you can protect them with the s2Member plugin. BUT, you will need to install this Bridge/plugin first. This bbPress® Bridge/plugin will block all non-Member access to your forums. Only the bbPress® login-page will be available. Forum registration will be redirected to your Membership Options Page for s2Member ( on your main WordPress® installation ). This way, a visitor can signup on your site, and gain Membership Access to your forums.</p>' . "\n";
42
  echo '<p><em>* This Bridge/plugin will NOT work, until you\'ve successfully integrated WordPress® into bbPress®. For more information, log into your bbPress® Dashboard, and go to: <code>bbPress® -> Settings -> WordPress® Integration</code>. Once you have WordPress® integrated ( <a href="http://wordpress.org/extend/plugins/bbpress-integration/" target="_blank" rel="external">install this plugin</a> ) and follow the instructions regarding your <code>/wp-config.php</code> file. Then, come back here, and install the s2Member Bridge/plugin. * This Bridge Integration could also be installed manually. You\'ll find the bbPress® Bridge/plugin inside <code>/s2member/includes/dropins/bridges/_s2member-bbpress-bridge.php</code>. Pop that file into the `my-plugins/` directory for bbPress®, or just click the Install button below; s2Member will do this part for you automatically.</em></p>' . "\n";
 
43
  do_action ("ws_plugin__s2member_during_bridges_page_during_left_sections_during_api_easy_way", get_defined_vars ());
44
  /**/
 
 
 
45
  echo '<table class="form-table">' . "\n";
46
  echo '<tbody>' . "\n";
47
  echo '<tr>' . "\n";
@@ -56,29 +60,60 @@ if (apply_filters ("ws_plugin__s2member_during_bridges_page_during_left_sections
56
  echo '<tr>' . "\n";
57
  /**/
58
  echo '<td>' . "\n";
59
- echo '<form method="post" name="ws_plugin__s2member_bridge_bbpress_form" id="ws-plugin--s2member-bridge-bbpress-form">' . "\n";
60
- echo '<input type="hidden" name="ws_plugin__s2member_bridge_bbpress" id="ws-plugin--s2member-bridge-bbpress" value="' . esc_attr (wp_create_nonce ("ws-plugin--s2member-bridge-bbpress")) . '" />' . "\n";
 
 
 
 
61
  /**/
62
- echo '<input type="text" name="ws_plugin__s2member_bridge_bbpress_plugins_dir" id="ws_plugin--s2member-bridge-bbpress-plugins-dir" value="' . format_to_edit (trim (stripslashes ($_POST["ws_plugin__s2member_bridge_bbpress_plugins_dir"]))) . '" style="width:99%;" /><br />' . "\n";
63
- echo 'Best guess: <code>' . esc_html ($_bridge_bbpress_plugins_dir_guess) . '</code><br /><br />' . "\n";
 
 
 
64
  /**/
65
- echo 'Minimum Level required for access to your bbPress® forums.<br />' . "\n";
66
- echo '<select name="ws_plugin__s2member_bridge_bbpress_min_level" id="ws-plugin--s2member-bbpress-min-level" style="width:99%;">' . "\n";
67
- echo '<option value=""' . ( (!strlen ($_POST["ws_plugin__s2member_bridge_bbpress_min_level"])) ? ' selected="selected"' : '') . '></option>' . "\n";
68
- echo '<option value="0"' . ( ($_POST["ws_plugin__s2member_bridge_bbpress_min_level"] === "0") ? ' selected="selected"' : '') . '>s2Member Level 0</option>' . "\n";
69
- echo '<option value="1"' . ( ($_POST["ws_plugin__s2member_bridge_bbpress_min_level"] === "1") ? ' selected="selected"' : '') . '>s2Member Level 1</option>' . "\n";
70
- echo '<option value="2"' . ( ($_POST["ws_plugin__s2member_bridge_bbpress_min_level"] === "2") ? ' selected="selected"' : '') . '>s2Member Level 2</option>' . "\n";
71
- echo '<option value="3"' . ( ($_POST["ws_plugin__s2member_bridge_bbpress_min_level"] === "3") ? ' selected="selected"' : '') . '>s2Member Level 3</option>' . "\n";
72
- echo '<option value="4"' . ( ($_POST["ws_plugin__s2member_bridge_bbpress_min_level"] === "4") ? ' selected="selected"' : '') . '>s2Member Level 4</option>' . "\n";
73
- echo '</select><br /><br />' . "\n";
74
  /**/
75
- echo '<p class="submit"><input type="submit" name="ws_plugin__s2member_bridge_bbpress_action" class="button-primary" value="Install / Re-Install" /> &nbsp;&nbsp; <input type="submit" name="ws_plugin__s2member_bridge_bbpress_action" class="button-primary" value="Un-Install" /></p>' . "\n";
76
- echo '</form>' . "\n";
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
77
  echo '</td>' . "\n";
78
  /**/
79
  echo '</tr>' . "\n";
80
  echo '</tbody>' . "\n";
81
  echo '</table>' . "\n";
 
 
 
 
 
 
82
  echo '</div>' . "\n";
83
  /**/
84
  echo '</div>' . "\n";
40
  echo '<h3>bbPress® Bridge Integration ( install/uninstall )</h3>' . "\n";
41
  echo '<p>If you\'re running <a href="http://bbpress.org/" target="_blank" rel="external">bbPress® forums</a>, you can protect them with the s2Member plugin. BUT, you will need to install this Bridge/plugin first. This bbPress® Bridge/plugin will block all non-Member access to your forums. Only the bbPress® login-page will be available. Forum registration will be redirected to your Membership Options Page for s2Member ( on your main WordPress® installation ). This way, a visitor can signup on your site, and gain Membership Access to your forums.</p>' . "\n";
42
  echo '<p><em>* This Bridge/plugin will NOT work, until you\'ve successfully integrated WordPress® into bbPress®. For more information, log into your bbPress® Dashboard, and go to: <code>bbPress® -> Settings -> WordPress® Integration</code>. Once you have WordPress® integrated ( <a href="http://wordpress.org/extend/plugins/bbpress-integration/" target="_blank" rel="external">install this plugin</a> ) and follow the instructions regarding your <code>/wp-config.php</code> file. Then, come back here, and install the s2Member Bridge/plugin. * This Bridge Integration could also be installed manually. You\'ll find the bbPress® Bridge/plugin inside <code>/s2member/includes/dropins/bridges/_s2member-bbpress-bridge.php</code>. Pop that file into the `my-plugins/` directory for bbPress®, or just click the Install button below; s2Member will do this part for you automatically.</em></p>' . "\n";
43
+ echo '<p><em>* This Bridge/plugin will also add a PHP Conditional Tag to your installation of bbPress®. This is 100% optional. Once installed, you could do something like this inside your bbPress® theme files with PHP code: ' . c_ws_plugin__s2member_utils_strings::highlight_php ('<?php if(current_wp_user_is("s2member_level2")){ /* Content. */ } ?>') . ' ... you can test for any WordPress® Role. The most common Roles associated with s2Member are: <code>subscriber</code>, <code>s2member_level1</code>, <code>s2member_level2</code>, <code>s2member_level3</code>, <code>s2member_level4</code>. This may come in handy for a developer integrating bbPress® in creative ways.</em></p>' . "\n";
44
  do_action ("ws_plugin__s2member_during_bridges_page_during_left_sections_during_api_easy_way", get_defined_vars ());
45
  /**/
46
+ echo '<form method="post" name="ws_plugin__s2member_bridge_bbpress_form" id="ws-plugin--s2member-bridge-bbpress-form">' . "\n";
47
+ echo '<input type="hidden" name="ws_plugin__s2member_bridge_bbpress" id="ws-plugin--s2member-bridge-bbpress" value="' . esc_attr (wp_create_nonce ("ws-plugin--s2member-bridge-bbpress")) . '" />' . "\n";
48
+ /**/
49
  echo '<table class="form-table">' . "\n";
50
  echo '<tbody>' . "\n";
51
  echo '<tr>' . "\n";
60
  echo '<tr>' . "\n";
61
  /**/
62
  echo '<td>' . "\n";
63
+ echo '<input type="text" name="ws_plugin__s2member_bridge_bbpress_plugins_dir" id="ws_plugin--s2member-bridge-bbpress-plugins-dir" value="' . format_to_edit ((!empty ($_POST)) ? trim (stripslashes ($_POST["ws_plugin__s2member_bridge_bbpress_plugins_dir"])) : $_bridge_bbpress_plugins_dir_guess) . '" /><br />' . "\n";
64
+ echo 'Best guess: <code>' . esc_html ($_bridge_bbpress_plugins_dir_guess) . '</code>' . "\n";
65
+ echo '</td>' . "\n";
66
+ /**/
67
+ echo '</tr>' . "\n";
68
+ echo '<tr>' . "\n";
69
  /**/
70
+ echo '<th>' . "\n";
71
+ echo '<label for="ws_plugin--s2member-bridge-bbpress-ovg">' . "\n";
72
+ echo 'Allow Open Viewing? ( can public visitors read forum posts? )' . "\n";
73
+ echo '</label>' . "\n";
74
+ echo '</th>' . "\n";
75
  /**/
76
+ echo '</tr>' . "\n";
77
+ echo '<tr>' . "\n";
 
 
 
 
 
 
 
78
  /**/
79
+ echo '<td>' . "\n";
80
+ echo '<select name="ws_plugin__s2member_bridge_bbpress_ovg" id="ws-plugin--s2member-bbpress-ovg">' . "\n";
81
+ echo '<option value="0"' . ( (!$_POST["ws_plugin__s2member_bridge_bbpress_min_level"]) ? ' selected="selected"' : '') . '>No ( my bbPress® forums are off-limits to the public )</option>' . "\n";
82
+ echo '<option value="1"' . ( ($_POST["ws_plugin__s2member_bridge_bbpress_min_level"]) ? ' selected="selected"' : '') . '>Yes ( enable Open Viewing for public visitors ) read-only</option>' . "\n";
83
+ echo '</select><span id="ws-plugin--s2member-bbpress-ovg-off-note" style="display:none;"><br />When this is <code>No</code>, the next setting below will include both read-access &amp; participation together ( as one concept ).</span>' . "\n";
84
+ echo '</td>' . "\n";
85
+ /**/
86
+ echo '</tr>' . "\n";
87
+ echo '<tr>' . "\n";
88
+ /**/
89
+ echo '<th>' . "\n";
90
+ echo '<label for="ws_plugin--s2member-bridge-bbpress-min-level">' . "\n";
91
+ echo 'Minimum Level to participate in your bbPress® forums.' . "\n";
92
+ echo '</label>' . "\n";
93
+ echo '</th>' . "\n";
94
+ /**/
95
+ echo '</tr>' . "\n";
96
+ echo '<tr>' . "\n";
97
+ /**/
98
+ echo '<td>' . "\n";
99
+ echo '<select name="ws_plugin__s2member_bridge_bbpress_min_level" id="ws-plugin--s2member-bbpress-min-level">' . "\n";
100
+ echo '<option value="0"' . ( ($_POST["ws_plugin__s2member_bridge_bbpress_min_level"] === "0") ? ' selected="selected"' : '') . '>Require s2Member Level #0 ( to participate )</option>' . "\n";
101
+ echo '<option value="1"' . ( ($_POST["ws_plugin__s2member_bridge_bbpress_min_level"] === "1") ? ' selected="selected"' : '') . '>Require s2Member Level #1 ( to participate )</option>' . "\n";
102
+ echo '<option value="2"' . ( ($_POST["ws_plugin__s2member_bridge_bbpress_min_level"] === "2") ? ' selected="selected"' : '') . '>Require s2Member Level #2 ( to participate )</option>' . "\n";
103
+ echo '<option value="3"' . ( ($_POST["ws_plugin__s2member_bridge_bbpress_min_level"] === "3") ? ' selected="selected"' : '') . '>Require s2Member Level #3 ( to participate )</option>' . "\n";
104
+ echo '<option value="4"' . ( ($_POST["ws_plugin__s2member_bridge_bbpress_min_level"] === "4") ? ' selected="selected"' : '') . '>Require s2Member Level #4 ( to participate )</option>' . "\n";
105
+ echo '</select>' . "\n";
106
  echo '</td>' . "\n";
107
  /**/
108
  echo '</tr>' . "\n";
109
  echo '</tbody>' . "\n";
110
  echo '</table>' . "\n";
111
+ /**/
112
+ echo '<br />' . "\n";
113
+ /**/
114
+ echo '<p class="submit"><input type="submit" name="ws_plugin__s2member_bridge_bbpress_action" class="button-primary" value="Install / Re-Install" /> &nbsp;&nbsp; <input type="submit" name="ws_plugin__s2member_bridge_bbpress_action" class="button-primary" value="Un-Install" /></p>' . "\n";
115
+ /**/
116
+ echo '</form>' . "\n";
117
  echo '</div>' . "\n";
118
  /**/
119
  echo '</div>' . "\n";
includes/menu-pages/els-ops.inc.php CHANGED
@@ -360,8 +360,8 @@ if (apply_filters ("ws_plugin__s2member_during_els_ops_page_during_left_sections
360
  echo '<td>' . "\n";
361
  echo '<div class="ws-menu-page-scrollbox" style="height:130px;">' . "\n";
362
  echo '<input type="hidden" name="ws_plugin__s2member_custom_reg_auto_opt_outs[]" value="update-signal" />' . "\n";
363
- foreach (array ("user-removal-deletion" => "Anytime a User/Member is deleted ( including manual deletions ).", "ipn-refund-reversal-deletion" => "Anytime s2Member deletes an account because of a Refund/Reversal.", "ipn-refund-reversal-demotion" => "Anytime s2Member demotes an account because of a Refund/Reversal.", "auto-eot-cancellation-expiration-deletion" => "Anytime s2Member deletes an account because of a Cancellation/Expiration.", "auto-eot-cancellation-expiration-demotion" => "Anytime s2Member demotes an account because of a Cancellation/Expiration.", "ipn-upgrade-downgrade" => "Anytime s2Member changes a Member's Access Level# thru a Subscr. Modification.") as $ws_plugin__s2member_temp_s_value => $ws_plugin__s2member_temp_s_label)
364
- echo '<input type="checkbox" name="ws_plugin__s2member_custom_reg_auto_opt_outs[]" id="ws-plugin--s2member-custom-reg-auto-opt-outs-' . esc_attr ($ws_plugin__s2member_temp_s_value) . '" value="' . esc_attr ($ws_plugin__s2member_temp_s_value) . '"' . ( (in_array ($ws_plugin__s2member_temp_s_value, $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["custom_reg_auto_opt_outs"])) ? ' checked="checked"' : '') . ' /> <label for="ws-plugin--s2member-custom-reg-auto-opt-outs-' . esc_attr ($ws_plugin__s2member_temp_s_value) . '">' . esc_html ($ws_plugin__s2member_temp_s_label) . '</label><br />' . "\n";
365
  echo '</div>' . "\n";
366
  echo '<em><strong>*Subscr. Modifications*</strong> If you check the box for ( <strong>changes in Access Level# thru a Subscr. Modification</strong> ), this tells s2Member that it should not only remove the Member from the List(s) at their current Level#, but that s2Member should <strong>also</strong> subscribe them to any Lists you\'ve configured at the new Access Level# they are being changed to; regardless of whether they are being upgraded or downgraded.</em>' . "\n";
367
  echo '</td>' . "\n";
360
  echo '<td>' . "\n";
361
  echo '<div class="ws-menu-page-scrollbox" style="height:130px;">' . "\n";
362
  echo '<input type="hidden" name="ws_plugin__s2member_custom_reg_auto_opt_outs[]" value="update-signal" />' . "\n";
363
+ foreach (array ("user-removal-deletion" => "Anytime a User/Member is deleted ( including manual deletions ).", "ipn-refund-reversal-deletion" => "Anytime s2Member deletes an account because of a Refund/Reversal.", "ipn-refund-reversal-demotion" => "Anytime s2Member demotes an account because of a Refund/Reversal.", "(ipn|auto-eot)-cancellation-expiration-deletion" => "Anytime s2Member deletes an account because of a Cancellation/Expiration.", "(ipn|auto-eot)-cancellation-expiration-demotion" => "Anytime s2Member demotes an account because of a Cancellation/Expiration.", "ipn-upgrade-downgrade" => "Anytime s2Member changes a Member's Access Level# thru a Subscr. Modification.") as $ws_plugin__s2member_temp_s_value => $ws_plugin__s2member_temp_s_label)
364
+ echo '<input type="checkbox" name="ws_plugin__s2member_custom_reg_auto_opt_outs[]" id="ws-plugin--s2member-custom-reg-auto-opt-outs-' . esc_attr (preg_replace ("/[^a-z0-9_\-]/", "-", $ws_plugin__s2member_temp_s_value)) . '" value="' . esc_attr ($ws_plugin__s2member_temp_s_value) . '"' . ( (in_array ($ws_plugin__s2member_temp_s_value, $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["custom_reg_auto_opt_outs"])) ? ' checked="checked"' : '') . ' /> <label for="ws-plugin--s2member-custom-reg-auto-opt-outs-' . esc_attr (preg_replace ("/[^a-z0-9_\-]/", "-", $ws_plugin__s2member_temp_s_value)) . '">' . esc_html ($ws_plugin__s2member_temp_s_label) . '</label><br />' . "\n";
365
  echo '</div>' . "\n";
366
  echo '<em><strong>*Subscr. Modifications*</strong> If you check the box for ( <strong>changes in Access Level# thru a Subscr. Modification</strong> ), this tells s2Member that it should not only remove the Member from the List(s) at their current Level#, but that s2Member should <strong>also</strong> subscribe them to any Lists you\'ve configured at the new Access Level# they are being changed to; regardless of whether they are being upgraded or downgraded.</em>' . "\n";
367
  echo '</td>' . "\n";
includes/menu-pages/menu-pages-s-min.js CHANGED
@@ -1 +1 @@
1
- jQuery(document).ready(function(b){var a=esc_html=function(c){return String(c).replace(/"/g,"&quot;").replace(/\</g,"&lt;").replace(/\>/g,"&gt;")};if(location.href.match(/page\=ws-plugin--s2member-mms-options/)){b("select#ws-plugin--s2member-mms-registration-file").change(function(){if(b(this).val()==="wp-signup"){b("div#ws-plugin--s2member-mms-registration-support-package-details-wrapper").show(),b("div.ws-plugin--s2member-mms-registration-wp-login, table.ws-plugin--s2member-mms-registration-wp-login").hide(),b("div.ws-plugin--s2member-mms-registration-wp-signup, table.ws-plugin--s2member-mms-registration-wp-signup").show();b("div.ws-plugin--s2member-mms-registration-wp-signup-blogs-level0, table.ws-plugin--s2member-mms-registration-wp-signup-blogs-level0")[((b("select#ws-plugin--s2member-mms-registration-grants").val()==="all")?"show":"hide")](),b("input#ws-plugin--s2member-mms-registration-blogs-level0").val(((b("select#ws-plugin--s2member-mms-registration-grants").val()==="all")?"1":"0"))}else{if(b(this).val()==="wp-login"){b("div#ws-plugin--s2member-mms-registration-support-package-details-wrapper").hide(),b("div.ws-plugin--s2member-mms-registration-wp-login, table.ws-plugin--s2member-mms-registration-wp-login").show(),b("div.ws-plugin--s2member-mms-registration-wp-signup, table.ws-plugin--s2member-mms-registration-wp-signup").hide(),b("input#ws-plugin--s2member-mms-registration-blogs-level0").val("0")}}}).trigger("change");b("select#ws-plugin--s2member-mms-registration-grants").change(function(){b("select#ws-plugin--s2member-mms-registration-file").trigger("change")})}else{if(location.href.match(/page\=ws-plugin--s2member-options/)){ws_plugin__s2member_generateSecurityKey=function(){var f=function(h,g){h=(arguments.length<1)?0:h;g=(arguments.length<2)?2147483647:g;return Math.floor(Math.random()*(g-h+1))+h};var e="ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()";for(var d=0,c="";d<56;d++){c+=e.substr(f(0,e.length-1),1)}b("input#ws-plugin--s2member-sec-encryption-key").val(c);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.")){b("input#ws-plugin--s2member-sec-encryption-key").attr("disabled",false)}return false};ws_plugin__s2member_securityKeyHistory=function(){b("div#ws-plugin--s2member-sec-encryption-key-history").toggle();return false};if(b("input#ws-plugin--s2member-custom-reg-fields").length&&b("div#ws-plugin--s2member-custom-reg-field-configuration").length){(function(){var c=b("input#ws-plugin--s2member-custom-reg-fields");var f=b("div#ws-plugin--s2member-custom-reg-field-configuration");var l=(c.val())?b.JSON.parse(c.val()):[];l=(l instanceof Array)?l:[];var k='<div id="ws-plugin--s2member-custom-reg-field-configuration-tools"></div>';var r='<table id="ws-plugin--s2member-custom-reg-field-configuration-table"></table>';f.html(k+r);var i=b("div#ws-plugin--s2member-custom-reg-field-configuration-tools");var o=b("table#ws-plugin--s2member-custom-reg-field-configuration-table");ws_plugin__s2member_customRegFieldTypeChange=function(t){var s,v,u=b(t).val();s="tr.ws-plugin--s2member-custom-reg-field-configuration-tools-form-options";v="tr.ws-plugin--s2member-custom-reg-field-configuration-tools-form-expected";if(u.match(/^(text|textarea|checkbox|pre_checkbox)$/)){b(s).css("display","none"),b(s).prev("tr").css("display","none")}else{b(s).css("display",""),b(s).prev("tr").css("display","")}if(u.match(/^(select|selects|checkboxes|radios)$/)){b(v).css("display","none"),b(v).prev("tr").css("display","none")}else{b(v).css("display",""),b(v).prev("tr").css("display","")}};ws_plugin__s2member_customRegFieldDelete=function(t){var s=new Array();for(var u=0;u<l.length;u++){if(u!==t){s.push(l[u])}}l=s,q(),p()};ws_plugin__s2member_customRegFieldMoveUp=function(u){if(typeof l[u]==="object"&&typeof l[u-1]==="object"){var t=l[u-1],s=l[u];l[u-1]=s,l[u]=t;q(),p()}};ws_plugin__s2member_customRegFieldMoveDown=function(u){if(typeof l[u]==="object"&&typeof l[u+1]==="object"){var s=l[u+1],t=l[u];l[u+1]=t,l[u]=s;q(),p()}};ws_plugin__s2member_customRegFieldCreate=function(){var s=b("table#ws-plugin--s2member-custom-reg-field-configuration-tools-form"),t={};b(":input[property]",s).each(function(){var v=b(this),u=v.attr("property"),w=b.trim(v.val());t[u]=w});if((t=d(t))){l.push(t),q(),j(),p(),n();setTimeout(function(){var u="tr.ws-plugin--s2member-custom-reg-field-configuration-table-row-"+(l.length-1);alert('Field created successfully.\n* Remember to "Save Changes".');b(u).effect("highlight",1000)},500)}};ws_plugin__s2member_customRegFieldUpdate=function(t){var s=b("table#ws-plugin--s2member-custom-reg-field-configuration-tools-form"),u={};b(":input[property]",s).each(function(){var x=b(this),w=x.attr("property"),y=b.trim(x.val());u[w]=y});if((u=d(u,t))){l[t]=u,q(),j(),p(),n();var v="tr.ws-plugin--s2member-custom-reg-field-configuration-table-row-"+t;b(v).effect("highlight",1000)}};ws_plugin__s2member_customRegFieldAdd=function(){j(true)};ws_plugin__s2member_customRegFieldEdit=function(s){j(false,s),n()};ws_plugin__s2member_customRegFieldCancel=function(){j(),n()};var d=function(w,u){var s=(typeof u==="number"&&typeof l[u]==="object")?true:false,x=[],t,v;if(typeof w!=="object"){x.push("Invalid field object. Please try again.")}else{if(!w.id){x.push("Unique Field ID:\nThis is required. Please try again.")}else{if(h(w.id)&&(!s||w.id!==l[u].id)){x.push("Unique Field ID:\nThat Field ID already exists. Please try again.")}}if(!w.label){x.push("Field Label/Description:\nThis is required. Please try again.")}if(w.type.match(/^(select|selects|checkboxes|radios)$/)){w.expected="";if(!w.options){x.push("Option Configuration File:\nThis is required. Please try again.")}else{t=w.options.split(/[\r\n]+/);for(v=0;v<t.length;v++){t[v]=b.trim(t[v]);if(!t[v].match(/^([^\|]*)(\|)([^\|]*)(\|default)?$/)){x.push("Option Configuration File:\nInvalid configuration at line #"+(v+1)+".");break}}w.options=b.trim(t.join("\n"))}}else{w.options=""}if(!(w.levels=w.levels.replace(/ /g,""))){x.push("Applicable Levels:\nThis is required. Please try again.")}else{if(!w.levels.match(/^(all|[0-9,]+)$/)){x.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(w.classes&&w.classes.match(/[^a-z 0-9 _ \-]/i)){x.push("CSS Classes:\nContains invalid characters. Please try again.\n( only: alphanumerics, underscores, hyphens, spaces )")}if(w.styles&&w.styles.match(/["\=\>\<]/)){x.push('CSS Styles:\nContains invalid characters. Please try again.\n( do NOT use these characters: = " < > )')}if(w.attrs&&w.attrs.match(/[\>\<]/)){x.push("Other Attributes:\nContains invalid characters. Please try again.\n( do NOT use these characters: < > )")}}if(x.length>0){alert(x.join("\n\n"));return false}else{return w}};var q=function(){c.val(((l.length>0)?b.JSON.stringify(l):""))};var m=function(s){return(typeof s==="string")?b.trim(s).toLowerCase().replace(/[^a-z0-9]/g,"_"):""};var g=function(t){var s={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 s[t]==="string"){return s[t]}return""};var h=function(s){for(var t=0;t<l.length;t++){if(l[t].id===s){return true}}};var n=function(){scrollTo(0,b("div.ws-plugin--s2member-custom-reg-fields-section").offset()["top"]-100)};var j=function(s,A){var x=0,z="",t="",D=0,y=0,v={id:"",label:"",type:"text",options:"",expected:"",required:"yes",levels:"all",editable:"yes",classes:"",styles:"",attrs:""};var u=(typeof A==="number"&&typeof l[A]==="object")?true:false,C=(s||u)?true:false,B=(u)?l[A]:v;z+='<a href="#" onclick="ws_plugin__s2member_customRegFieldAdd(); return false;">Add New Field</a>';tb_remove(),b("div#ws-plugin--s2member-custom-reg-field-configuration-thickbox-tools-form").remove();if(C){t+='<div id="ws-plugin--s2member-custom-reg-field-configuration-thickbox-tools-form">';t+='<table id="ws-plugin--s2member-custom-reg-field-configuration-tools-form">';t+="<tbody>";t+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-type">';t+='<td colspan="2">';t+='<label for="ws-plugin--s2member-custom-reg-field-configuration-tools-form-type">Form Field Type: *</label>';t+="</td>";t+="</tr>";t+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-type">';t+='<td colspan="2">';t+='<select property="type" onchange="ws_plugin__s2member_customRegFieldTypeChange(this);" id="ws-plugin--s2member-custom-reg-field-configuration-tools-form-type">';t+='<option value="text"'+((B.type==="text")?' selected="selected"':"")+'">'+esc_html(g("text"))+"</option>";t+='<option value="textarea"'+((B.type==="textarea")?' selected="selected"':"")+'">'+esc_html(g("textarea"))+"</option>";t+='<option value="select"'+((B.type==="select")?' selected="selected"':"")+'">'+esc_html(g("select"))+"</option>";t+='<option value="selects"'+((B.type==="selects")?' selected="selected"':"")+'">'+esc_html(g("selects"))+"</option>";t+='<option value="checkbox"'+((B.type==="checkbox")?' selected="selected"':"")+'">'+esc_html(g("checkbox"))+"</option>";t+='<option value="pre_checkbox"'+((B.type==="pre_checkbox")?' selected="selected"':"")+'">'+esc_html(g("pre_checkbox"))+"</option>";t+='<option value="checkboxes"'+((B.type==="checkboxes")?' selected="selected"':"")+'">'+esc_html(g("checkboxes"))+"</option>";t+='<option value="radios"'+((B.type==="radios")?' selected="selected"':"")+'">'+esc_html(g("radios"))+"</option>";t+="</select>";t+="</td>";t+="</tr>";t+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-spacer"><td colspan="2">&nbsp;</td></tr>';t+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-label">';t+='<td colspan="2">';t+='<label for="ws-plugin--s2member-custom-reg-field-configuration-tools-form-label">Field Label/Desc: *</label>';t+="</td>";t+="</tr>";t+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-label">';t+='<td colspan="2">';t+='<input type="text" property="label" value="'+a(B.label)+'" id="ws-plugin--s2member-custom-reg-field-configuration-tools-form-label" /><br />';t+="<small>Examples: <code>Choose Country</code>, <code>Street Address</code></small>";t+="</td>";t+="</tr>";t+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-spacer"><td colspan="2">&nbsp;</td></tr>';t+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-id">';t+='<td colspan="2">';t+='<label for="ws-plugin--s2member-custom-reg-field-configuration-tools-form-id">Unique Field ID: *</label></label>';t+="</td>";t+="</tr>";t+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-id">';t+='<td colspan="2">';t+='<input type="text" property="id" value="'+a(B.id)+'" maxlength="25" id="ws-plugin--s2member-custom-reg-field-configuration-tools-form-id" /><br />';t+="<small>Examples: <code>country_code</code>, <code>street_address</code></small><br />";t+='<small>e.g. <code>[s2Get user_field="country_code" /]</code></small>';t+="</td>";t+="</tr>";t+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-spacer"><td colspan="2">&nbsp;</td></tr>';t+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-required">';t+='<td colspan="2">';t+='<label for="ws-plugin--s2member-custom-reg-field-configuration-tools-form-required">Field Required: *</label>';t+="</td>";t+="</tr>";t+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-required">';t+='<td colspan="2">';t+='<select property="required" id="ws-plugin--s2member-custom-reg-field-configuration-tools-form-required">';t+='<option value="yes"'+((B.required==="yes")?' selected="selected"':"")+'">Yes ( required )</option>';t+='<option value="no"'+((B.required==="no")?' selected="selected"':"")+'">No ( optional )</option>';t+="</select><br />";t+='<small>If <code>yes</code>, only Users/Members will be "required" to enter this field.</small><br />';t+="<small>* Administrators are exempt from this requirement.</small>";t+="</td>";t+="</tr>";t+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-spacer"'+((B.type.match(/^(text|textarea|checkbox|pre_checkbox)$/))?' style="display:none;"':"")+'><td colspan="2">&nbsp;</td></tr>';t+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-options"'+((B.type.match(/^(text|textarea|checkbox|pre_checkbox)$/))?' style="display:none;"':"")+">";t+='<td colspan="2">';t+='<label for="ws-plugin--s2member-custom-reg-field-configuration-tools-form-options">Option Configuration File: * ( one option per line )</label><br />';t+="<small>Use a pipe <code>|</code> delimited format: <code>option value|option label</code></small>";t+="</td>";t+="</tr>";t+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-options"'+((B.type.match(/^(text|textarea|checkbox|pre_checkbox)$/))?' style="display:none;"':"")+">";t+='<td colspan="2">';t+='<textarea property="options" rows="3" wrap="off" spellcheck="false" id="ws-plugin--s2member-custom-reg-field-configuration-tools-form-options">'+esc_html(B.options)+"</textarea><br />";t+="Here is a quick example:<br />";t+="<small>You can also specify a <em>default</em> option:</small><br />";t+="<code>US|United States|default</code><br />";t+="<code>CA|Canada</code><br />";t+="<code>VI|Virgin Islands (U.S.)</code>";t+="</td>";t+="</tr>";t+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-spacer"'+((B.type.match(/^(select|selects|checkboxes|radios)$/))?' style="display:none;"':"")+'><td colspan="2">&nbsp;</td></tr>';t+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-expected"'+((B.type.match(/^(select|selects|checkboxes|radios)$/))?' style="display:none;"':"")+">";t+='<td colspan="2">';t+='<label for="ws-plugin--s2member-custom-reg-field-configuration-tools-form-expected">Expected Format: *</label>';t+="</td>";t+="</tr>";t+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-expected"'+((B.type.match(/^(select|selects|checkboxes|radios)$/))?' style="display:none;"':"")+">";t+='<td colspan="2">';t+='<select property="expected" id="ws-plugin--s2member-custom-reg-field-configuration-tools-form-expected">';t+='<option value=""'+((B.expected==="")?' selected="selected"':"")+'">Anything Goes</option>';t+='<option disabled="disabled"></option>';t+='<optgroup label="Specific Input Types">';t+='<option value="numeric-wp-commas"'+((B.expected==="numeric-wp-commas")?' selected="selected"':"")+'">Numeric ( with or without decimals, commas allowed )</option>';t+='<option value="numeric"'+((B.expected==="numeric")?' selected="selected"':"")+'">Numeric ( with or without decimals, no commas )</option>';t+='<option value="integer"'+((B.expected==="integer")?' selected="selected"':"")+'">Integer ( whole number, without any decimals )</option>';t+='<option value="integer-gt-0"'+((B.expected==="integer-gt-0")?' selected="selected"':"")+'">Integer > 0 ( whole number, no decimals, greater than 0 )</option>';t+='<option value="float"'+((B.expected==="float")?' selected="selected"':"")+'">Float ( floating point number, decimals required )</option>';t+='<option value="float-gt-0"'+((B.expected==="float-gt-0")?' selected="selected"':"")+'">Float > 0 ( floating point number, decimals required, greater than 0 )</option>';t+='<option value="date"'+((B.expected==="date")?' selected="selected"':"")+'">Date ( required date format: dd/mm/yyyy )</option>';t+='<option value="email"'+((B.expected==="email")?' selected="selected"':"")+'">Email ( require valid email )</option>';t+='<option value="url"'+((B.expected==="url")?' selected="selected"':"")+'">Full URL ( starting with http or https )</option>';t+='<option value="domain"'+((B.expected==="domain")?' selected="selected"':"")+'">Domain Name ( domain name only, without http )</option>';t+='<option value="phone"'+((B.expected==="phone")?' selected="selected"':"")+'">Phone # ( 10 digits w/possible hyphens,spaces,brackets )</option>';t+='<option value="uszip"'+((B.expected==="uszip")?' selected="selected"':"")+'">US Zipcode ( 5-9 digits w/possible hyphen )</option>';t+='<option value="cazip"'+((B.expected==="cazip")?' selected="selected"':"")+'">Canadian Zipcode ( 6 alpha-numerics w/possible space )</option>';t+='<option value="uczip"'+((B.expected==="uczip")?' selected="selected"':"")+'">US/Canadian Zipcode ( either a US or Canadian zipcode )</option>';t+="</optgroup>";t+='<option disabled="disabled"></option>';t+='<optgroup label="Any Character Combination">';for(x=1;x<=25;x++){t+='<option value="any-'+x+'"'+((B.expected==="any-"+x)?' selected="selected"':"")+'">Any Character Combination ( '+x+" character minimum )</option>";t+='<option value="any-'+x+'-e"'+((B.expected==="any-"+x+"-e")?' selected="selected"':"")+'">Any Character Combination ( exactly '+x+" character"+((x>1)?"s":"")+" )</option>"}t+="</optgroup>";t+='<option disabled="disabled"></option>';t+='<optgroup label="Alphanumerics, Spaces &amp; Punctuation Only">';for(x=1;x<=25;x++){t+='<option value="alphanumerics-spaces-punctuation-'+x+'"'+((B.expected==="alphanumerics-spaces-punctuation-"+x)?' selected="selected"':"")+'">Alphanumerics, Spaces &amp; Punctuation ( '+x+" character minimum )</option>";t+='<option value="alphanumerics-spaces-punctuation-'+x+'-e"'+((B.expected==="alphanumerics-spaces-punctuation-"+x+"-e")?' selected="selected"':"")+'">Alphanumerics, Spaces &amp; Punctuation ( exactly '+x+" character"+((x>1)?"s":"")+" )</option>"}t+="</optgroup>";t+='<option disabled="disabled"></option>';t+='<optgroup label="Alphanumerics &amp; Spaces Only">';for(x=1;x<=25;x++){t+='<option value="alphanumerics-spaces-'+x+'"'+((B.expected==="alphanumerics-spaces-"+x)?' selected="selected"':"")+'">Alphanumerics &amp; Spaces ( '+x+" character minimum )</option>";t+='<option value="alphanumerics-spaces-'+x+'-e"'+((B.expected==="alphanumerics-spaces-"+x+"-e")?' selected="selected"':"")+'">Alphanumerics &amp; Spaces ( exactly '+x+" character"+((x>1)?"s":"")+" )</option>"}t+="</optgroup>";t+='<option disabled="disabled"></option>';t+='<optgroup label="Alphanumerics &amp; Punctuation Only">';for(x=1;x<=25;x++){t+='<option value="alphanumerics-punctuation-'+x+'"'+((B.expected==="alphanumerics-punctuation-"+x)?' selected="selected"':"")+'">Alphanumerics &amp; Punctuation ( '+x+" character minimum )</option>";t+='<option value="alphanumerics-punctuation-'+x+'-e"'+((B.expected==="alphanumerics-punctuation-"+x+"-e")?' selected="selected"':"")+'">Alphanumerics &amp; Punctuation ( exactly '+x+" character"+((x>1)?"s":"")+" )</option>"}t+="</optgroup>";t+='<option disabled="disabled"></option>';t+='<optgroup label="Alphanumerics Only">';for(x=1;x<=25;x++){t+='<option value="alphanumerics-'+x+'"'+((B.expected==="alphanumerics-"+x)?' selected="selected"':"")+'">Alphanumerics ( '+x+" character minimum )</option>";t+='<option value="alphanumerics-'+x+'-e"'+((B.expected==="alphanumerics-"+x+"-e")?' selected="selected"':"")+'">Alphanumerics ( exactly '+x+" character"+((x>1)?"s":"")+" )</option>"}t+="</optgroup>";t+='<option disabled="disabled"></option>';t+='<optgroup label="Alphabetics Only">';for(x=1;x<=25;x++){t+='<option value="alphabetics-'+x+'"'+((B.expected==="alphabetics-"+x)?' selected="selected"':"")+'">Alphabetics ( '+x+" character minimum )</option>";t+='<option value="alphabetics-'+x+'-e"'+((B.expected==="alphabetics-"+x+"-e")?' selected="selected"':"")+'">Alphabetics ( exactly '+x+" character"+((x>1)?"s":"")+" )</option>"}t+="</optgroup>";t+='<option disabled="disabled"></option>';t+='<optgroup label="Numeric Digits Only">';for(x=1;x<=25;x++){t+='<option value="numerics-'+x+'"'+((B.expected==="numerics-"+x)?' selected="selected"':"")+'">Numeric Digits ( '+x+" digit minimum )</option>";t+='<option value="numerics-'+x+'-e"'+((B.expected==="numerics-"+x+"-e")?' selected="selected"':"")+'">Numeric Digits ( exactly '+x+" digit"+((x>1)?"s":"")+" )</option>"}t+="</optgroup>";t+="</select><br />";t+="<small>Only Users/Members will be required to meet this criteria.</small><br />";t+="<small>* Administrators are exempt from this.</small>";t+="</td>";t+="</tr>";t+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-spacer"><td colspan="2">&nbsp;</td></tr>';t+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-levels">';t+='<td colspan="2">';t+='<label for="ws-plugin--s2member-custom-reg-field-configuration-tools-form-levels">Applicable Membership Levels: *</label>';t+="</td>";t+="</tr>";t+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-levels">';t+='<td colspan="2">';t+='<input type="text" property="levels" value="'+a(B.levels)+'" id="ws-plugin--s2member-custom-reg-field-configuration-tools-form-levels" /><br />';t+="<small>Please use comma-delimited Level #'s: <code>0,1,2,3,4</code> or type: <code>all</code>.</small><br />";t+="<small>This allows you to enable this field - only at specific Membership Levels.</small>";t+="</td>";t+="</tr>";t+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-spacer"><td colspan="2">&nbsp;</td></tr>';t+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-editable">';t+='<td colspan="2">';t+='<label for="ws-plugin--s2member-custom-reg-field-configuration-tools-form-editable">Allow Profile Edits: *</label>';t+="</td>";t+="</tr>";t+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-editable">';t+='<td colspan="2">';t+='<select property="editable" id="ws-plugin--s2member-custom-reg-field-configuration-tools-form-editable">';t+='<option value="yes"'+((B.editable==="yes")?' selected="selected"':"")+'">Yes ( editable )</option>';t+='<option value="no"'+((B.editable==="no")?' selected="selected"':"")+'">No ( uneditable after registration )</option>';t+='<option value="no-invisible"'+((B.editable==="no-invisible")?' selected="selected"':"")+'">No ( uneditable &amp; totally invisible )</option>';t+="</select><br />";t+="<small>If <code>No</code>, this field will be un-editable after registration.</small><br />";t+="<small>* Administrators are exempt from this.</small>";t+="</td>";t+="</tr>";t+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-spacer"><td colspan="2">&nbsp;</td></tr>';t+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-classes">';t+='<td colspan="2">';t+='<label for="ws-plugin--s2member-custom-reg-field-configuration-tools-form-classes">CSS Classes: ( optional )</label>';t+="</td>";t+="</tr>";t+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-classes">';t+='<td colspan="2">';t+='<input type="text" property="classes" value="'+a(B.classes)+'" id="ws-plugin--s2member-custom-reg-field-configuration-tools-form-classes" /><br />';t+="<small>Example: <code>my-style-1 my-style-2</code></small>";t+="</td>";t+="</tr>";t+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-spacer"><td colspan="2">&nbsp;</td></tr>';t+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-styles">';t+='<td colspan="2">';t+='<label for="ws-plugin--s2member-custom-reg-field-configuration-tools-form-styles">CSS Styles: ( optional )</label>';t+="</td>";t+="</tr>";t+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-styles">';t+='<td colspan="2">';t+='<input type="text" property="styles" value="'+a(B.styles)+'" id="ws-plugin--s2member-custom-reg-field-configuration-tools-form-styles" /><br />';t+="<small>Example: <code>color:#000000; background:#FFFFFF;</code></small>";t+="</td>";t+="</tr>";t+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-spacer"><td colspan="2">&nbsp;</td></tr>';t+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-attrs">';t+='<td colspan="2">';t+='<label for="ws-plugin--s2member-custom-reg-field-configuration-tools-form-attrs">Other Attributes: ( optional )</label>';t+="</td>";t+="</tr>";t+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-attrs">';t+='<td colspan="2">';t+='<input type="text" property="attrs" value="'+a(B.attrs)+'" id="ws-plugin--s2member-custom-reg-field-configuration-tools-form-attrs" /><br />';t+='<small>Example: <code>onkeyup="" onblur=""</code></small>';t+="</td>";t+="</tr>";t+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-spacer"><td colspan="2">&nbsp;</td></tr>';t+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-buttons">';t+='<td align="left">';t+='<input type="button" value="Cancel" onclick="ws_plugin__s2member_customRegFieldCancel();" />';t+="</td>";t+='<td align="right">';t+='<input type="button" value="'+((u)?"Update This Field":"Create Registration Field")+'" onclick="'+((u)?"ws_plugin__s2member_customRegFieldUpdate("+A+");":"ws_plugin__s2member_customRegFieldCreate();")+'" />';t+="</td>";t+="</tr>";t+="</tbody>";t+="</table>";t+="<div>";b("body").append(t);tb_show(((u)?"Editing Registration Field":"New Custom Registration Field"),"#TB_inline?inlineId=ws-plugin--s2member-custom-reg-field-configuration-thickbox-tools-form");b(window).trigger("resize"),b("table#ws-plugin--s2member-custom-reg-field-configuration-tools-form").show()}i.html(z)};var e=function(){b(window).resize(function(){var s,t;s=b(window).width(),t=b(window).height(),s=(s>720)?720:s;b("#TB_ajaxContent").css({width:s-50,height:t-75,margin:0,padding:0})})};var p=function(){var s=l.length,v=0,w,u="",t="o";u+="<tbody>";u+="<tr>";u+="<th>Order</th>";u+="<th>Field Type</th>";u+="<th>Unique ID</th>";u+="<th>Required</th>";u+="<th>Levels</th>";u+="<th>- Tools -</th>";u+="</tr>";if(l.length>0){for(v=0;v<l.length;v++){t=(t==="o")?"e":"o";w=l[v];u+='<tr class="'+a(t)+" ws-plugin--s2member-custom-reg-field-configuration-table-row-"+v+'">';u+='<td nowrap="nowrap"><a class="ws-plugin--s2member-custom-reg-field-configuration-move-up" href="#" onclick="ws_plugin__s2member_customRegFieldMoveUp('+v+'); return false;"></a><a class="ws-plugin--s2member-custom-reg-field-configuration-move-down" href="#" onclick="ws_plugin__s2member_customRegFieldMoveDown('+v+'); return false;"></a></td>';u+='<td nowrap="nowrap">'+esc_html(g(w.type))+"</td>";u+='<td nowrap="nowrap">'+esc_html(w.id)+"</td>";u+='<td nowrap="nowrap">'+esc_html(w.required)+"</td>";u+='<td nowrap="nowrap">'+esc_html(w.levels)+"</td>";u+='<td nowrap="nowrap"><a class="ws-plugin--s2member-custom-reg-field-configuration-edit" href="#" onclick="ws_plugin__s2member_customRegFieldEdit('+v+'); return false;"></a><a class="ws-plugin--s2member-custom-reg-field-configuration-delete" href="#" onclick="ws_plugin__s2member_customRegFieldDelete('+v+'); return false;"></a></td>';u+="</tr>"}}else{u+="<tr>";u+='<td colspan="6">No Custom Fields are configured.</td>';u+="</tr>"}u+="</tbody>";o.html(u)};j(),e(),p()})()}b("input#ws-plugin--s2member-brute-force-restrictions-reset-button").click(function(){var c=b(this);c.val("one moment please ...");b.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(d){alert("s2Member's Brute Force Restriction Logs have all been reset."),c.val("Reset Brute Force Logs")});return false});b("input#ws-plugin--s2member-ip-restrictions-reset-button").click(function(){var c=b(this);c.val("one moment please ...");b.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(d){alert("s2Member's IP Restriction Logs have all been reset."),c.val("Reset IP Restriction Logs")});return false})}else{if(location.href.match(/page\=ws-plugin--s2member-paypal-ops/)){b("select#ws-plugin--s2member-auto-eot-system-enabled").change(function(){var d=b(this),e=d.val();var c=b("p#ws-plugin--s2member-auto-eot-system-enabled-via-cron");if(e==2){c.show()}else{c.hide()}})}else{if(location.href.match(/page\=ws-plugin--s2member-els-ops/)){b("select#ws-plugin--s2member-custom-reg-opt-in").change(function(){var e=b(this),f=e.val();var d=b("tr.ws-plugin--s2member-custom-reg-opt-in-label-row");var c=b("img.ws-plugin--s2member-custom-reg-opt-in-label-prev-img");if(f<=0){d.css("display","none"),c.attr("src",c.attr("src").replace(/\/checked\.png$/,"/unchecked.png"))}else{if(f==1){d.css("display",""),c.attr("src",c.attr("src").replace(/\/unchecked\.png$/,"/checked.png"))}else{if(f==2){d.css("display",""),c.attr("src",c.attr("src").replace(/\/checked\.png$/,"/unchecked.png"))}}}})}else{if(location.href.match(/page\=ws-plugin--s2member-paypal-buttons/)){b("select#ws-plugin--s2member-level1-term, select#ws-plugin--s2member-level2-term, select#ws-plugin--s2member-level3-term, select#ws-plugin--s2member-level4-term, select#ws-plugin--s2member-modification-term").change(function(){var d=this.id.replace(/^ws-plugin--s2member-(.+?)-term$/g,"$1");var c=(b(this).val().split("-")[2].replace(/[^0-1BN]/g,"")==="BN")?1:0;b("p#ws-plugin--s2member-"+d+"-trial-line").css("display",(c?"none":""));b("span#ws-plugin--s2member-"+d+"-trial-then").css("display",(c?"none":""));b("span#ws-plugin--s2member-"+d+"-20p-rule").css("display",(c?"none":""));(c)?b("input#ws-plugin--s2member-"+form+"-trial-period").val(0):null;(c)?b("input#ws-plugin--s2member-"+form+"-trial-amount").val("0.00"):null});b("input#ws-plugin--s2member-level1-ccaps, input#ws-plugin--s2member-level2-ccaps, input#ws-plugin--s2member-level3-ccaps, input#ws-plugin--s2member-level4-ccaps, input#ws-plugin--s2member-modification-ccaps").keyup(function(){var c=this.value.replace(/^\+/,""),d=(this.value.match(/^\+/))?"+":"";if(c.match(/[^a-z_0-9,]/)){this.value=d+b.trim(b.trim(c).replace(/[ \-]/g,"_").replace(/[^A-Z_0-9,]/gi,"").toLowerCase())}});ws_plugin__s2member_paypalButtonGenerate=function(f){var c='[s2Member-PayPal-Button %%attrs%% image="default" output="button" /]',r="",v={};v.level0='<?php echo c_ws_plugin__s2member_utils_strings::esc_sq ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["level0_label"]); ?>';v.level1='<?php echo c_ws_plugin__s2member_utils_strings::esc_sq ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["level1_label"]); ?>';v.level2='<?php echo c_ws_plugin__s2member_utils_strings::esc_sq ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["level2_label"]); ?>';v.level3='<?php echo c_ws_plugin__s2member_utils_strings::esc_sq ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["level3_label"]); ?>';v.level4='<?php echo c_ws_plugin__s2member_utils_strings::esc_sq ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["level4_label"]); ?>';var o=b("input#ws-plugin--s2member-"+f+"-shortcode");var g=b("textarea#ws-plugin--s2member-"+f+"-button");var k=b("select#ws-plugin--s2member-modification-level");var h=(f==="modification")?k.val().split(":",2)[1]:f.replace(/^level/,"");var l=v["level"+h].replace(/"/g,"");var s=b.trim(b("input#ws-plugin--s2member-"+f+"-desc").val().replace(/"/g,""));var p=b("input#ws-plugin--s2member-"+f+"-trial-amount").val().replace(/[^0-9\.]/g,"");var e=b("input#ws-plugin--s2member-"+f+"-trial-period").val().replace(/[^0-9]/g,"");var j=b("select#ws-plugin--s2member-"+f+"-trial-term").val().replace(/[^A-Z]/g,"");var m=b("input#ws-plugin--s2member-"+f+"-amount").val().replace(/[^0-9\.]/g,"");var u=b("select#ws-plugin--s2member-"+f+"-term").val().split("-")[0].replace(/[^0-9]/g,"");var w=b("select#ws-plugin--s2member-"+f+"-term").val().split("-")[1].replace(/[^A-Z]/g,"");var t=b("select#ws-plugin--s2member-"+f+"-term").val().split("-")[2].replace(/[^0-1BN]/g,"");var d=b.trim(b("input#ws-plugin--s2member-"+f+"-page-style").val().replace(/"/g,""));var i=b("select#ws-plugin--s2member-"+f+"-currency").val().replace(/[^A-Z]/g,"");var n=b.trim(b.trim(b("input#ws-plugin--s2member-"+f+"-ccaps").val()).replace(/[ \-]/g,"_").replace(/[^A-Z_0-9,]/gi,"").toLowerCase());n=(b.trim(b("input#ws-plugin--s2member-"+f+"-ccaps").val()).match(/^\+/))?"+"+n.toLowerCase():n.toLowerCase();e=(t==="BN")?"0":e;p=(!p||isNaN(p)||p<0.01||e<=0)?"0":p;var q=(t==="BN"&&w!=="L")?h+":"+n+":"+u+" "+w:h+":"+n;q=q.replace(/\:+$/g,"");if(p!=="0"&&(isNaN(p)||p<0)){alert("Oops, a slight problem:\n\nWhen provided, Trial Amount must be >= 0.00");return false}else{if(p!=="0"&&p>10000){alert("Oops, a slight problem:\n\nMaximum Trial Amount is: 10000.00");return false}else{if(j==="D"&&e>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(j==="W"&&e>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(j==="M"&&e>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(j==="Y"&&e>1){alert("Oops, a slight problem:\n\nMax Trial Period Years is: 1.");return false}else{if(!m||isNaN(m)||m<0.01){alert("Oops, a slight problem:\n\nAmount must be >= 0.01");return false}else{if(m>10000){alert("Oops, a slight problem:\n\nMaximum Amount is: 10000.00");return false}else{if(!s){alert("Oops, a slight problem:\n\nPlease type a Description for this Button.");return false}}}}}}}}}g.html(g.val().replace(/ \<\!--(\<input type\="hidden" name\="(amount|src|sra|a1|p1|t1|a3|p3|t3)" value\="(.*?)" \/\>)--\>/g," $1"));(parseInt(e)<=0)?g.html(g.val().replace(/ (\<input type\="hidden" name\="(a1|p1|t1)" value\="(.*?)" \/\>)/g," <!--$1-->")):null;(t==="BN")?g.html(g.val().replace(/ (\<input type\="hidden" name\="cmd" value\=")(.*?)(" \/\>)/g," $1_xclick$3")):null;(t==="BN")?g.html(g.val().replace(/ (\<input type\="hidden" name\="(src|sra|a1|p1|t1|a3|p3|t3)" value\="(.*?)" \/\>)/g," <!--$1-->")):null;(t!=="BN")?g.html(g.val().replace(/ (\<input type\="hidden" name\="cmd" value\=")(.*?)(" \/\>)/g," $1_xclick-subscriptions$3")):null;(t!=="BN")?g.html(g.val().replace(/ (\<input type\="hidden" name\="amount" value\="(.*?)" \/\>)/g," <!--$1-->")):null;r+='level="'+a(h)+'" ccaps="'+a(n)+'" desc="'+a(s)+'" ps="'+a(d)+'" cc="'+a(i)+'" ns="1" custom="<?php echo c_ws_plugin__s2member_utils_strings::esc_sq (esc_attr ($_SERVER["HTTP_HOST"])); ?>"';r+=' ta="'+a(p)+'" tp="'+a(e)+'" tt="'+a(j)+'" ra="'+a(m)+'" rp="'+a(u)+'" rt="'+a(w)+'" rr="'+a(t)+'"';r+=(f==="modification")?' modify="1"':"";o.val(c.replace(/%%attrs%%/,r));g.html(g.val().replace(/ name\="item_name" value\="(.*?)"/,' name="item_name" value="'+a(s)+'"'));g.html(g.val().replace(/ name\="item_number" value\="(.*?)"/,' name="item_number" value="'+a(q)+'"'));g.html(g.val().replace(/ name\="page_style" value\="(.*?)"/,' name="page_style" value="'+a(d)+'"'));g.html(g.val().replace(/ name\="currency_code" value\="(.*?)"/,' name="currency_code" value="'+a(i)+'"'));g.html(g.val().replace(/ name\="custom" value\="(.*?)"/,' name="custom" value="<?php echo c_ws_plugin__s2member_utils_strings::esc_sq (esc_attr ($_SERVER["HTTP_HOST"])); ?>"'));g.html(g.val().replace(/ name\="modify" value\="(.*?)"/,' name="modify" value="'+((f==="modification")?"1":"0")+'"'));g.html(g.val().replace(/ name\="amount" value\="(.*?)"/,' name="amount" value="'+a(m)+'"'));g.html(g.val().replace(/ name\="src" value\="(.*?)"/,' name="src" value="'+a(t)+'"'));g.html(g.val().replace(/ name\="a1" value\="(.*?)"/,' name="a1" value="'+a(p)+'"'));g.html(g.val().replace(/ name\="p1" value\="(.*?)"/,' name="p1" value="'+a(e)+'"'));g.html(g.val().replace(/ name\="t1" value\="(.*?)"/,' name="t1" value="'+a(j)+'"'));g.html(g.val().replace(/ name\="a3" value\="(.*?)"/,' name="a3" value="'+a(m)+'"'));g.html(g.val().replace(/ name\="p3" value\="(.*?)"/,' name="p3" value="'+a(u)+'"'));g.html(g.val().replace(/ name\="t3" value\="(.*?)"/,' name="t3" value="'+a(w)+'"'));b("div#ws-plugin--s2member-"+f+"-button-prev").html(g.val().replace(/\<form/,'<form target="_blank"').replace(/\<\?php echo S2MEMBER_CURRENT_USER_VALUE_FOR_PP_(ON0|OS0); \?\>/g,""));(f==="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.");o.each(function(){this.focus(),this.select()});return false};ws_plugin__s2member_paypalSpButtonGenerate=function(){var q='[s2Member-PayPal-Button %%attrs%% image="default" output="button" /]',p="";var n=b("input#ws-plugin--s2member-sp-shortcode");var e=b("textarea#ws-plugin--s2member-sp-button");var f=b("select#ws-plugin--s2member-sp-leading-id").val().replace(/[^0-9]/g,"");var h=b("select#ws-plugin--s2member-sp-additional-ids").val()||[];var o=b("select#ws-plugin--s2member-sp-hours").val().replace(/[^0-9]/g,"");var k=b("input#ws-plugin--s2member-sp-amount").val().replace(/[^0-9\.]/g,"");var j=b.trim(b("input#ws-plugin--s2member-sp-desc").val().replace(/"/g,""));var m=b.trim(b("input#ws-plugin--s2member-sp-page-style").val().replace(/"/g,""));var d=b("select#ws-plugin--s2member-sp-currency").val().replace(/[^A-Z]/g,"");if(!f){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 -> General Options -> Specific Post/Page Access Restrictions.");return false}else{if(!k||isNaN(k)||k<0.01){alert("Oops, a slight problem:\n\nAmount must be >= 0.01");return false}else{if(k>10000){alert("Oops, a slight problem:\n\nMaximum Amount is: 10000.00");return false}else{if(!j){alert("Oops, a slight problem:\n\nPlease type a Description for this Button.");return false}}}}for(var g=0,c=f;g<h.length;g++){if(h[g]&&h[g]!==f){c+=","+h[g]}}var l="sp:"+c+":"+o;p+='ids="'+a(c)+'" exp="'+a(o)+'" desc="'+a(j)+'" ps="'+a(m)+'" cc="'+a(d)+'" ns="1"';p+=' custom="<?php echo c_ws_plugin__s2member_utils_strings::esc_sq (esc_attr ($_SERVER["HTTP_HOST"])); ?>" ra="'+a(k)+'" sp="1"';n.val(q.replace(/%%attrs%%/,p));e.html(e.val().replace(/ name\="item_name" value\="(.*?)"/,' name="item_name" value="'+a(j)+'"'));e.html(e.val().replace(/ name\="item_number" value\="(.*?)"/,' name="item_number" value="'+a(l)+'"'));e.html(e.val().replace(/ name\="page_style" value\="(.*?)"/,' name="page_style" value="'+a(m)+'"'));e.html(e.val().replace(/ name\="currency_code" value\="(.*?)"/,' name="currency_code" value="'+a(d)+'"'));e.html(e.val().replace(/ name\="custom" value\="(.*?)"/,' name="custom" value="<?php echo c_ws_plugin__s2member_utils_strings::esc_sq (esc_attr ($_SERVER["HTTP_HOST"])); ?>"'));e.html(e.val().replace(/ name\="amount" value\="(.*?)"/,' name="amount" value="'+a(k)+'"'));b("div#ws-plugin--s2member-sp-button-prev").html(e.val().replace(/\<form/,'<form target="_blank"'));alert("Your Button has been generated.\nPlease copy/paste the Shortcode Format into your Membership Options Page.");n.each(function(){this.focus(),this.select()});return false};ws_plugin__s2member_paypalRegLinkGenerate=function(){var j=b("select#ws-plugin--s2member-reg-link-level").val().replace(/[^0-9]/g,"");var i=b.trim(b("input#ws-plugin--s2member-reg-link-subscr-id").val());var h=b.trim(b("input#ws-plugin--s2member-reg-link-custom").val());var d=b.trim(b.trim(b("input#ws-plugin--s2member-reg-link-ccaps").val()).replace(/[ \-]/g,"_").replace(/[^A-Z_0-9,]/gi,"").toLowerCase());var f=b.trim(b("input#ws-plugin--s2member-reg-link-fixed-term").val().replace(/[^A-Z 0-9]/gi,"").toUpperCase());var c=b("p#ws-plugin--s2member-reg-link"),g=b("img#ws-plugin--s2member-reg-link-loading");var e=(f&&!f.match(/L$/))?j+":"+d+":"+f:j+":"+d;e=e.replace(/\:+$/g,"");if(!i){alert("Oops, a slight problem:\n\nPaid Subscr. ID is a required value.");return false}else{if(!h||h.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(f&&!f.match(/^[1-9]+ (D|W|M|Y|L)$/)){alert("Oops, a slight problem:\n\nThe Fixed Term Length is not formatted properly.");return false}}}c.hide(),g.show(),b.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:i,s2member_reg_access_link_custom:h,s2member_reg_access_link_item_number:e},function(k){c.show().html('<a href="'+a(k)+'" target="_blank" rel="external">'+esc_html(k)+"</a>"),g.hide()});return false};ws_plugin__s2member_paypalSpLinkGenerate=function(){var j=b("select#ws-plugin--s2member-sp-link-leading-id").val().replace(/[^0-9]/g,"");var h=b("select#ws-plugin--s2member-sp-link-additional-ids").val()||[];var c=b("select#ws-plugin--s2member-sp-link-hours").val().replace(/[^0-9]/g,"");var d=b("p#ws-plugin--s2member-sp-link"),g=b("img#ws-plugin--s2member-sp-link-loading");if(!j){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 -> General Options -> Specific Post/Page Access Restrictions.");return false}for(var e=0,f=j;e<h.length;e++){if(h[e]&&h[e]!==j){f+=","+h[e]}}d.hide(),g.show(),b.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:f,s2member_sp_access_link_hours:c},function(i){d.show().html('<a href="'+a(i)+'" target="_blank" rel="external">'+esc_html(i)+"</a>"),g.hide()});return false}}}}}}});
1
+ jQuery(document).ready(function(b){var a=esc_html=function(c){return String(c).replace(/"/g,"&quot;").replace(/\</g,"&lt;").replace(/\>/g,"&gt;")};if(location.href.match(/page\=ws-plugin--s2member-mms-options/)){b("select#ws-plugin--s2member-mms-registration-file").change(function(){if(b(this).val()==="wp-signup"){b("div#ws-plugin--s2member-mms-registration-support-package-details-wrapper").show(),b("div.ws-plugin--s2member-mms-registration-wp-login, table.ws-plugin--s2member-mms-registration-wp-login").hide(),b("div.ws-plugin--s2member-mms-registration-wp-signup, table.ws-plugin--s2member-mms-registration-wp-signup").show();b("div.ws-plugin--s2member-mms-registration-wp-signup-blogs-level0, table.ws-plugin--s2member-mms-registration-wp-signup-blogs-level0")[((b("select#ws-plugin--s2member-mms-registration-grants").val()==="all")?"show":"hide")](),b("input#ws-plugin--s2member-mms-registration-blogs-level0").val(((b("select#ws-plugin--s2member-mms-registration-grants").val()==="all")?"1":"0"))}else{if(b(this).val()==="wp-login"){b("div#ws-plugin--s2member-mms-registration-support-package-details-wrapper").hide(),b("div.ws-plugin--s2member-mms-registration-wp-login, table.ws-plugin--s2member-mms-registration-wp-login").show(),b("div.ws-plugin--s2member-mms-registration-wp-signup, table.ws-plugin--s2member-mms-registration-wp-signup").hide(),b("input#ws-plugin--s2member-mms-registration-blogs-level0").val("0")}}}).trigger("change");b("select#ws-plugin--s2member-mms-registration-grants").change(function(){b("select#ws-plugin--s2member-mms-registration-file").trigger("change")})}else{if(location.href.match(/page\=ws-plugin--s2member-bridges/)){b("select#ws-plugin--s2member-bbpress-ovg").change(function(){if(b(this).val()==="0"){b("span#ws-plugin--s2member-bbpress-ovg-off-note").css("display","inline");var c='form#ws-plugin--s2member-bridge-bbpress-form label[for="ws_plugin--s2member-bridge-bbpress-min-level"]';b(c).text(b(c).text().replace(/to (read\/)?participate/i,"to read/participate")),b("select#ws-plugin--s2member-bbpress-min-level option").each(function(){b(this).text(b(this).text().replace(/\( to( read and)? participate \)/i,"( to read and participate )"))})}else{if(b(this).val()==="1"){b("span#ws-plugin--s2member-bbpress-ovg-off-note").css("display","none");var c='form#ws-plugin--s2member-bridge-bbpress-form label[for="ws_plugin--s2member-bridge-bbpress-min-level"]';b(c).text(b(c).text().replace(/to (read\/)?participate/i,"to participate")),b("select#ws-plugin--s2member-bbpress-min-level option").each(function(){b(this).text(b(this).text().replace(/\( to( read and)? participate \)/i,"( to participate )"))})}}}).trigger("change")}else{if(location.href.match(/page\=ws-plugin--s2member-options/)){ws_plugin__s2member_generateSecurityKey=function(){var f=function(h,g){h=(arguments.length<1)?0:h;g=(arguments.length<2)?2147483647:g;return Math.floor(Math.random()*(g-h+1))+h};var e="ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()";for(var d=0,c="";d<56;d++){c+=e.substr(f(0,e.length-1),1)}b("input#ws-plugin--s2member-sec-encryption-key").val(c);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.")){b("input#ws-plugin--s2member-sec-encryption-key").attr("disabled",false)}return false};ws_plugin__s2member_securityKeyHistory=function(){b("div#ws-plugin--s2member-sec-encryption-key-history").toggle();return false};if(b("input#ws-plugin--s2member-custom-reg-fields").length&&b("div#ws-plugin--s2member-custom-reg-field-configuration").length){(function(){var c=b("input#ws-plugin--s2member-custom-reg-fields");var f=b("div#ws-plugin--s2member-custom-reg-field-configuration");var l=(c.val())?b.JSON.parse(c.val()):[];l=(l instanceof Array)?l:[];var k='<div id="ws-plugin--s2member-custom-reg-field-configuration-tools"></div>';var r='<table id="ws-plugin--s2member-custom-reg-field-configuration-table"></table>';f.html(k+r);var i=b("div#ws-plugin--s2member-custom-reg-field-configuration-tools");var o=b("table#ws-plugin--s2member-custom-reg-field-configuration-table");ws_plugin__s2member_customRegFieldTypeChange=function(t){var s,v,u=b(t).val();s="tr.ws-plugin--s2member-custom-reg-field-configuration-tools-form-options";v="tr.ws-plugin--s2member-custom-reg-field-configuration-tools-form-expected";if(u.match(/^(text|textarea|checkbox|pre_checkbox)$/)){b(s).css("display","none"),b(s).prev("tr").css("display","none")}else{b(s).css("display",""),b(s).prev("tr").css("display","")}if(u.match(/^(select|selects|checkboxes|radios)$/)){b(v).css("display","none"),b(v).prev("tr").css("display","none")}else{b(v).css("display",""),b(v).prev("tr").css("display","")}};ws_plugin__s2member_customRegFieldDelete=function(t){var s=new Array();for(var u=0;u<l.length;u++){if(u!==t){s.push(l[u])}}l=s,q(),p()};ws_plugin__s2member_customRegFieldMoveUp=function(u){if(typeof l[u]==="object"&&typeof l[u-1]==="object"){var t=l[u-1],s=l[u];l[u-1]=s,l[u]=t;q(),p()}};ws_plugin__s2member_customRegFieldMoveDown=function(u){if(typeof l[u]==="object"&&typeof l[u+1]==="object"){var s=l[u+1],t=l[u];l[u+1]=t,l[u]=s;q(),p()}};ws_plugin__s2member_customRegFieldCreate=function(){var s=b("table#ws-plugin--s2member-custom-reg-field-configuration-tools-form"),t={};b(":input[property]",s).each(function(){var v=b(this),u=v.attr("property"),w=b.trim(v.val());t[u]=w});if((t=d(t))){l.push(t),q(),j(),p(),n();setTimeout(function(){var u="tr.ws-plugin--s2member-custom-reg-field-configuration-table-row-"+(l.length-1);alert('Field created successfully.\n* Remember to "Save Changes".');b(u).effect("highlight",1000)},500)}};ws_plugin__s2member_customRegFieldUpdate=function(t){var s=b("table#ws-plugin--s2member-custom-reg-field-configuration-tools-form"),u={};b(":input[property]",s).each(function(){var x=b(this),w=x.attr("property"),y=b.trim(x.val());u[w]=y});if((u=d(u,t))){l[t]=u,q(),j(),p(),n();var v="tr.ws-plugin--s2member-custom-reg-field-configuration-table-row-"+t;b(v).effect("highlight",1000)}};ws_plugin__s2member_customRegFieldAdd=function(){j(true)};ws_plugin__s2member_customRegFieldEdit=function(s){j(false,s),n()};ws_plugin__s2member_customRegFieldCancel=function(){j(),n()};var d=function(w,u){var s=(typeof u==="number"&&typeof l[u]==="object")?true:false,x=[],t,v;if(typeof w!=="object"){x.push("Invalid field object. Please try again.")}else{if(!w.id){x.push("Unique Field ID:\nThis is required. Please try again.")}else{if(h(w.id)&&(!s||w.id!==l[u].id)){x.push("Unique Field ID:\nThat Field ID already exists. Please try again.")}}if(!w.label){x.push("Field Label/Description:\nThis is required. Please try again.")}if(w.type.match(/^(select|selects|checkboxes|radios)$/)){w.expected="";if(!w.options){x.push("Option Configuration File:\nThis is required. Please try again.")}else{t=w.options.split(/[\r\n]+/);for(v=0;v<t.length;v++){t[v]=b.trim(t[v]);if(!t[v].match(/^([^\|]*)(\|)([^\|]*)(\|default)?$/)){x.push("Option Configuration File:\nInvalid configuration at line #"+(v+1)+".");break}}w.options=b.trim(t.join("\n"))}}else{w.options=""}if(!(w.levels=w.levels.replace(/ /g,""))){x.push("Applicable Levels:\nThis is required. Please try again.")}else{if(!w.levels.match(/^(all|[0-9,]+)$/)){x.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(w.classes&&w.classes.match(/[^a-z 0-9 _ \-]/i)){x.push("CSS Classes:\nContains invalid characters. Please try again.\n( only: alphanumerics, underscores, hyphens, spaces )")}if(w.styles&&w.styles.match(/["\=\>\<]/)){x.push('CSS Styles:\nContains invalid characters. Please try again.\n( do NOT use these characters: = " < > )')}if(w.attrs&&w.attrs.match(/[\>\<]/)){x.push("Other Attributes:\nContains invalid characters. Please try again.\n( do NOT use these characters: < > )")}}if(x.length>0){alert(x.join("\n\n"));return false}else{return w}};var q=function(){c.val(((l.length>0)?b.JSON.stringify(l):""))};var m=function(s){return(typeof s==="string")?b.trim(s).toLowerCase().replace(/[^a-z0-9]/g,"_"):""};var g=function(t){var s={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 s[t]==="string"){return s[t]}return""};var h=function(s){for(var t=0;t<l.length;t++){if(l[t].id===s){return true}}};var n=function(){scrollTo(0,b("div.ws-plugin--s2member-custom-reg-fields-section").offset()["top"]-100)};var j=function(s,A){var x=0,z="",t="",D=0,y=0,v={id:"",label:"",type:"text",options:"",expected:"",required:"yes",levels:"all",editable:"yes",classes:"",styles:"",attrs:""};var u=(typeof A==="number"&&typeof l[A]==="object")?true:false,C=(s||u)?true:false,B=(u)?l[A]:v;z+='<a href="#" onclick="ws_plugin__s2member_customRegFieldAdd(); return false;">Add New Field</a>';tb_remove(),b("div#ws-plugin--s2member-custom-reg-field-configuration-thickbox-tools-form").remove();if(C){t+='<div id="ws-plugin--s2member-custom-reg-field-configuration-thickbox-tools-form">';t+='<table id="ws-plugin--s2member-custom-reg-field-configuration-tools-form">';t+="<tbody>";t+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-type">';t+='<td colspan="2">';t+='<label for="ws-plugin--s2member-custom-reg-field-configuration-tools-form-type">Form Field Type: *</label>';t+="</td>";t+="</tr>";t+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-type">';t+='<td colspan="2">';t+='<select property="type" onchange="ws_plugin__s2member_customRegFieldTypeChange(this);" id="ws-plugin--s2member-custom-reg-field-configuration-tools-form-type">';t+='<option value="text"'+((B.type==="text")?' selected="selected"':"")+'">'+esc_html(g("text"))+"</option>";t+='<option value="textarea"'+((B.type==="textarea")?' selected="selected"':"")+'">'+esc_html(g("textarea"))+"</option>";t+='<option value="select"'+((B.type==="select")?' selected="selected"':"")+'">'+esc_html(g("select"))+"</option>";t+='<option value="selects"'+((B.type==="selects")?' selected="selected"':"")+'">'+esc_html(g("selects"))+"</option>";t+='<option value="checkbox"'+((B.type==="checkbox")?' selected="selected"':"")+'">'+esc_html(g("checkbox"))+"</option>";t+='<option value="pre_checkbox"'+((B.type==="pre_checkbox")?' selected="selected"':"")+'">'+esc_html(g("pre_checkbox"))+"</option>";t+='<option value="checkboxes"'+((B.type==="checkboxes")?' selected="selected"':"")+'">'+esc_html(g("checkboxes"))+"</option>";t+='<option value="radios"'+((B.type==="radios")?' selected="selected"':"")+'">'+esc_html(g("radios"))+"</option>";t+="</select>";t+="</td>";t+="</tr>";t+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-spacer"><td colspan="2">&nbsp;</td></tr>';t+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-label">';t+='<td colspan="2">';t+='<label for="ws-plugin--s2member-custom-reg-field-configuration-tools-form-label">Field Label/Desc: *</label>';t+="</td>";t+="</tr>";t+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-label">';t+='<td colspan="2">';t+='<input type="text" property="label" value="'+a(B.label)+'" id="ws-plugin--s2member-custom-reg-field-configuration-tools-form-label" /><br />';t+="<small>Examples: <code>Choose Country</code>, <code>Street Address</code></small>";t+="</td>";t+="</tr>";t+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-spacer"><td colspan="2">&nbsp;</td></tr>';t+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-id">';t+='<td colspan="2">';t+='<label for="ws-plugin--s2member-custom-reg-field-configuration-tools-form-id">Unique Field ID: *</label></label>';t+="</td>";t+="</tr>";t+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-id">';t+='<td colspan="2">';t+='<input type="text" property="id" value="'+a(B.id)+'" maxlength="25" id="ws-plugin--s2member-custom-reg-field-configuration-tools-form-id" /><br />';t+="<small>Examples: <code>country_code</code>, <code>street_address</code></small><br />";t+='<small>e.g. <code>[s2Get user_field="country_code" /]</code></small>';t+="</td>";t+="</tr>";t+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-spacer"><td colspan="2">&nbsp;</td></tr>';t+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-required">';t+='<td colspan="2">';t+='<label for="ws-plugin--s2member-custom-reg-field-configuration-tools-form-required">Field Required: *</label>';t+="</td>";t+="</tr>";t+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-required">';t+='<td colspan="2">';t+='<select property="required" id="ws-plugin--s2member-custom-reg-field-configuration-tools-form-required">';t+='<option value="yes"'+((B.required==="yes")?' selected="selected"':"")+'">Yes ( required )</option>';t+='<option value="no"'+((B.required==="no")?' selected="selected"':"")+'">No ( optional )</option>';t+="</select><br />";t+='<small>If <code>yes</code>, only Users/Members will be "required" to enter this field.</small><br />';t+="<small>* Administrators are exempt from this requirement.</small>";t+="</td>";t+="</tr>";t+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-spacer"'+((B.type.match(/^(text|textarea|checkbox|pre_checkbox)$/))?' style="display:none;"':"")+'><td colspan="2">&nbsp;</td></tr>';t+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-options"'+((B.type.match(/^(text|textarea|checkbox|pre_checkbox)$/))?' style="display:none;"':"")+">";t+='<td colspan="2">';t+='<label for="ws-plugin--s2member-custom-reg-field-configuration-tools-form-options">Option Configuration File: * ( one option per line )</label><br />';t+="<small>Use a pipe <code>|</code> delimited format: <code>option value|option label</code></small>";t+="</td>";t+="</tr>";t+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-options"'+((B.type.match(/^(text|textarea|checkbox|pre_checkbox)$/))?' style="display:none;"':"")+">";t+='<td colspan="2">';t+='<textarea property="options" rows="3" wrap="off" spellcheck="false" id="ws-plugin--s2member-custom-reg-field-configuration-tools-form-options">'+esc_html(B.options)+"</textarea><br />";t+="Here is a quick example:<br />";t+="<small>You can also specify a <em>default</em> option:</small><br />";t+="<code>US|United States|default</code><br />";t+="<code>CA|Canada</code><br />";t+="<code>VI|Virgin Islands (U.S.)</code>";t+="</td>";t+="</tr>";t+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-spacer"'+((B.type.match(/^(select|selects|checkboxes|radios)$/))?' style="display:none;"':"")+'><td colspan="2">&nbsp;</td></tr>';t+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-expected"'+((B.type.match(/^(select|selects|checkboxes|radios)$/))?' style="display:none;"':"")+">";t+='<td colspan="2">';t+='<label for="ws-plugin--s2member-custom-reg-field-configuration-tools-form-expected">Expected Format: *</label>';t+="</td>";t+="</tr>";t+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-expected"'+((B.type.match(/^(select|selects|checkboxes|radios)$/))?' style="display:none;"':"")+">";t+='<td colspan="2">';t+='<select property="expected" id="ws-plugin--s2member-custom-reg-field-configuration-tools-form-expected">';t+='<option value=""'+((B.expected==="")?' selected="selected"':"")+'">Anything Goes</option>';t+='<option disabled="disabled"></option>';t+='<optgroup label="Specific Input Types">';t+='<option value="numeric-wp-commas"'+((B.expected==="numeric-wp-commas")?' selected="selected"':"")+'">Numeric ( with or without decimals, commas allowed )</option>';t+='<option value="numeric"'+((B.expected==="numeric")?' selected="selected"':"")+'">Numeric ( with or without decimals, no commas )</option>';t+='<option value="integer"'+((B.expected==="integer")?' selected="selected"':"")+'">Integer ( whole number, without any decimals )</option>';t+='<option value="integer-gt-0"'+((B.expected==="integer-gt-0")?' selected="selected"':"")+'">Integer > 0 ( whole number, no decimals, greater than 0 )</option>';t+='<option value="float"'+((B.expected==="float")?' selected="selected"':"")+'">Float ( floating point number, decimals required )</option>';t+='<option value="float-gt-0"'+((B.expected==="float-gt-0")?' selected="selected"':"")+'">Float > 0 ( floating point number, decimals required, greater than 0 )</option>';t+='<option value="date"'+((B.expected==="date")?' selected="selected"':"")+'">Date ( required date format: dd/mm/yyyy )</option>';t+='<option value="email"'+((B.expected==="email")?' selected="selected"':"")+'">Email ( require valid email )</option>';t+='<option value="url"'+((B.expected==="url")?' selected="selected"':"")+'">Full URL ( starting with http or https )</option>';t+='<option value="domain"'+((B.expected==="domain")?' selected="selected"':"")+'">Domain Name ( domain name only, without http )</option>';t+='<option value="phone"'+((B.expected==="phone")?' selected="selected"':"")+'">Phone # ( 10 digits w/possible hyphens,spaces,brackets )</option>';t+='<option value="uszip"'+((B.expected==="uszip")?' selected="selected"':"")+'">US Zipcode ( 5-9 digits w/possible hyphen )</option>';t+='<option value="cazip"'+((B.expected==="cazip")?' selected="selected"':"")+'">Canadian Zipcode ( 6 alpha-numerics w/possible space )</option>';t+='<option value="uczip"'+((B.expected==="uczip")?' selected="selected"':"")+'">US/Canadian Zipcode ( either a US or Canadian zipcode )</option>';t+="</optgroup>";t+='<option disabled="disabled"></option>';t+='<optgroup label="Any Character Combination">';for(x=1;x<=25;x++){t+='<option value="any-'+x+'"'+((B.expected==="any-"+x)?' selected="selected"':"")+'">Any Character Combination ( '+x+" character minimum )</option>";t+='<option value="any-'+x+'-e"'+((B.expected==="any-"+x+"-e")?' selected="selected"':"")+'">Any Character Combination ( exactly '+x+" character"+((x>1)?"s":"")+" )</option>"}t+="</optgroup>";t+='<option disabled="disabled"></option>';t+='<optgroup label="Alphanumerics, Spaces &amp; Punctuation Only">';for(x=1;x<=25;x++){t+='<option value="alphanumerics-spaces-punctuation-'+x+'"'+((B.expected==="alphanumerics-spaces-punctuation-"+x)?' selected="selected"':"")+'">Alphanumerics, Spaces &amp; Punctuation ( '+x+" character minimum )</option>";t+='<option value="alphanumerics-spaces-punctuation-'+x+'-e"'+((B.expected==="alphanumerics-spaces-punctuation-"+x+"-e")?' selected="selected"':"")+'">Alphanumerics, Spaces &amp; Punctuation ( exactly '+x+" character"+((x>1)?"s":"")+" )</option>"}t+="</optgroup>";t+='<option disabled="disabled"></option>';t+='<optgroup label="Alphanumerics &amp; Spaces Only">';for(x=1;x<=25;x++){t+='<option value="alphanumerics-spaces-'+x+'"'+((B.expected==="alphanumerics-spaces-"+x)?' selected="selected"':"")+'">Alphanumerics &amp; Spaces ( '+x+" character minimum )</option>";t+='<option value="alphanumerics-spaces-'+x+'-e"'+((B.expected==="alphanumerics-spaces-"+x+"-e")?' selected="selected"':"")+'">Alphanumerics &amp; Spaces ( exactly '+x+" character"+((x>1)?"s":"")+" )</option>"}t+="</optgroup>";t+='<option disabled="disabled"></option>';t+='<optgroup label="Alphanumerics &amp; Punctuation Only">';for(x=1;x<=25;x++){t+='<option value="alphanumerics-punctuation-'+x+'"'+((B.expected==="alphanumerics-punctuation-"+x)?' selected="selected"':"")+'">Alphanumerics &amp; Punctuation ( '+x+" character minimum )</option>";t+='<option value="alphanumerics-punctuation-'+x+'-e"'+((B.expected==="alphanumerics-punctuation-"+x+"-e")?' selected="selected"':"")+'">Alphanumerics &amp; Punctuation ( exactly '+x+" character"+((x>1)?"s":"")+" )</option>"}t+="</optgroup>";t+='<option disabled="disabled"></option>';t+='<optgroup label="Alphanumerics Only">';for(x=1;x<=25;x++){t+='<option value="alphanumerics-'+x+'"'+((B.expected==="alphanumerics-"+x)?' selected="selected"':"")+'">Alphanumerics ( '+x+" character minimum )</option>";t+='<option value="alphanumerics-'+x+'-e"'+((B.expected==="alphanumerics-"+x+"-e")?' selected="selected"':"")+'">Alphanumerics ( exactly '+x+" character"+((x>1)?"s":"")+" )</option>"}t+="</optgroup>";t+='<option disabled="disabled"></option>';t+='<optgroup label="Alphabetics Only">';for(x=1;x<=25;x++){t+='<option value="alphabetics-'+x+'"'+((B.expected==="alphabetics-"+x)?' selected="selected"':"")+'">Alphabetics ( '+x+" character minimum )</option>";t+='<option value="alphabetics-'+x+'-e"'+((B.expected==="alphabetics-"+x+"-e")?' selected="selected"':"")+'">Alphabetics ( exactly '+x+" character"+((x>1)?"s":"")+" )</option>"}t+="</optgroup>";t+='<option disabled="disabled"></option>';t+='<optgroup label="Numeric Digits Only">';for(x=1;x<=25;x++){t+='<option value="numerics-'+x+'"'+((B.expected==="numerics-"+x)?' selected="selected"':"")+'">Numeric Digits ( '+x+" digit minimum )</option>";t+='<option value="numerics-'+x+'-e"'+((B.expected==="numerics-"+x+"-e")?' selected="selected"':"")+'">Numeric Digits ( exactly '+x+" digit"+((x>1)?"s":"")+" )</option>"}t+="</optgroup>";t+="</select><br />";t+="<small>Only Users/Members will be required to meet this criteria.</small><br />";t+="<small>* Administrators are exempt from this.</small>";t+="</td>";t+="</tr>";t+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-spacer"><td colspan="2">&nbsp;</td></tr>';t+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-levels">';t+='<td colspan="2">';t+='<label for="ws-plugin--s2member-custom-reg-field-configuration-tools-form-levels">Applicable Membership Levels: *</label>';t+="</td>";t+="</tr>";t+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-levels">';t+='<td colspan="2">';t+='<input type="text" property="levels" value="'+a(B.levels)+'" id="ws-plugin--s2member-custom-reg-field-configuration-tools-form-levels" /><br />';t+="<small>Please use comma-delimited Level #'s: <code>0,1,2,3,4</code> or type: <code>all</code>.</small><br />";t+="<small>This allows you to enable this field - only at specific Membership Levels.</small>";t+="</td>";t+="</tr>";t+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-spacer"><td colspan="2">&nbsp;</td></tr>';t+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-editable">';t+='<td colspan="2">';t+='<label for="ws-plugin--s2member-custom-reg-field-configuration-tools-form-editable">Allow Profile Edits: *</label>';t+="</td>";t+="</tr>";t+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-editable">';t+='<td colspan="2">';t+='<select property="editable" id="ws-plugin--s2member-custom-reg-field-configuration-tools-form-editable">';t+='<option value="yes"'+((B.editable==="yes")?' selected="selected"':"")+'">Yes ( editable )</option>';t+='<option value="no"'+((B.editable==="no")?' selected="selected"':"")+'">No ( uneditable after registration )</option>';t+='<option value="no-invisible"'+((B.editable==="no-invisible")?' selected="selected"':"")+'">No ( uneditable &amp; totally invisible )</option>';t+="</select><br />";t+="<small>If <code>No</code>, this field will be un-editable after registration.</small><br />";t+="<small>* Administrators are exempt from this.</small>";t+="</td>";t+="</tr>";t+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-spacer"><td colspan="2">&nbsp;</td></tr>';t+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-classes">';t+='<td colspan="2">';t+='<label for="ws-plugin--s2member-custom-reg-field-configuration-tools-form-classes">CSS Classes: ( optional )</label>';t+="</td>";t+="</tr>";t+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-classes">';t+='<td colspan="2">';t+='<input type="text" property="classes" value="'+a(B.classes)+'" id="ws-plugin--s2member-custom-reg-field-configuration-tools-form-classes" /><br />';t+="<small>Example: <code>my-style-1 my-style-2</code></small>";t+="</td>";t+="</tr>";t+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-spacer"><td colspan="2">&nbsp;</td></tr>';t+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-styles">';t+='<td colspan="2">';t+='<label for="ws-plugin--s2member-custom-reg-field-configuration-tools-form-styles">CSS Styles: ( optional )</label>';t+="</td>";t+="</tr>";t+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-styles">';t+='<td colspan="2">';t+='<input type="text" property="styles" value="'+a(B.styles)+'" id="ws-plugin--s2member-custom-reg-field-configuration-tools-form-styles" /><br />';t+="<small>Example: <code>color:#000000; background:#FFFFFF;</code></small>";t+="</td>";t+="</tr>";t+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-spacer"><td colspan="2">&nbsp;</td></tr>';t+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-attrs">';t+='<td colspan="2">';t+='<label for="ws-plugin--s2member-custom-reg-field-configuration-tools-form-attrs">Other Attributes: ( optional )</label>';t+="</td>";t+="</tr>";t+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-attrs">';t+='<td colspan="2">';t+='<input type="text" property="attrs" value="'+a(B.attrs)+'" id="ws-plugin--s2member-custom-reg-field-configuration-tools-form-attrs" /><br />';t+='<small>Example: <code>onkeyup="" onblur=""</code></small>';t+="</td>";t+="</tr>";t+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-spacer"><td colspan="2">&nbsp;</td></tr>';t+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-buttons">';t+='<td align="left">';t+='<input type="button" value="Cancel" onclick="ws_plugin__s2member_customRegFieldCancel();" />';t+="</td>";t+='<td align="right">';t+='<input type="button" value="'+((u)?"Update This Field":"Create Registration Field")+'" onclick="'+((u)?"ws_plugin__s2member_customRegFieldUpdate("+A+");":"ws_plugin__s2member_customRegFieldCreate();")+'" />';t+="</td>";t+="</tr>";t+="</tbody>";t+="</table>";t+="<div>";b("body").append(t);tb_show(((u)?"Editing Registration Field":"New Custom Registration Field"),"#TB_inline?inlineId=ws-plugin--s2member-custom-reg-field-configuration-thickbox-tools-form");b(window).trigger("resize"),b("table#ws-plugin--s2member-custom-reg-field-configuration-tools-form").show()}i.html(z)};var e=function(){b(window).resize(function(){var s,t;s=b(window).width(),t=b(window).height(),s=(s>720)?720:s;b("#TB_ajaxContent").css({width:s-50,height:t-75,margin:0,padding:0})})};var p=function(){var s=l.length,v=0,w,u="",t="o";u+="<tbody>";u+="<tr>";u+="<th>Order</th>";u+="<th>Field Type</th>";u+="<th>Unique ID</th>";u+="<th>Required</th>";u+="<th>Levels</th>";u+="<th>- Tools -</th>";u+="</tr>";if(l.length>0){for(v=0;v<l.length;v++){t=(t==="o")?"e":"o";w=l[v];u+='<tr class="'+a(t)+" ws-plugin--s2member-custom-reg-field-configuration-table-row-"+v+'">';u+='<td nowrap="nowrap"><a class="ws-plugin--s2member-custom-reg-field-configuration-move-up" href="#" onclick="ws_plugin__s2member_customRegFieldMoveUp('+v+'); return false;"></a><a class="ws-plugin--s2member-custom-reg-field-configuration-move-down" href="#" onclick="ws_plugin__s2member_customRegFieldMoveDown('+v+'); return false;"></a></td>';u+='<td nowrap="nowrap">'+esc_html(g(w.type))+"</td>";u+='<td nowrap="nowrap">'+esc_html(w.id)+"</td>";u+='<td nowrap="nowrap">'+esc_html(w.required)+"</td>";u+='<td nowrap="nowrap">'+esc_html(w.levels)+"</td>";u+='<td nowrap="nowrap"><a class="ws-plugin--s2member-custom-reg-field-configuration-edit" href="#" onclick="ws_plugin__s2member_customRegFieldEdit('+v+'); return false;"></a><a class="ws-plugin--s2member-custom-reg-field-configuration-delete" href="#" onclick="ws_plugin__s2member_customRegFieldDelete('+v+'); return false;"></a></td>';u+="</tr>"}}else{u+="<tr>";u+='<td colspan="6">No Custom Fields are configured.</td>';u+="</tr>"}u+="</tbody>";o.html(u)};j(),e(),p()})()}b("input#ws-plugin--s2member-brute-force-restrictions-reset-button").click(function(){var c=b(this);c.val("one moment please ...");b.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(d){alert("s2Member's Brute Force Restriction Logs have all been reset."),c.val("Reset Brute Force Logs")});return false});b("input#ws-plugin--s2member-ip-restrictions-reset-button").click(function(){var c=b(this);c.val("one moment please ...");b.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(d){alert("s2Member's IP Restriction Logs have all been reset."),c.val("Reset IP Restriction Logs")});return false})}else{if(location.href.match(/page\=ws-plugin--s2member-paypal-ops/)){b("select#ws-plugin--s2member-auto-eot-system-enabled").change(function(){var d=b(this),e=d.val();var c=b("p#ws-plugin--s2member-auto-eot-system-enabled-via-cron");if(e==2){c.show()}else{c.hide()}})}else{if(location.href.match(/page\=ws-plugin--s2member-els-ops/)){b("select#ws-plugin--s2member-custom-reg-opt-in").change(function(){var e=b(this),f=e.val();var d=b("tr.ws-plugin--s2member-custom-reg-opt-in-label-row");var c=b("img.ws-plugin--s2member-custom-reg-opt-in-label-prev-img");if(f<=0){d.css("display","none"),c.attr("src",c.attr("src").replace(/\/checked\.png$/,"/unchecked.png"))}else{if(f==1){d.css("display",""),c.attr("src",c.attr("src").replace(/\/unchecked\.png$/,"/checked.png"))}else{if(f==2){d.css("display",""),c.attr("src",c.attr("src").replace(/\/checked\.png$/,"/unchecked.png"))}}}})}else{if(location.href.match(/page\=ws-plugin--s2member-paypal-buttons/)){b("select#ws-plugin--s2member-level1-term, select#ws-plugin--s2member-level2-term, select#ws-plugin--s2member-level3-term, select#ws-plugin--s2member-level4-term, select#ws-plugin--s2member-modification-term").change(function(){var d=this.id.replace(/^ws-plugin--s2member-(.+?)-term$/g,"$1");var c=(b(this).val().split("-")[2].replace(/[^0-1BN]/g,"")==="BN")?1:0;b("p#ws-plugin--s2member-"+d+"-trial-line").css("display",(c?"none":""));b("span#ws-plugin--s2member-"+d+"-trial-then").css("display",(c?"none":""));b("span#ws-plugin--s2member-"+d+"-20p-rule").css("display",(c?"none":""));(c)?b("input#ws-plugin--s2member-"+form+"-trial-period").val(0):null;(c)?b("input#ws-plugin--s2member-"+form+"-trial-amount").val("0.00"):null});b("input#ws-plugin--s2member-level1-ccaps, input#ws-plugin--s2member-level2-ccaps, input#ws-plugin--s2member-level3-ccaps, input#ws-plugin--s2member-level4-ccaps, input#ws-plugin--s2member-modification-ccaps").keyup(function(){var c=this.value.replace(/^\+/,""),d=(this.value.match(/^\+/))?"+":"";if(c.match(/[^a-z_0-9,]/)){this.value=d+b.trim(b.trim(c).replace(/[ \-]/g,"_").replace(/[^A-Z_0-9,]/gi,"").toLowerCase())}});ws_plugin__s2member_paypalButtonGenerate=function(f){var c='[s2Member-PayPal-Button %%attrs%% image="default" output="button" /]',r="",v={};v.level0='<?php echo c_ws_plugin__s2member_utils_strings::esc_sq ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["level0_label"]); ?>';v.level1='<?php echo c_ws_plugin__s2member_utils_strings::esc_sq ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["level1_label"]); ?>';v.level2='<?php echo c_ws_plugin__s2member_utils_strings::esc_sq ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["level2_label"]); ?>';v.level3='<?php echo c_ws_plugin__s2member_utils_strings::esc_sq ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["level3_label"]); ?>';v.level4='<?php echo c_ws_plugin__s2member_utils_strings::esc_sq ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["level4_label"]); ?>';var o=b("input#ws-plugin--s2member-"+f+"-shortcode");var g=b("textarea#ws-plugin--s2member-"+f+"-button");var k=b("select#ws-plugin--s2member-modification-level");var h=(f==="modification")?k.val().split(":",2)[1]:f.replace(/^level/,"");var l=v["level"+h].replace(/"/g,"");var s=b.trim(b("input#ws-plugin--s2member-"+f+"-desc").val().replace(/"/g,""));var p=b("input#ws-plugin--s2member-"+f+"-trial-amount").val().replace(/[^0-9\.]/g,"");var e=b("input#ws-plugin--s2member-"+f+"-trial-period").val().replace(/[^0-9]/g,"");var j=b("select#ws-plugin--s2member-"+f+"-trial-term").val().replace(/[^A-Z]/g,"");var m=b("input#ws-plugin--s2member-"+f+"-amount").val().replace(/[^0-9\.]/g,"");var u=b("select#ws-plugin--s2member-"+f+"-term").val().split("-")[0].replace(/[^0-9]/g,"");var w=b("select#ws-plugin--s2member-"+f+"-term").val().split("-")[1].replace(/[^A-Z]/g,"");var t=b("select#ws-plugin--s2member-"+f+"-term").val().split("-")[2].replace(/[^0-1BN]/g,"");var d=b.trim(b("input#ws-plugin--s2member-"+f+"-page-style").val().replace(/"/g,""));var i=b("select#ws-plugin--s2member-"+f+"-currency").val().replace(/[^A-Z]/g,"");var n=b.trim(b.trim(b("input#ws-plugin--s2member-"+f+"-ccaps").val()).replace(/[ \-]/g,"_").replace(/[^A-Z_0-9,]/gi,"").toLowerCase());n=(b.trim(b("input#ws-plugin--s2member-"+f+"-ccaps").val()).match(/^\+/))?"+"+n.toLowerCase():n.toLowerCase();e=(t==="BN")?"0":e;p=(!p||isNaN(p)||p<0.01||e<=0)?"0":p;var q=(t==="BN"&&w!=="L")?h+":"+n+":"+u+" "+w:h+":"+n;q=q.replace(/\:+$/g,"");if(p!=="0"&&(isNaN(p)||p<0)){alert("Oops, a slight problem:\n\nWhen provided, Trial Amount must be >= 0.00");return false}else{if(p!=="0"&&p>10000){alert("Oops, a slight problem:\n\nMaximum Trial Amount is: 10000.00");return false}else{if(j==="D"&&e>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(j==="W"&&e>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(j==="M"&&e>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(j==="Y"&&e>1){alert("Oops, a slight problem:\n\nMax Trial Period Years is: 1.");return false}else{if(!m||isNaN(m)||m<0.01){alert("Oops, a slight problem:\n\nAmount must be >= 0.01");return false}else{if(m>10000){alert("Oops, a slight problem:\n\nMaximum Amount is: 10000.00");return false}else{if(!s){alert("Oops, a slight problem:\n\nPlease type a Description for this Button.");return false}}}}}}}}}g.html(g.val().replace(/ \<\!--(\<input type\="hidden" name\="(amount|src|sra|a1|p1|t1|a3|p3|t3)" value\="(.*?)" \/\>)--\>/g," $1"));(parseInt(e)<=0)?g.html(g.val().replace(/ (\<input type\="hidden" name\="(a1|p1|t1)" value\="(.*?)" \/\>)/g," <!--$1-->")):null;(t==="BN")?g.html(g.val().replace(/ (\<input type\="hidden" name\="cmd" value\=")(.*?)(" \/\>)/g," $1_xclick$3")):null;(t==="BN")?g.html(g.val().replace(/ (\<input type\="hidden" name\="(src|sra|a1|p1|t1|a3|p3|t3)" value\="(.*?)" \/\>)/g," <!--$1-->")):null;(t!=="BN")?g.html(g.val().replace(/ (\<input type\="hidden" name\="cmd" value\=")(.*?)(" \/\>)/g," $1_xclick-subscriptions$3")):null;(t!=="BN")?g.html(g.val().replace(/ (\<input type\="hidden" name\="amount" value\="(.*?)" \/\>)/g," <!--$1-->")):null;r+='level="'+a(h)+'" ccaps="'+a(n)+'" desc="'+a(s)+'" ps="'+a(d)+'" cc="'+a(i)+'" ns="1" custom="<?php echo c_ws_plugin__s2member_utils_strings::esc_sq (esc_attr ($_SERVER["HTTP_HOST"])); ?>"';r+=' ta="'+a(p)+'" tp="'+a(e)+'" tt="'+a(j)+'" ra="'+a(m)+'" rp="'+a(u)+'" rt="'+a(w)+'" rr="'+a(t)+'"';r+=(f==="modification")?' modify="1"':"";o.val(c.replace(/%%attrs%%/,r));g.html(g.val().replace(/ name\="item_name" value\="(.*?)"/,' name="item_name" value="'+a(s)+'"'));g.html(g.val().replace(/ name\="item_number" value\="(.*?)"/,' name="item_number" value="'+a(q)+'"'));g.html(g.val().replace(/ name\="page_style" value\="(.*?)"/,' name="page_style" value="'+a(d)+'"'));g.html(g.val().replace(/ name\="currency_code" value\="(.*?)"/,' name="currency_code" value="'+a(i)+'"'));g.html(g.val().replace(/ name\="custom" value\="(.*?)"/,' name="custom" value="<?php echo c_ws_plugin__s2member_utils_strings::esc_sq (esc_attr ($_SERVER["HTTP_HOST"])); ?>"'));g.html(g.val().replace(/ name\="modify" value\="(.*?)"/,' name="modify" value="'+((f==="modification")?"1":"0")+'"'));g.html(g.val().replace(/ name\="amount" value\="(.*?)"/,' name="amount" value="'+a(m)+'"'));g.html(g.val().replace(/ name\="src" value\="(.*?)"/,' name="src" value="'+a(t)+'"'));g.html(g.val().replace(/ name\="a1" value\="(.*?)"/,' name="a1" value="'+a(p)+'"'));g.html(g.val().replace(/ name\="p1" value\="(.*?)"/,' name="p1" value="'+a(e)+'"'));g.html(g.val().replace(/ name\="t1" value\="(.*?)"/,' name="t1" value="'+a(j)+'"'));g.html(g.val().replace(/ name\="a3" value\="(.*?)"/,' name="a3" value="'+a(m)+'"'));g.html(g.val().replace(/ name\="p3" value\="(.*?)"/,' name="p3" value="'+a(u)+'"'));g.html(g.val().replace(/ name\="t3" value\="(.*?)"/,' name="t3" value="'+a(w)+'"'));b("div#ws-plugin--s2member-"+f+"-button-prev").html(g.val().replace(/\<form/,'<form target="_blank"').replace(/\<\?php echo S2MEMBER_CURRENT_USER_VALUE_FOR_PP_(ON0|OS0); \?\>/g,""));(f==="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.");o.each(function(){this.focus(),this.select()});return false};ws_plugin__s2member_paypalSpButtonGenerate=function(){var q='[s2Member-PayPal-Button %%attrs%% image="default" output="button" /]',p="";var n=b("input#ws-plugin--s2member-sp-shortcode");var e=b("textarea#ws-plugin--s2member-sp-button");var f=b("select#ws-plugin--s2member-sp-leading-id").val().replace(/[^0-9]/g,"");var h=b("select#ws-plugin--s2member-sp-additional-ids").val()||[];var o=b("select#ws-plugin--s2member-sp-hours").val().replace(/[^0-9]/g,"");var k=b("input#ws-plugin--s2member-sp-amount").val().replace(/[^0-9\.]/g,"");var j=b.trim(b("input#ws-plugin--s2member-sp-desc").val().replace(/"/g,""));var m=b.trim(b("input#ws-plugin--s2member-sp-page-style").val().replace(/"/g,""));var d=b("select#ws-plugin--s2member-sp-currency").val().replace(/[^A-Z]/g,"");if(!f){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 -> General Options -> Specific Post/Page Access Restrictions.");return false}else{if(!k||isNaN(k)||k<0.01){alert("Oops, a slight problem:\n\nAmount must be >= 0.01");return false}else{if(k>10000){alert("Oops, a slight problem:\n\nMaximum Amount is: 10000.00");return false}else{if(!j){alert("Oops, a slight problem:\n\nPlease type a Description for this Button.");return false}}}}for(var g=0,c=f;g<h.length;g++){if(h[g]&&h[g]!==f){c+=","+h[g]}}var l="sp:"+c+":"+o;p+='ids="'+a(c)+'" exp="'+a(o)+'" desc="'+a(j)+'" ps="'+a(m)+'" cc="'+a(d)+'" ns="1"';p+=' custom="<?php echo c_ws_plugin__s2member_utils_strings::esc_sq (esc_attr ($_SERVER["HTTP_HOST"])); ?>" ra="'+a(k)+'" sp="1"';n.val(q.replace(/%%attrs%%/,p));e.html(e.val().replace(/ name\="item_name" value\="(.*?)"/,' name="item_name" value="'+a(j)+'"'));e.html(e.val().replace(/ name\="item_number" value\="(.*?)"/,' name="item_number" value="'+a(l)+'"'));e.html(e.val().replace(/ name\="page_style" value\="(.*?)"/,' name="page_style" value="'+a(m)+'"'));e.html(e.val().replace(/ name\="currency_code" value\="(.*?)"/,' name="currency_code" value="'+a(d)+'"'));e.html(e.val().replace(/ name\="custom" value\="(.*?)"/,' name="custom" value="<?php echo c_ws_plugin__s2member_utils_strings::esc_sq (esc_attr ($_SERVER["HTTP_HOST"])); ?>"'));e.html(e.val().replace(/ name\="amount" value\="(.*?)"/,' name="amount" value="'+a(k)+'"'));b("div#ws-plugin--s2member-sp-button-prev").html(e.val().replace(/\<form/,'<form target="_blank"'));alert("Your Button has been generated.\nPlease copy/paste the Shortcode Format into your Membership Options Page.");n.each(function(){this.focus(),this.select()});return false};ws_plugin__s2member_paypalRegLinkGenerate=function(){var j=b("select#ws-plugin--s2member-reg-link-level").val().replace(/[^0-9]/g,"");var i=b.trim(b("input#ws-plugin--s2member-reg-link-subscr-id").val());var h=b.trim(b("input#ws-plugin--s2member-reg-link-custom").val());var d=b.trim(b.trim(b("input#ws-plugin--s2member-reg-link-ccaps").val()).replace(/[ \-]/g,"_").replace(/[^A-Z_0-9,]/gi,"").toLowerCase());var f=b.trim(b("input#ws-plugin--s2member-reg-link-fixed-term").val().replace(/[^A-Z 0-9]/gi,"").toUpperCase());var c=b("p#ws-plugin--s2member-reg-link"),g=b("img#ws-plugin--s2member-reg-link-loading");var e=(f&&!f.match(/L$/))?j+":"+d+":"+f:j+":"+d;e=e.replace(/\:+$/g,"");if(!i){alert("Oops, a slight problem:\n\nPaid Subscr. ID is a required value.");return false}else{if(!h||h.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(f&&!f.match(/^[1-9]+ (D|W|M|Y|L)$/)){alert("Oops, a slight problem:\n\nThe Fixed Term Length is not formatted properly.");return false}}}c.hide(),g.show(),b.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:i,s2member_reg_access_link_custom:h,s2member_reg_access_link_item_number:e},function(k){c.show().html('<a href="'+a(k)+'" target="_blank" rel="external">'+esc_html(k)+"</a>"),g.hide()});return false};ws_plugin__s2member_paypalSpLinkGenerate=function(){var j=b("select#ws-plugin--s2member-sp-link-leading-id").val().replace(/[^0-9]/g,"");var h=b("select#ws-plugin--s2member-sp-link-additional-ids").val()||[];var c=b("select#ws-plugin--s2member-sp-link-hours").val().replace(/[^0-9]/g,"");var d=b("p#ws-plugin--s2member-sp-link"),g=b("img#ws-plugin--s2member-sp-link-loading");if(!j){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 -> General Options -> Specific Post/Page Access Restrictions.");return false}for(var e=0,f=j;e<h.length;e++){if(h[e]&&h[e]!==j){f+=","+h[e]}}d.hide(),g.show(),b.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:f,s2member_sp_access_link_hours:c},function(i){d.show().html('<a href="'+a(i)+'" target="_blank" rel="external">'+esc_html(i)+"</a>"),g.hide()});return false}}}}}}}});
includes/menu-pages/menu-pages-s.js CHANGED
@@ -39,6 +39,36 @@ jQuery (document).ready (function($)
39
  });
40
  }
41
  /**/
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
42
  else if (location.href.match (/page\=ws-plugin--s2member-options/))
43
  {
44
  ws_plugin__s2member_generateSecurityKey = function() /* Generates a unique Security Key. */
39
  });
40
  }
41
  /**/
42
+ else if (location.href.match (/page\=ws-plugin--s2member-bridges/))
43
+ {
44
+ $ ('select#ws-plugin--s2member-bbpress-ovg').change (function()
45
+ {
46
+ if ($ (this).val () === '0') /* Expand/collapse notation; based on selection. */
47
+ {
48
+ $ ('span#ws-plugin--s2member-bbpress-ovg-off-note').css ('display', 'inline');
49
+ /**/
50
+ var l = 'form#ws-plugin--s2member-bridge-bbpress-form label[for="ws_plugin--s2member-bridge-bbpress-min-level"]';
51
+ /**/
52
+ $ (l).text ($ (l).text ().replace (/to (read\/)?participate/i, 'to read/participate')), $ ('select#ws-plugin--s2member-bbpress-min-level option').each (function()
53
+ {
54
+ $ (this).text ($ (this).text ().replace (/\( to( read and)? participate \)/i, '( to read and participate )'));
55
+ });
56
+ }
57
+ else if ($ (this).val () === '1') /* Expand/collapse notation. */
58
+ {
59
+ $ ('span#ws-plugin--s2member-bbpress-ovg-off-note').css ('display', 'none');
60
+ /**/
61
+ var l = 'form#ws-plugin--s2member-bridge-bbpress-form label[for="ws_plugin--s2member-bridge-bbpress-min-level"]';
62
+ /**/
63
+ $ (l).text ($ (l).text ().replace (/to (read\/)?participate/i, 'to participate')), $ ('select#ws-plugin--s2member-bbpress-min-level option').each (function()
64
+ {
65
+ $ (this).text ($ (this).text ().replace (/\( to( read and)? participate \)/i, '( to participate )'));
66
+ });
67
+ }
68
+ /**/
69
+ }).trigger ('change'); /* Fire on ready too. */
70
+ }
71
+ /**/
72
  else if (location.href.match (/page\=ws-plugin--s2member-options/))
73
  {
74
  ws_plugin__s2member_generateSecurityKey = function() /* Generates a unique Security Key. */
includes/menu-pages/paypal-ops.inc.php CHANGED
@@ -209,7 +209,7 @@ if (apply_filters ("ws_plugin__s2member_during_paypal_ops_page_during_left_secti
209
  /**/
210
  echo '<h3>More Information ( <a href="#" onclick="jQuery(\'div#ws-plugin--s2member-paypal-ipn-details\').toggle(); return false;" class="ws-dotted-link">click here</a> )</h3>' . "\n";
211
  echo '<div id="ws-plugin--s2member-paypal-ipn-details" style="display:none;">' . "\n";
212
- echo '<p><em><strong>*Quick Tip*</strong> In addition to the default IPN Settings inside your PayPal® account, the IPN URL is also set on a per-transaction basis by the special PayPal® Button Code that s2Member provides you with. In other words, if you have multiple sites operating on one PayPal® account, that\'s OK. s2Member dynamically sets the IPN URL for each transaction. The result is that the IPN URL configured from within your PayPal® account, becomes the default, which is then overwritten on a per-transaction basis. In fact, PayPal® recently updated their system to support IPN URL preservation. One PayPal® account can handle multiple sites, all using different IPN URLs.</em></p>' . "\n";
213
  do_action ("ws_plugin__s2member_during_paypal_ops_page_during_left_sections_during_paypal_ipn_after_quick_tip", get_defined_vars ());
214
  echo '<p><em><strong>*IPN Communications*</strong> 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. 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.</em></p>' . "\n";
215
  echo '</div>' . "\n";
@@ -270,7 +270,7 @@ if (apply_filters ("ws_plugin__s2member_during_paypal_ops_page_during_left_secti
270
  /**/
271
  echo '<h3>More Information ( <a href="#" onclick="jQuery(\'div#ws-plugin--s2member-paypal-pdt-details\').toggle(); return false;" class="ws-dotted-link">click here</a> )</h3>' . "\n";
272
  echo '<div id="ws-plugin--s2member-paypal-pdt-details" style="display:none;">' . "\n";
273
- echo '<p><em><strong>*Quick Tip*</strong> In addition to your default PayPal® account configuration, the Auto-Return URL is also set on a per-transaction basis from within the special PayPal® Button Code that s2Member provides you with. In other words, if you have multiple sites operating on one PayPal® account, that\'s OK. s2Member dynamically sets the Auto-Return URL for each transaction. The result is that the Auto-Return URL configured from within your PayPal® account, becomes the default, which is then overwritten on a per-transaction basis.</em></p>' . "\n";
274
  do_action ("ws_plugin__s2member_during_paypal_ops_page_during_left_sections_during_paypal_pdt_after_quick_tip", get_defined_vars ());
275
  echo '</div>' . "\n";
276
  echo '</div>' . "\n";
209
  /**/
210
  echo '<h3>More Information ( <a href="#" onclick="jQuery(\'div#ws-plugin--s2member-paypal-ipn-details\').toggle(); return false;" class="ws-dotted-link">click here</a> )</h3>' . "\n";
211
  echo '<div id="ws-plugin--s2member-paypal-ipn-details" style="display:none;">' . "\n";
212
+ echo '<p><em><strong>*Quick Tip*</strong> In addition to the <a href="https://cms.paypal.com/us/cgi-bin/?cmd=_render-content&content_ID=developer/e_howto_admin_IPNSetup" target="_blank" rel="external">default IPN settings inside your PayPal® account</a>, the IPN URL is also set on a per-transaction basis by the special PayPal® Button Code that s2Member provides you with. In other words, if you have multiple sites operating on one PayPal® account, that\'s OK. s2Member dynamically sets the IPN URL for each transaction. The result is that the IPN URL configured from within your PayPal® account, becomes the default, which is then overwritten on a per-transaction basis. In fact, PayPal® recently updated their system to support IPN URL preservation. One PayPal® account can handle multiple sites, all using different IPN URLs.</em></p>' . "\n";
213
  do_action ("ws_plugin__s2member_during_paypal_ops_page_during_left_sections_during_paypal_ipn_after_quick_tip", get_defined_vars ());
214
  echo '<p><em><strong>*IPN Communications*</strong> 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. 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.</em></p>' . "\n";
215
  echo '</div>' . "\n";
270
  /**/
271
  echo '<h3>More Information ( <a href="#" onclick="jQuery(\'div#ws-plugin--s2member-paypal-pdt-details\').toggle(); return false;" class="ws-dotted-link">click here</a> )</h3>' . "\n";
272
  echo '<div id="ws-plugin--s2member-paypal-pdt-details" style="display:none;">' . "\n";
273
+ echo '<p><em><strong>*Quick Tip*</strong> In addition to the <a href="https://cms.paypal.com/us/cgi-bin/?cmd=_render-content&content_ID=developer/howto_html_paymentdatatransfer" target="_blank" rel="external">default Auto-Return/PDT configuration inside your PayPal® account</a>, the Auto-Return URL is also set on a per-transaction basis from within the special PayPal® Button Code that s2Member provides you with. In other words, if you have multiple sites operating on one PayPal® account, that\'s OK. s2Member dynamically sets the Auto-Return URL for each transaction. The result is that the Auto-Return URL configured from within your PayPal® account, becomes the default, which is then overwritten on a per-transaction basis.</em></p>' . "\n";
274
  do_action ("ws_plugin__s2member_during_paypal_ops_page_during_left_sections_during_paypal_pdt_after_quick_tip", get_defined_vars ());
275
  echo '</div>' . "\n";
276
  echo '</div>' . "\n";
includes/s2member-min.js CHANGED
@@ -1 +1 @@
1
- jQuery(document).ready(function(a){ws_plugin__s2member_uniqueFilesDownloaded=[];if(S2MEMBER_CURRENT_USER_IS_LOGGED_IN&&S2MEMBER_CURRENT_USER_DOWNLOADS_CURRENTLY<S2MEMBER_CURRENT_USER_DOWNLOADS_ALLOWED){a('a[href*="s2member_file_download"]').click(function(){if(!this.href.match(/s2member_file_download_key\=(.+)/i)){var b="** Please Confirm This File Download **\n\n";b+="You've downloaded "+S2MEMBER_CURRENT_USER_DOWNLOADS_CURRENTLY+" protected file"+((S2MEMBER_CURRENT_USER_DOWNLOADS_CURRENTLY<1||S2MEMBER_CURRENT_USER_DOWNLOADS_CURRENTLY>1)?"s":"")+" in the last "+S2MEMBER_CURRENT_USER_DOWNLOADS_ALLOWED_DAYS+" days.\n\n";b+="You're entitled to "+((S2MEMBER_CURRENT_USER_DOWNLOADS_ALLOWED_IS_UNLIMITED)?"UNLIMITED downloads though ( so, no worries ).":S2MEMBER_CURRENT_USER_DOWNLOADS_ALLOWED+" unique downloads every "+S2MEMBER_CURRENT_USER_DOWNLOADS_ALLOWED_DAYS+" day period.");if(this.href.match(/s2member_skip_confirmation/i)||confirm(b)){if(a.inArray(this.href,ws_plugin__s2member_uniqueFilesDownloaded)===-1){ws_plugin__s2member_uniqueFilesDownloaded.push(this.href),S2MEMBER_CURRENT_USER_DOWNLOADS_CURRENTLY++}return true}else{return false}}else{return true}})}if(location.href.match(/\/wp-signup\.php/)){a("div#content > div.mu_register > form#setupform").submit(function(){var d=this,c="",b="",e="";a("input#user_name, input#user_email, input#blogname, input#blog_title",d).each(function(){if((c=a.trim(a(this).prev("label").text().replace(/[\r\n\t]+/g," ")))){if(b=ws_plugin__s2member_validationErrors(c,this,d,true)){e+=b+"\n\n"}}else{if((c=a.trim(a(this).prev("span.prefix_address").prev("label").text().replace(/[\r\n\t]+/g," ")))){if(b=ws_plugin__s2member_validationErrors(c,this,d,true)){e+=b+"\n\n"}}}});a(":input",d).each(function(){if((c=a.trim(a(this).prev("label").text().replace(/[\r\n\t]+/g," ")))){if(b=ws_plugin__s2member_validationErrors(c,this,d)){e+=b+"\n\n"}}});if(e=a.trim(e)){alert("Oops, you missed something:\n\n"+e);return false}return true})}else{if(location.href.match(/\/wp-login\.php/)){a("div#login > form#registerform").submit(function(){var d=this,c="",b="",e="";a("input#user_login, input#user_email",d).each(function(){if((c=a.trim(a(this).parent("label").text().replace(/[\r\n\t]+/g," ")))){if(b=ws_plugin__s2member_validationErrors(c,this,d,true)){e+=b+"\n\n"}}});a(":input",d).each(function(){if((c=a.trim(a(this).parent("label").children("span").slice(0,1).text().replace(/[\r\n\t]+/g," ")))){if(b=ws_plugin__s2member_validationErrors(c,this,d)){e+=b+"\n\n"}}});if(e=a.trim(e)){alert("Oops, you missed something:\n\n"+e);return false}return true})}else{if(location.href.match(/\/\?s2member_profile\=1/)){a("form#ws-plugin--s2member-profile").submit(function(){var e=this,d="",c="",g="";var b=a("input#ws-plugin--s2member-profile-password");var f=a("input#ws-plugin--s2member-profile-password-confirmation");a(":input",e).each(function(){if((d=a.trim(a(this).parent("label").children("strong").slice(0,1).text().replace(/[\r\n\t]+/g," ")))){if(c=ws_plugin__s2member_validationErrors(d,this,e)){g+=c+"\n\n"}}});if(g=a.trim(g)){alert("Oops, you missed something:\n\n"+g);return false}else{if(a.trim(b.val())&&a.trim(b.val())!==a.trim(f.val())){alert("Oops, you missed something:\n\nPasswords do not match up. Please try again.");return false}}return true})}else{if(location.href.match(/\/wp-admin\/(user\/)?profile\.php/)){a("form#your-profile").submit(function(){var d=this,c="",b="",e="";a(':input[id^="ws-plugin--s2member-profile-"]',d).each(function(){if((c=a.trim(a(this).parent("td").prev("th").children("label").slice(0,1).text().replace(/[\r\n\t]+/g," ")))){if(b=ws_plugin__s2member_validationErrors(c,this,d)){e+=b+"\n\n"}}});if(e=a.trim(e)){alert("Oops, you missed something:\n\n"+e);return false}return true})}}}}ws_plugin__s2member_validationErrors=function(l,k,c,g,f){if(typeof l==="string"&&l&&typeof k==="object"&&typeof c==="object"){if(typeof k.tagName==="string"&&k.tagName.match(/^(input|textarea|select)$/i)){var n=k.tagName.toLowerCase(),j=a(k),i=String(j.attr("type")).toLowerCase(),b=String(j.attr("name")),m=j.val();var g=(typeof g==="boolean")?g:(j.attr("aria-required")==="true"),f=(typeof f==="string")?f:j.attr("data-expected");if(n==="input"&&i==="checkbox"&&b.match(/\[\]$/)){if(typeof k.id==="string"&&k.id.match(/-0$/)){if(g&&!a('input[name="'+b.replace(/([\[\]])/g,"$1")+'"]:checked',c).length){return l+"\nPlease check at least one of the boxes."}}}else{if(n==="input"&&i==="checkbox"){if(g&&!k.checked){return l+"\nRequired. This box must be checked."}}else{if(n==="input"&&i==="radio"){if(typeof k.id==="string"&&k.id.match(/-0$/)){if(g&&!a('input[name="'+b.replace(/([\[\]])/g,"$1")+'"]:checked',c).length){return l+"\nPlease select one of the options."}}}else{if(n==="select"&&j.attr("multiple")){if(g&&(!(m instanceof Array)||!m.length)){return l+"\nPlease select at least one of the options."}}else{if(typeof m!=="string"||(g&&!(m=a.trim(m)).length)){return l+"\nThis is a required field, please try again."}else{if((m=a.trim(m)).length&&((n==="input"&&i.match(/^(text|password)$/i))||n==="textarea")&&typeof f==="string"&&f.length){if(f==="numeric-wp-commas"&&(!m.match(/^[0-9\.,]+$/)||isNaN(m.replace(/,/g,"")))){return l+"\nMust be numeric ( with or without decimals, commas allowed )."}else{if(f==="numeric"&&(!m.match(/^[0-9\.]+$/)||isNaN(m))){return l+"\nMust be numeric ( with or without decimals, no commas )."}else{if(f==="integer"&&(!m.match(/^[0-9]+$/)||isNaN(m))){return l+"\nMust be an integer ( a whole number, without any decimals )."}else{if(f==="integer-gt-0"&&(!m.match(/^[0-9]+$/)||isNaN(m)||m<=0)){return l+"\nMust be an integer > 0 ( whole number, no decimals, greater than 0 )."}else{if(f==="float"&&(!m.match(/^[0-9\.]+$/)||!m.match(/[0-9]/)||!m.match(/\./)||isNaN(m))){return l+"\nMust be a float ( floating point number, decimals required )."}else{if(f==="float-gt-0"&&(!m.match(/^[0-9\.]+$/)||!m.match(/[0-9]/)||!m.match(/\./)||isNaN(m)||m<=0)){return l+"\nMust be a float > 0 ( floating point number, decimals required, greater than 0 )."}else{if(f==="date"&&!m.match(/^[0-9]{2}\/[0-9]{2}\/[0-9]{4}$/)){return l+"\nMust be a date ( required date format: dd/mm/yyyy )."}else{if(f==="email"&&!m.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)){return l+"\nMust be a valid email address."}else{if(f==="url"&&!m.match(/^http(s?)\:\/\/(.{5,})$/i)){return l+"\nMust be a full URL ( starting with http or https )."}else{if(f==="domain"&&!m.match(/^([a-z0-9]+)(((-*)([a-z0-9]+))*)(((\.)([a-z0-9]+)(((-*)([a-z0-9]+))*))*)(\.)([a-z]{2,6})$/i)){return l+"\nMust be a domain name ( domain name only, without http )."}else{if(f==="phone"&&(!m.match(/^[0-9 \(\)\-]+$/)||m.replace(/[^0-9]/g,"").length!==10)){return l+"\nMust be a phone # ( 10 digits w/possible hyphens,spaces,brackets )."}else{if(f==="uszip"&&!m.match(/^[0-9]{5}(-[0-9]{4})?$/)){return l+"\nMust be a US zipcode ( 5-9 digits w/possible hyphen )."}else{if(f==="cazip"&&!m.match(/^[0-9A-Z]{3}( ?)[0-9A-Z]{3}$/i)){return l+"\nMust be a Canadian zipcode ( 6 alpha-numerics w/possible space )."}else{if(f==="uczip"&&!m.match(/^[0-9]{5}(-[0-9]{4})?$/)&&!m.match(/^[0-9A-Z]{3}( ?)[0-9A-Z]{3}$/i)){return l+"\nMust be a zipcode ( either a US or Canadian zipcode )."}else{if(f.match(/^alphanumerics-spaces-punctuation-([0-9]+)(-e)?$/)&&!m.match(/^[a-z 0-9,\.\/\?\:;"'\{\}\[\]\|\\\+\=_\-\(\)\*&\^%\$#@\!`~]+$/i)){return l+"\nPlease use alphanumerics, spaces & punctuation only."}else{if(f.match(/^alphanumerics-spaces-([0-9]+)(-e)?$/)&&!m.match(/^[a-z 0-9]+$/i)){return l+"\nPlease use alphanumerics & spaces only."}else{if(f.match(/^alphanumerics-punctuation-([0-9]+)(-e)?$/)&&!m.match(/^[a-z0-9,\.\/\?\:;"'\{\}\[\]\|\\\+\=_\-\(\)\*&\^%\$#@\!`~]+$/i)){return l+"\nPlease use alphanumerics & punctuation only ( no spaces )."}else{if(f.match(/^alphanumerics-([0-9]+)(-e)?$/)&&!m.match(/^[a-z0-9]+$/i)){return l+"\nPlease use alphanumerics only ( no spaces/punctuation )."}else{if(f.match(/^alphabetics-([0-9]+)(-e)?$/)&&!m.match(/^[a-z]+$/i)){return l+"\nPlease use alphabetics only ( no digits/spaces/punctuation )."}else{if(f.match(/^numerics-([0-9]+)(-e)?$/)&&!m.match(/^[0-9]+$/i)){return l+"\nPlease use numeric digits only."}else{if(f.match(/^(any|alphanumerics-spaces-punctuation|alphanumerics-spaces|alphanumerics-punctuation|alphanumerics|alphabetics|numerics)-([0-9]+)(-e)?$/)){var h=f.split("-"),d=Number(h[1]),e=(h.length>2)?Number(h[2]):"";if(e&&m.length!==d){return l+"\nMust be exactly "+d+" "+((h[0]==="numerics")?"digit":"character")+((d>1)?"s":"")+"."}else{if(m.length<d){return l+"\nMust be at least "+d+" "+((h[0]==="numerics")?"digit":"character")+((d>1)?"s":"")+"."}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}return""}});
1
+ jQuery(document).ready(function(a){ws_plugin__s2member_uniqueFilesDownloaded=[];if(S2MEMBER_CURRENT_USER_IS_LOGGED_IN&&S2MEMBER_CURRENT_USER_DOWNLOADS_CURRENTLY<S2MEMBER_CURRENT_USER_DOWNLOADS_ALLOWED){a('a[href*="s2member_file_download"]').click(function(){if(!this.href.match(/s2member_file_download_key\=(.+)/i)){var b="** Please Confirm This File Download **\n\n";b+="You've downloaded "+S2MEMBER_CURRENT_USER_DOWNLOADS_CURRENTLY+" protected file"+((S2MEMBER_CURRENT_USER_DOWNLOADS_CURRENTLY<1||S2MEMBER_CURRENT_USER_DOWNLOADS_CURRENTLY>1)?"s":"")+" in the last "+S2MEMBER_CURRENT_USER_DOWNLOADS_ALLOWED_DAYS+" days.\n\n";b+="You're entitled to "+((S2MEMBER_CURRENT_USER_DOWNLOADS_ALLOWED_IS_UNLIMITED)?"UNLIMITED downloads though ( so, no worries ).":S2MEMBER_CURRENT_USER_DOWNLOADS_ALLOWED+" unique downloads every "+S2MEMBER_CURRENT_USER_DOWNLOADS_ALLOWED_DAYS+" day period.");if(this.href.match(/s2member_skip_confirmation/i)||confirm(b)){if(a.inArray(this.href,ws_plugin__s2member_uniqueFilesDownloaded)===-1){ws_plugin__s2member_uniqueFilesDownloaded.push(this.href),S2MEMBER_CURRENT_USER_DOWNLOADS_CURRENTLY++}return true}else{return false}}else{return true}})}if(location.href.match(/\/wp-signup\.php/)){a("div#content > div.mu_register > form#setupform").submit(function(){var d=this,c="",b="",e="";a("input#user_name, input#user_email, input#blogname, input#blog_title",d).each(function(){if((c=a.trim(a(this).prev("label").text().replace(/[\r\n\t]+/g," ")))){if(b=ws_plugin__s2member_validationErrors(c,this,d,true)){e+=b+"\n\n"}}else{if((c=a.trim(a(this).prev("span.prefix_address").prev("label").text().replace(/[\r\n\t]+/g," ")))){if(b=ws_plugin__s2member_validationErrors(c,this,d,true)){e+=b+"\n\n"}}}});a(":input",d).each(function(){if((c=a.trim(a(this).prev("label").text().replace(/[\r\n\t]+/g," ")))){if(b=ws_plugin__s2member_validationErrors(c,this,d)){e+=b+"\n\n"}}});if(e=a.trim(e)){alert("Oops, you missed something:\n\n"+e);return false}return true})}else{if(location.href.match(/\/wp-login\.php/)){a("div#login > form#registerform").submit(function(){var d=this,c="",b="",e="";a("input#user_login, input#user_email",d).each(function(){if((c=a.trim(a(this).parent("label").text().replace(/[\r\n\t]+/g," ")))){if(b=ws_plugin__s2member_validationErrors(c,this,d,true)){e+=b+"\n\n"}}});a(":input",d).each(function(){if((c=a.trim(a(this).parent("label").children("span").slice(0,1).text().replace(/[\r\n\t]+/g," ")))){if(b=ws_plugin__s2member_validationErrors(c,this,d)){e+=b+"\n\n"}}});if(e=a.trim(e)){alert("Oops, you missed something:\n\n"+e);return false}return true})}else{if(location.href.match(/\/\?s2member_profile\=1/)){a("form#ws-plugin--s2member-profile").submit(function(){var e=this,d="",c="",g="";var b=a("input#ws-plugin--s2member-profile-password");var f=a("input#ws-plugin--s2member-profile-password-confirmation");a(":input",e).each(function(){if((d=a.trim(a(this).parent("label").children("strong").slice(0,1).text().replace(/[\r\n\t]+/g," ")))){if(c=ws_plugin__s2member_validationErrors(d,this,e)){g+=c+"\n\n"}}});if(g=a.trim(g)){alert("Oops, you missed something:\n\n"+g);return false}else{if(a.trim(b.val())&&a.trim(b.val())!==a.trim(f.val())){alert("Oops, you missed something:\n\nPasswords do not match up. Please try again.");return false}}return true})}else{if(location.href.match(/\/wp-admin\/(user\/)?profile\.php/)){a("form#your-profile").submit(function(){var d=this,c="",b="",e="";a(':input[id^="ws-plugin--s2member-profile-"]',d).each(function(){if((c=a.trim(a(this).parent("td").prev("th").children("label").slice(0,1).text().replace(/[\r\n\t]+/g," ")))){if(b=ws_plugin__s2member_validationErrors(c,this,d)){e+=b+"\n\n"}}});if(e=a.trim(e)){alert("Oops, you missed something:\n\n"+e);return false}return true})}}}}ws_plugin__s2member_validationErrors=function(l,k,c,g,f){if(typeof l==="string"&&l&&typeof k==="object"&&typeof c==="object"){if(typeof k.tagName==="string"&&k.tagName.match(/^(input|textarea|select)$/i)&&!k.disabled){var n=k.tagName.toLowerCase(),j=a(k),i=String(j.attr("type")).toLowerCase(),b=String(j.attr("name")),m=j.val();var g=(typeof g==="boolean")?g:(j.attr("aria-required")==="true"),f=(typeof f==="string")?f:j.attr("data-expected");if(n==="input"&&i==="checkbox"&&b.match(/\[\]$/)){if(typeof k.id==="string"&&k.id.match(/-0$/)){if(g&&!a('input[name="'+b.replace(/([\[\]])/g,"$1")+'"]:checked',c).length){return l+"\nPlease check at least one of the boxes."}}}else{if(n==="input"&&i==="checkbox"){if(g&&!k.checked){return l+"\nRequired. This box must be checked."}}else{if(n==="input"&&i==="radio"){if(typeof k.id==="string"&&k.id.match(/-0$/)){if(g&&!a('input[name="'+b.replace(/([\[\]])/g,"$1")+'"]:checked',c).length){return l+"\nPlease select one of the options."}}}else{if(n==="select"&&j.attr("multiple")){if(g&&(!(m instanceof Array)||!m.length)){return l+"\nPlease select at least one of the options."}}else{if(typeof m!=="string"||(g&&!(m=a.trim(m)).length)){return l+"\nThis is a required field, please try again."}else{if((m=a.trim(m)).length&&((n==="input"&&i.match(/^(text|password)$/i))||n==="textarea")&&typeof f==="string"&&f.length){if(f==="numeric-wp-commas"&&(!m.match(/^[0-9\.,]+$/)||isNaN(m.replace(/,/g,"")))){return l+"\nMust be numeric ( with or without decimals, commas allowed )."}else{if(f==="numeric"&&(!m.match(/^[0-9\.]+$/)||isNaN(m))){return l+"\nMust be numeric ( with or without decimals, no commas )."}else{if(f==="integer"&&(!m.match(/^[0-9]+$/)||isNaN(m))){return l+"\nMust be an integer ( a whole number, without any decimals )."}else{if(f==="integer-gt-0"&&(!m.match(/^[0-9]+$/)||isNaN(m)||m<=0)){return l+"\nMust be an integer > 0 ( whole number, no decimals, greater than 0 )."}else{if(f==="float"&&(!m.match(/^[0-9\.]+$/)||!m.match(/[0-9]/)||!m.match(/\./)||isNaN(m))){return l+"\nMust be a float ( floating point number, decimals required )."}else{if(f==="float-gt-0"&&(!m.match(/^[0-9\.]+$/)||!m.match(/[0-9]/)||!m.match(/\./)||isNaN(m)||m<=0)){return l+"\nMust be a float > 0 ( floating point number, decimals required, greater than 0 )."}else{if(f==="date"&&!m.match(/^[0-9]{2}\/[0-9]{2}\/[0-9]{4}$/)){return l+"\nMust be a date ( required date format: dd/mm/yyyy )."}else{if(f==="email"&&!m.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)){return l+"\nMust be a valid email address."}else{if(f==="url"&&!m.match(/^http(s?)\:\/\/(.{5,})$/i)){return l+"\nMust be a full URL ( starting with http or https )."}else{if(f==="domain"&&!m.match(/^([a-z0-9]+)(((-*)([a-z0-9]+))*)(((\.)([a-z0-9]+)(((-*)([a-z0-9]+))*))*)(\.)([a-z]{2,6})$/i)){return l+"\nMust be a domain name ( domain name only, without http )."}else{if(f==="phone"&&(!m.match(/^[0-9 \(\)\-]+$/)||m.replace(/[^0-9]/g,"").length!==10)){return l+"\nMust be a phone # ( 10 digits w/possible hyphens,spaces,brackets )."}else{if(f==="uszip"&&!m.match(/^[0-9]{5}(-[0-9]{4})?$/)){return l+"\nMust be a US zipcode ( 5-9 digits w/possible hyphen )."}else{if(f==="cazip"&&!m.match(/^[0-9A-Z]{3}( ?)[0-9A-Z]{3}$/i)){return l+"\nMust be a Canadian zipcode ( 6 alpha-numerics w/possible space )."}else{if(f==="uczip"&&!m.match(/^[0-9]{5}(-[0-9]{4})?$/)&&!m.match(/^[0-9A-Z]{3}( ?)[0-9A-Z]{3}$/i)){return l+"\nMust be a zipcode ( either a US or Canadian zipcode )."}else{if(f.match(/^alphanumerics-spaces-punctuation-([0-9]+)(-e)?$/)&&!m.match(/^[a-z 0-9,\.\/\?\:;"'\{\}\[\]\|\\\+\=_\-\(\)\*&\^%\$#@\!`~]+$/i)){return l+"\nPlease use alphanumerics, spaces & punctuation only."}else{if(f.match(/^alphanumerics-spaces-([0-9]+)(-e)?$/)&&!m.match(/^[a-z 0-9]+$/i)){return l+"\nPlease use alphanumerics & spaces only."}else{if(f.match(/^alphanumerics-punctuation-([0-9]+)(-e)?$/)&&!m.match(/^[a-z0-9,\.\/\?\:;"'\{\}\[\]\|\\\+\=_\-\(\)\*&\^%\$#@\!`~]+$/i)){return l+"\nPlease use alphanumerics & punctuation only ( no spaces )."}else{if(f.match(/^alphanumerics-([0-9]+)(-e)?$/)&&!m.match(/^[a-z0-9]+$/i)){return l+"\nPlease use alphanumerics only ( no spaces/punctuation )."}else{if(f.match(/^alphabetics-([0-9]+)(-e)?$/)&&!m.match(/^[a-z]+$/i)){return l+"\nPlease use alphabetics only ( no digits/spaces/punctuation )."}else{if(f.match(/^numerics-([0-9]+)(-e)?$/)&&!m.match(/^[0-9]+$/i)){return l+"\nPlease use numeric digits only."}else{if(f.match(/^(any|alphanumerics-spaces-punctuation|alphanumerics-spaces|alphanumerics-punctuation|alphanumerics|alphabetics|numerics)-([0-9]+)(-e)?$/)){var h=f.split("-"),d=Number(h[1]),e=(h.length>2)?Number(h[2]):"";if(e&&m.length!==d){return l+"\nMust be exactly "+d+" "+((h[0]==="numerics")?"digit":"character")+((d>1)?"s":"")+"."}else{if(m.length<d){return l+"\nMust be at least "+d+" "+((h[0]==="numerics")?"digit":"character")+((d>1)?"s":"")+"."}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}return""}});
includes/s2member.js CHANGED
@@ -10,20 +10,20 @@ If not, see: <http://www.gnu.org/licenses/>.
10
  /*
11
  Scripting routines handled on document ready state.
12
  */
13
- jQuery (document).ready (function($)
14
  {
15
  ws_plugin__s2member_uniqueFilesDownloaded = []; /* Real-time counts. */
16
  /* This is used in case a user downloads multiple files from a single page. */
17
  /**/
18
  if (S2MEMBER_CURRENT_USER_IS_LOGGED_IN && S2MEMBER_CURRENT_USER_DOWNLOADS_CURRENTLY < S2MEMBER_CURRENT_USER_DOWNLOADS_ALLOWED)
19
  {
20
- $ ('a[href*="s2member_file_download"]').click (function()
21
  {
22
  if (!this.href.match (/s2member_file_download_key\=(.+)/i))
23
  {
24
  var c = '** Please Confirm This File Download **\n\n';
25
- c += 'You\'ve downloaded ' + S2MEMBER_CURRENT_USER_DOWNLOADS_CURRENTLY + ' protected file' + ( (S2MEMBER_CURRENT_USER_DOWNLOADS_CURRENTLY < 1 || S2MEMBER_CURRENT_USER_DOWNLOADS_CURRENTLY > 1) ? 's' : '') + ' in the last ' + S2MEMBER_CURRENT_USER_DOWNLOADS_ALLOWED_DAYS + ' days.\n\n';
26
- c += 'You\'re entitled to ' + ( (S2MEMBER_CURRENT_USER_DOWNLOADS_ALLOWED_IS_UNLIMITED) ? 'UNLIMITED downloads though ( so, no worries ).' : S2MEMBER_CURRENT_USER_DOWNLOADS_ALLOWED + ' unique downloads every ' + S2MEMBER_CURRENT_USER_DOWNLOADS_ALLOWED_DAYS + ' day period.');
27
  /**/
28
  if (this.href.match (/s2member_skip_confirmation/i) || confirm (c))
29
  {
@@ -43,7 +43,7 @@ jQuery (document).ready (function($)
43
  */
44
  if (location.href.match (/\/wp-signup\.php/))
45
  /**/
46
- $ ('div#content > div.mu_register > form#setupform').submit (function()
47
  {
48
  var context = this, label = '', error = '', errors = '';
49
  /**/
@@ -71,7 +71,7 @@ jQuery (document).ready (function($)
71
  /**/
72
  if (errors = $.trim (errors))
73
  {
74
- alert ('Oops, you missed something:\n\n' + errors);
75
  return false;
76
  }
77
  /**/
@@ -82,7 +82,7 @@ jQuery (document).ready (function($)
82
  */
83
  else if (location.href.match (/\/wp-login\.php/))
84
  /**/
85
- $ ('div#login > form#registerform').submit (function()
86
  {
87
  var context = this, label = '', error = '', errors = '';
88
  /**/
@@ -102,7 +102,7 @@ jQuery (document).ready (function($)
102
  /**/
103
  if (errors = $.trim (errors))
104
  {
105
- alert ('Oops, you missed something:\n\n' + errors);
106
  return false;
107
  }
108
  /**/
@@ -113,7 +113,7 @@ jQuery (document).ready (function($)
113
  */
114
  else if (location.href.match (/\/\?s2member_profile\=1/))
115
  /**/
116
- $ ('form#ws-plugin--s2member-profile').submit (function()
117
  {
118
  var context = this, label = '', error = '', errors = '';
119
  /**/
@@ -129,13 +129,13 @@ jQuery (document).ready (function($)
129
  /**/
130
  if (errors = $.trim (errors))
131
  {
132
- alert ('Oops, you missed something:\n\n' + errors);
133
  return false;
134
  }
135
  /**/
136
  else if ($.trim ($password.val ()) && $.trim ($password.val ()) !== $.trim ($passwordConfirmation.val ()))
137
  {
138
- alert ('Oops, you missed something:\n\nPasswords do not match up. Please try again.');
139
  return false;
140
  }
141
  /**/
@@ -146,7 +146,7 @@ jQuery (document).ready (function($)
146
  */
147
  else if (location.href.match (/\/wp-admin\/(user\/)?profile\.php/))
148
  /**/
149
- $ ('form#your-profile').submit (function() /* Validation. */
150
  {
151
  var context = this, label = '', error = '', errors = '';
152
  /**/
@@ -159,7 +159,7 @@ jQuery (document).ready (function($)
159
  /**/
160
  if (errors = $.trim (errors))
161
  {
162
- alert ('Oops, you missed something:\n\n' + errors);
163
  return false;
164
  }
165
  /**/
@@ -171,7 +171,7 @@ jQuery (document).ready (function($)
171
  ws_plugin__s2member_validationErrors = function(label, field, context, required, expected)
172
  {
173
  if (typeof label === 'string' && label && typeof field === 'object' && typeof context === 'object')
174
- if (typeof field.tagName === 'string' && field.tagName.match (/^(input|textarea|select)$/i))
175
  {
176
  var tag = field.tagName.toLowerCase (), $field = $ (field), type = String ($field.attr ('type')).toLowerCase (), name = String ($field.attr ('name')), value = $field.val ();
177
  var required = ( typeof required === 'boolean') ? required : ($field.attr ('aria-required') === 'true'), expected = ( typeof expected === 'string') ? expected : $field.attr ('data-expected');
@@ -195,15 +195,15 @@ jQuery (document).ready (function($)
195
  }
196
  else if (tag === 'select' && $field.attr ('multiple'))
197
  {
198
- if (required && (! (value instanceof Array) || !value.length))
199
  return label + '\nPlease select at least one of the options.';
200
  }
201
- else if (typeof value !== 'string' || (required && ! (value = $.trim (value)).length))
202
  /* If we get here, the value MUST be in string format, and we need to trim the string before validation. */
203
  {
204
  return label + '\nThis is a required field, please try again.'; /* Missing data. */
205
  }
206
- else if ((value = $.trim (value)).length && ( (tag === 'input' && type.match (/^(text|password)$/i)) || tag === 'textarea') && typeof expected === 'string' && expected.length)
207
  {
208
  if (expected === 'numeric-wp-commas' && (!value.match (/^[0-9\.,]+$/) || isNaN (value.replace (/,/g, ''))))
209
  {
@@ -290,10 +290,10 @@ jQuery (document).ready (function($)
290
  var split = expected.split ('-'), length = Number (split[1]), exactLength = (split.length > 2) ? Number (split[2]) : '';
291
  /**/
292
  if (exactLength && value.length !== length) /* An exact length is required? */
293
- return label + '\nMust be exactly ' + length + ' ' + ( (split[0] === 'numerics') ? 'digit' : 'character') + ( (length > 1) ? 's' : '') + '.';
294
  /**/
295
  else if (value.length < length) /* Otherwise, we interpret as the minimum length. */
296
- return label + '\nMust be at least ' + length + ' ' + ( (split[0] === 'numerics') ? 'digit' : 'character') + ( (length > 1) ? 's' : '') + '.';
297
  }
298
  }
299
  }
10
  /*
11
  Scripting routines handled on document ready state.
12
  */
13
+ jQuery(document).ready (function($)
14
  {
15
  ws_plugin__s2member_uniqueFilesDownloaded = []; /* Real-time counts. */
16
  /* This is used in case a user downloads multiple files from a single page. */
17
  /**/
18
  if (S2MEMBER_CURRENT_USER_IS_LOGGED_IN && S2MEMBER_CURRENT_USER_DOWNLOADS_CURRENTLY < S2MEMBER_CURRENT_USER_DOWNLOADS_ALLOWED)
19
  {
20
+ $('a[href*="s2member_file_download"]').click (function()
21
  {
22
  if (!this.href.match (/s2member_file_download_key\=(.+)/i))
23
  {
24
  var c = '** Please Confirm This File Download **\n\n';
25
+ c += 'You\'ve downloaded ' + S2MEMBER_CURRENT_USER_DOWNLOADS_CURRENTLY + ' protected file' + ((S2MEMBER_CURRENT_USER_DOWNLOADS_CURRENTLY < 1 || S2MEMBER_CURRENT_USER_DOWNLOADS_CURRENTLY > 1) ? 's' : '') + ' in the last ' + S2MEMBER_CURRENT_USER_DOWNLOADS_ALLOWED_DAYS + ' days.\n\n';
26
+ c += 'You\'re entitled to ' + ((S2MEMBER_CURRENT_USER_DOWNLOADS_ALLOWED_IS_UNLIMITED) ? 'UNLIMITED downloads though ( so, no worries ).' : S2MEMBER_CURRENT_USER_DOWNLOADS_ALLOWED + ' unique downloads every ' + S2MEMBER_CURRENT_USER_DOWNLOADS_ALLOWED_DAYS + ' day period.');
27
  /**/
28
  if (this.href.match (/s2member_skip_confirmation/i) || confirm (c))
29
  {
43
  */
44
  if (location.href.match (/\/wp-signup\.php/))
45
  /**/
46
+ $('div#content > div.mu_register > form#setupform').submit (function()
47
  {
48
  var context = this, label = '', error = '', errors = '';
49
  /**/
71
  /**/
72
  if (errors = $.trim (errors))
73
  {
74
+ alert('Oops, you missed something:\n\n' + errors);
75
  return false;
76
  }
77
  /**/
82
  */
83
  else if (location.href.match (/\/wp-login\.php/))
84
  /**/
85
+ $('div#login > form#registerform').submit (function()
86
  {
87
  var context = this, label = '', error = '', errors = '';
88
  /**/
102
  /**/
103
  if (errors = $.trim (errors))
104
  {
105
+ alert('Oops, you missed something:\n\n' + errors);
106
  return false;
107
  }
108
  /**/
113
  */
114
  else if (location.href.match (/\/\?s2member_profile\=1/))
115
  /**/
116
+ $('form#ws-plugin--s2member-profile').submit (function()
117
  {
118
  var context = this, label = '', error = '', errors = '';
119
  /**/
129
  /**/
130
  if (errors = $.trim (errors))
131
  {
132
+ alert('Oops, you missed something:\n\n' + errors);
133
  return false;
134
  }
135
  /**/
136
  else if ($.trim ($password.val ()) && $.trim ($password.val ()) !== $.trim ($passwordConfirmation.val ()))
137
  {
138
+ alert('Oops, you missed something:\n\nPasswords do not match up. Please try again.');
139
  return false;
140
  }
141
  /**/
146
  */
147
  else if (location.href.match (/\/wp-admin\/(user\/)?profile\.php/))
148
  /**/
149
+ $('form#your-profile').submit (function() /* Validation. */
150
  {
151
  var context = this, label = '', error = '', errors = '';
152
  /**/
159
  /**/
160
  if (errors = $.trim (errors))
161
  {
162
+ alert('Oops, you missed something:\n\n' + errors);
163
  return false;
164
  }
165
  /**/
171
  ws_plugin__s2member_validationErrors = function(label, field, context, required, expected)
172
  {
173
  if (typeof label === 'string' && label && typeof field === 'object' && typeof context === 'object')
174
+ if (typeof field.tagName === 'string' && field.tagName.match (/^(input|textarea|select)$/i) && !field.disabled)
175
  {
176
  var tag = field.tagName.toLowerCase (), $field = $ (field), type = String ($field.attr ('type')).toLowerCase (), name = String ($field.attr ('name')), value = $field.val ();
177
  var required = ( typeof required === 'boolean') ? required : ($field.attr ('aria-required') === 'true'), expected = ( typeof expected === 'string') ? expected : $field.attr ('data-expected');
195
  }
196
  else if (tag === 'select' && $field.attr ('multiple'))
197
  {
198
+ if (required && (!(value instanceof Array) || !value.length))
199
  return label + '\nPlease select at least one of the options.';
200
  }
201
+ else if (typeof value !== 'string' || (required && !(value = $.trim (value)).length))
202
  /* If we get here, the value MUST be in string format, and we need to trim the string before validation. */
203
  {
204
  return label + '\nThis is a required field, please try again.'; /* Missing data. */
205
  }
206
+ else if ((value = $.trim (value)).length && ((tag === 'input' && type.match (/^(text|password)$/i)) || tag === 'textarea') && typeof expected === 'string' && expected.length)
207
  {
208
  if (expected === 'numeric-wp-commas' && (!value.match (/^[0-9\.,]+$/) || isNaN (value.replace (/,/g, ''))))
209
  {
290
  var split = expected.split ('-'), length = Number (split[1]), exactLength = (split.length > 2) ? Number (split[2]) : '';
291
  /**/
292
  if (exactLength && value.length !== length) /* An exact length is required? */
293
+ return label + '\nMust be exactly ' + length + ' ' + ((split[0] === 'numerics') ? 'digit' : 'character') + ((length > 1) ? 's' : '') + '.';
294
  /**/
295
  else if (value.length < length) /* Otherwise, we interpret as the minimum length. */
296
+ return label + '\nMust be at least ' + length + ' ' + ((split[0] === 'numerics') ? 'digit' : 'character') + ((length > 1) ? 's' : '') + '.';
297
  }
298
  }
299
  }
includes/syscon.inc.php CHANGED
@@ -20,15 +20,17 @@ if (realpath (__FILE__) === realpath ($_SERVER["SCRIPT_FILENAME"]))
20
  /*
21
  Determine the full url to the directory this plugin resides in.
22
  */
23
- $GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["dir_url"] = content_url () . preg_replace ("/^(.*?)(\/" . preg_quote (basename (WP_CONTENT_DIR), "/") . ")/", "", preg_replace ("/" . preg_quote (DIRECTORY_SEPARATOR, "/") . "/", "/", dirname (dirname (__FILE__))));
 
 
24
  /*
25
  Configure the directory for files protected by this plugin.
26
  */
27
- $GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["files_dir"] = apply_filters ("ws_plugin__s2member_files_dir", dirname (dirname (__FILE__)) . "-files" . ( (preg_match ("/^win/i", PHP_OS)) ? DIRECTORY_SEPARATOR . "app_data" : ""));
28
  /*
29
  Configure the directory for logs protected by this plugin.
30
  */
31
- $GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["logs_dir"] = apply_filters ("ws_plugin__s2member_logs_dir", dirname (dirname (__FILE__)) . "-logs" . ( (preg_match ("/^win/i", PHP_OS)) ? DIRECTORY_SEPARATOR . "app_data" : ""));
32
  /*
33
  Configure the global reCaptcha for ( www.s2-all-domains.com ). These public/private keys work on any installation.
34
  */
@@ -36,7 +38,7 @@ $GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["recaptcha"] = array ("public_key" => "
36
  /*
37
  Configure the right menu options panel for this software.
38
  */
39
- $GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["menu_pages"] = array ("upsell-pro" => true, "installation" => true, "tools" => true, "support" => true, "donations" => true);
40
  /*
41
  Check if the plugin has been configured *should be set after the first config via options panel*.
42
  */
20
  /*
21
  Determine the full url to the directory this plugin resides in.
22
  */
23
+ $GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["dir_url"] = (stripos (__FILE__, WP_CONTENT_DIR) !== 0) ? /* Have to assume plugins dir? */
24
+ plugins_url ("/" . basename (dirname (dirname (__FILE__)))) : /* Otherwise, this gives it a chance to live anywhere in the content dir. */
25
+ content_url (preg_replace ("/^(.*?)\/" . preg_quote (basename (WP_CONTENT_DIR), "/") . "/", "", str_replace (DIRECTORY_SEPARATOR, "/", dirname (dirname (__FILE__)))));
26
  /*
27
  Configure the directory for files protected by this plugin.
28
  */
29
+ $GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["files_dir"] = apply_filters ("ws_plugin__s2member_files_dir", dirname (dirname (__FILE__)) . "-files" . ( (preg_match ("/^win/i", PHP_OS)) ? "/app_data" : ""));
30
  /*
31
  Configure the directory for logs protected by this plugin.
32
  */
33
+ $GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["logs_dir"] = apply_filters ("ws_plugin__s2member_logs_dir", dirname (dirname (__FILE__)) . "-logs" . ( (preg_match ("/^win/i", PHP_OS)) ? "/app_data" : ""));
34
  /*
35
  Configure the global reCaptcha for ( www.s2-all-domains.com ). These public/private keys work on any installation.
36
  */
38
  /*
39
  Configure the right menu options panel for this software.
40
  */
41
+ $GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["menu_pages"] = array ("upsell-pro" => true, "installation" => false, "tools" => true, "support" => true, "donations" => true);
42
  /*
43
  Check if the plugin has been configured *should be set after the first config via options panel*.
44
  */
readme.txt CHANGED
@@ -1,7 +1,7 @@
1
  === s2Member ( Membership w/ PayPal® ) ===
2
 
3
- Version: 3.5.2
4
- Stable tag: 3.5.2
5
  Framework: WS-P-3.5
6
 
7
  SSL Compatible: yes
@@ -51,8 +51,8 @@ s2Member is an extremely powerful (and free) membership management system for Wo
51
  = Auto-installing through WordPress® ( memory errors? ) =
52
  This depends on your hosting provider and/or server configuration. Some web hosting companies impose very low limits on the amount of memory available to WordPress® during the execution of a single script. Since s2Member is a larger plugin, WordPress® may exceed conservative limits set forth by shared hosting companies. Don't feel bad, it's a very common problem. The solution is to install manually, using the instructions above. Memory limits only affect the WordPress® auto-installation routine, not the actual functionality of WordPress® or s2Member.
53
 
54
- = Is s2Member compatible with WordPress® 3.0+ Multisite Networking ? =
55
- 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 ).
56
 
57
  = What about Multisite Networking ( WPMU ), used on a Blog Farm? =
58
  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. 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 )`.
@@ -143,8 +143,8 @@ Yes, s2Member provides many *Advanced Scripting* techniques that are fully docum
143
  = Is s2Member compatible with Quick Cache or WP Super Cache? =
144
  Yes, there were some bugs in the beginning, but they have been fixed now. Both Quick Cache and WP Super Cache will remain compatible with s2Member. We have integrated two internal Constants that prevent these plugins from caching important Members Only areas of your site, no matter what your cache configuration might be. The two Constants are: `DONOTCACHEPAGE` and `QUICK_CACHE_ALLOWED = false`. We recommend Quick Cache over WP Super Cache though; simply because we actually developed Quick Cache, and we've done more extensive testing with the s2Member/Quick-Cache combination.
145
 
146
- = Is s2Member compatible with WordPress® 3.0+ Multisite Networking ? =
147
- 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 ).
148
 
149
  = What about Multisite Networking ( WPMU ), used on a Blog Farm? =
150
  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. 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 )`.
@@ -174,13 +174,31 @@ Yes and no. We've left this feature out of the plugin intentionally, because man
174
 
175
  == Changelog ==
176
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
177
  = 3.5.2 =
178
  * Framework updated; general cleanup.
179
  * **(s2Member/s2Member Pro). Optimizations.** Further internal optimizations applied through configuration checksums that allow s2Member and s2Member Pro to load with even less overhead now.
180
  * **(s2Member/s2Member Pro). Optimizations.** Further internal optimizations applied with Hook priorities that allow s2Member and s2Member Pro to load dynamic CSS/JS files with even less overhead now.
181
  * **(s2Member). Bug fix.** Due to changes in WordPress® 3.1+, s2Member was including it's JavaScript routines twice on the `/wp-login.php` page. This has been resolved in s2Member v3.5.2+.
182
- * **(s2Member). Hook change. Attn WP developers: s2Member's Hook `_ws_plugin__s2member_force_ssl_buffer_tags` is now `_ws_plugin__s2member_force_ssl_buffer_tags_array`.
183
- * **(s2Member). API Constant change. Attn WP developers: s2Member's API Constant `S2MEMBER_CURRENT_USER_SUBSCR_ID` is now accompanied with a new API Constant `S2MEMBER_CURRENT_USER_SUBSCR_OR_WP_ID`. The values returned by these API Constants have changed (slightly). For further details, check your Dashboard under: `s2Member -> API Scripting -> API Constants`.
184
  * **(s2Member Pro). Bug fix.** s2Member's ccBill® DataLink routines were sometimes generating the error `Too Many Connections` due to an invalid data storage routine under a delayed scenario. This has been resolved in s2Member v3.5.2+.
185
 
186
  = 3.5.1 =
1
  === s2Member ( Membership w/ PayPal® ) ===
2
 
3
+ Version: 3.5.3
4
+ Stable tag: 3.5.3
5
  Framework: WS-P-3.5
6
 
7
  SSL Compatible: yes
51
  = Auto-installing through WordPress® ( memory errors? ) =
52
  This depends on your hosting provider and/or server configuration. Some web hosting companies impose very low limits on the amount of memory available to WordPress® during the execution of a single script. Since s2Member is a larger plugin, WordPress® may exceed conservative limits set forth by shared hosting companies. Don't feel bad, it's a very common problem. The solution is to install manually, using the instructions above. Memory limits only affect the WordPress® auto-installation routine, not the actual functionality of WordPress® or s2Member.
53
 
54
+ = Is s2Member compatible with Multisite Networking ? =
55
+ 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 ).
56
 
57
  = What about Multisite Networking ( WPMU ), used on a Blog Farm? =
58
  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. 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 )`.
143
  = Is s2Member compatible with Quick Cache or WP Super Cache? =
144
  Yes, there were some bugs in the beginning, but they have been fixed now. Both Quick Cache and WP Super Cache will remain compatible with s2Member. We have integrated two internal Constants that prevent these plugins from caching important Members Only areas of your site, no matter what your cache configuration might be. The two Constants are: `DONOTCACHEPAGE` and `QUICK_CACHE_ALLOWED = false`. We recommend Quick Cache over WP Super Cache though; simply because we actually developed Quick Cache, and we've done more extensive testing with the s2Member/Quick-Cache combination.
145
 
146
+ = Is s2Member compatible with Multisite Networking ? =
147
+ 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 ).
148
 
149
  = What about Multisite Networking ( WPMU ), used on a Blog Farm? =
150
  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. 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 )`.
174
 
175
  == Changelog ==
176
 
177
+ = 3.5.3 =
178
+ * **(s2Member). Feature improvement.** s2Member's Bridge integration with bbPress®. It is now possible to allow bbPress® forums to be available to the public ( with read-only access ), and to restrict participation access by Level # instead of locking everything down entirely. You now have the choice whenever you install and/or re-install the bbPress® Bridge/plugin for s2Member. In addition, s2Member makes a new API function available for bbPress® `current_wp_user_is()`. This will be useful to developers integrating bbPress® with s2Member in creative ways. For further details, please check your Dashboard under: `s2Member -> API Bridges -> bbPress®`.
179
+ * **(s2Member Pro). Feature improvement.** s2Member Pro Forms for Free Registration access are now more versatile. It is now possible to configure your Pro Form Shortcode so that Free Registrants come into your site with something other than the default Level #0 Access Level. For example, if you need to, you can change the Form Attribute `level="0"`, to `level="1"`, attach Custom Capabilities with the `ccaps=""` Attribute, and even limit this access to a certain timeframe with `tp="30" tt="D"` ( i.e. 30 Days ). So this Form is very flexible now. It can be used to allow free access to just about any aspect of your service. For more information on this topic, please check your Dashboard under: `s2Member -> PayPal® Pro Forms -> Free Registration Forms`. Also works with Pro Forms for Authorize.Net®.
180
+ * **(s2Member). New Filters.** s2Member v3.5.3 adds two new WordPress® Filters that allow developers to further customize the inner workings of s2Member ( among 300+ other existing Filters already established for s2Member ). You will find these two new Filters in the source code of the free version: `wp_register_location` and `ws_plugin__s2member_redirection_url_after_modification`. For Multisite Networks, there is also this Filter available: `wp_signup_location`. If you're a novice site owner, please keep tabs on our [forums](http://www.primothemes.com/forums/viewforum.php?f=4) for examples on how to utilize these new Filters. We're sure this topic will come up.
181
+ * **(s2Member). New Filters.** s2Member v3.5.3 adds two new WordPress® Filters that allow developers to further customize tinyURLs generated for email confirmations. You will find these two new Filters in the source code of the free version: `ws_plugin__s2member_register_link_gen_alternative` and `ws_plugin__s2member_sp_access_link_gen_alternative`. I've posted [an example](http://www.primothemes.com/forums/viewtopic.php?f=4&t=1636&p=7677#p7677) of how to use these in the forums. So these new Filters make it possible to use a shortening service that you prefer over tinyURL ( but you will have to integrate it yourself ). In a later release, we'll try to add some pre-integrated alternatives into the Dashboard for s2Member.
182
+ * **(s2Member). New Replacement Code.** s2Member's EOT/Deletion Notification now provides additional detail about the actual event that triggers this API Notification through a new Replacement Code: `%%eot_del_type%%`. For further details on this new Replacement Code, and a list of possible values, please check your Dashboard under: `s2Member -> API Notifications -> EOT/Deletion Notifications`.
183
+ * **(s2Member). Bug fix.** A common error that site owners see in s2Member's log file is `unable to verify POST vars`. This is due to issues with various hosting companies not being configured with either cURL and/or `allow_url_fopen` -> `on`. However, we recently discovered that WordPress® ( i.e. via the `WP_Http` class ) will attempt to officially verify the SSL certificate issued through remote connections to Payment Gateways integrated with s2Member. This can cause an additional roadblock on some servers, because often they are not capable of officially verifying SSL certificates. They lack the extended configuration necessary to do so. In other words, this default behavior in the `WP_Http` class file can ultimately lead to `unable to verify POST vars` in s2Member. To workaround this compatibility issue, s2Member now specifies `sslverify = false` in communications to Payment Gateways. This should work to further eliminate sightings of this error in your log files. Also important to note; this does NOT pose a security issue, because all communications with Payment Gateways have authentication mechanisms already in place. Either through explicit API Key validation or through server-to-server checksum verifications related to IPN data received by s2Member silently behind-the-scene.
184
+ * **(s2Member). Bug fix.** s2Member's Auto-Return/PDT handler was sometimes triggering the error `unable to verify POST vars` under special circumstances that are applicable with PayPal's Enchanced Recurring Billing service, and sometimes with Subscriptions that are paid for by credit card, instead of through a PayPal account; again related to PayPal's ERP add-on service. This has been resolved in s2Member v3.5.3+. In some special cases, PayPal® does not provide any data through PDT ( Payment Data Transfer ) and so s2Member must recover gracefully by asking the Customer to check their email. This does not affect s2Member's ability to process a Customer's transaction, but it does require s2Member's processing to take place entirely behind-the-scene via the IPN service, instead of immediately after checkout ( in a very few special cases ). This bug fix may or may not affect you, depending on what you're selling, and depending on whether you're using PayPal's ERP service or not.
185
+ * **(s2Member/s2Member Pro).** Bug fix. Supression of PHP errors triggered by web hosts that disable `set_time_limit()` via `@set_time_limit()`. Also applied to `@ignore_user_abort()` within s2Member's IPN handlers that need to finish processing even when Payment Gateways break the connection early. Resolved in s2Member v3.5.3+.
186
+ * **(s2Member). Bug fix.** Custom Registration Fields that are configured for s2Member as being `uneditable`; which are subsequently disabled for Users attempting to edit their Profile ( e.g. with `disabled="disabled"` ), are now excluded from s2Member's JavaScript validation routines; as they should be. Resolved in s2Member v3.5.3+.
187
+ * **(s2Member). Bug fix.** On some web hosts s2Member was generating the error: `Cannot modify header information, headers already sent` during activation on a Multisite Blog Farm. Resolved in s2Member v3.5.3+.
188
+ * **(s2Member Pro). Bug fix.** Invalid link corrected in PayPal® Options panel for download of `/s2m-pro-extras.zip`. Note, this file is NOT to be installed, it just contains some additional code samples and API documentation for payment gateways that is sometimes useful to developers integrating s2Member for their clients.
189
+ * **(s2Member Pro). Bug fix.** Under certain scenarios, s2Member's "Force SSL" functionality was incorrectly parsing content in its output buffer; ( i.e. an issue with regex in `preg_replace_callback()` ). A symptom of this bug was to experience SSL-enabled links in navigation menus for some themes; and possibly in other areas, such as login links after a Pro Form checkout was completed successfully. s2Member's intention is only to satisfy browser requirements for SSL media and other embedded content; and NOT to convert all navigation links over to SSL. This issue has been resolved in the latest release of s2Member Pro v1.5.3+.
190
+ * **(s2Member Pro). Bug fix.** s2Member Pro Forms integrated with PayPal® Pro and Authorize.Net® were not allowing flexible timeframes whenever `rr="BN"`. This was preventing advanced site owners and developers from selling fixed-term access for non-standardized term lengths. For instance, it is now possible to sell a 13 month ( fixed-term ) "Buy Now" Membership by adjusting your Pro Form Shortcode in the following way: `tp="0" tt="D" ta="0" rp="13" rt="M" ra="100.00" rr="BN"` ( BN = Buy Now ). For further details, please check your Dashboard under: `s2Member -> PayPal® Pro Forms -> Shortcode Attributes Explained`.
191
+ * **(s2Member). BuddyPress Multisite Bug fix.** When s2Member was running together with BuddyPress on a Multisite Network, if s2Member's Multisite (Config) was NOT offering Blogs, it was inadvertently disabling Open Registration for BuddyPress all together; regardless of the configuration value for Open Registration. In other words, in previous versions of s2Member, the only way to run BuddyPress effectively on a Multisite Network was to choose the Blog Farm option and set Blog counts to `0`. Starting with s2Member v3.5.3, it is now possible to run s2Member/BuddyPress without choosing to allow Blog creation, and without needing to use the `0` Blog hack. This bug should be resolved in s2Member v3.5.3+.
192
+ * **(s2Member). Bug fix.** Strange behavior ( i.e. 500 internal server errors ) were reported in PHP v5.2.17 / reproducible on GoDaddy servers. This quirkiness was related to the `map_meta_cap` Filter in WordPress®, where s2Member deals with permissions on a Multisite Network for Blog Farm Administrators. However, due to the nature of this quirkiness, it could also have affected standard WordPress® installations running PHP v5.2.17. This bug has been resolved by modifying s2Member's Filter against this troublesome `map_meta_cap` Filter. Instead of mapping meta capabilities, s2Member now Filters against `user_has_cap`. This technique not only avoids the troublesome behavior in PHP v5.2.17, but also optimizes s2Member on a Multisite Network just a bit further.
193
+ * **(s2Member). Bug fix.** Bug related to output buffering. This was preventing large file downloads protected by s2Member on some installations; depending on other plugins running in concert with s2Member. s2Member now implements `while(@ob_end_clean())` to be sure any/ALL output buffers are cleaned before chunked file delivery begins.
194
+
195
  = 3.5.2 =
196
  * Framework updated; general cleanup.
197
  * **(s2Member/s2Member Pro). Optimizations.** Further internal optimizations applied through configuration checksums that allow s2Member and s2Member Pro to load with even less overhead now.
198
  * **(s2Member/s2Member Pro). Optimizations.** Further internal optimizations applied with Hook priorities that allow s2Member and s2Member Pro to load dynamic CSS/JS files with even less overhead now.
199
  * **(s2Member). Bug fix.** Due to changes in WordPress® 3.1+, s2Member was including it's JavaScript routines twice on the `/wp-login.php` page. This has been resolved in s2Member v3.5.2+.
200
+ * **(s2Member). Hook change.** Attn WP developers: s2Member's Hook `_ws_plugin__s2member_force_ssl_buffer_tags` is now `_ws_plugin__s2member_force_ssl_buffer_tags_array`.
201
+ * **(s2Member). API Constant change.** Attn WP developers: s2Member's API Constant `S2MEMBER_CURRENT_USER_SUBSCR_ID` is now accompanied with a new API Constant `S2MEMBER_CURRENT_USER_SUBSCR_OR_WP_ID`. The values returned by these API Constants have changed (slightly). For further details, check your Dashboard under: `s2Member -> API Scripting -> API Constants`.
202
  * **(s2Member Pro). Bug fix.** s2Member's ccBill® DataLink routines were sometimes generating the error `Too Many Connections` due to an invalid data storage routine under a delayed scenario. This has been resolved in s2Member v3.5.2+.
203
 
204
  = 3.5.1 =
s2member.php CHANGED
@@ -9,8 +9,8 @@ along with this software. In the main directory, see: /licensing/
9
  If not, see: <http://www.gnu.org/licenses/>.
10
  */
11
  /*
12
- Version: 3.5.2
13
- Stable tag: 3.5.2
14
  Framework: WS-P-3.5
15
 
16
  SSL Compatible: yes
@@ -54,10 +54,10 @@ if (realpath (__FILE__) === realpath ($_SERVER["SCRIPT_FILENAME"]))
54
  /*
55
  Define versions.
56
  */
57
- define ("WS_PLUGIN__S2MEMBER_VERSION", "3.5.2");
58
  define ("WS_PLUGIN__S2MEMBER_MIN_PHP_VERSION", "5.2");
59
  define ("WS_PLUGIN__S2MEMBER_MIN_WP_VERSION", "3.0");
60
- define ("WS_PLUGIN__S2MEMBER_MIN_PRO_VERSION", "1.5.2");
61
  /*
62
  Compatibility checks.
63
  */
9
  If not, see: <http://www.gnu.org/licenses/>.
10
  */
11
  /*
12
+ Version: 3.5.3
13
+ Stable tag: 3.5.3
14
  Framework: WS-P-3.5
15
 
16
  SSL Compatible: yes
54
  /*
55
  Define versions.
56
  */
57
+ define ("WS_PLUGIN__S2MEMBER_VERSION", "3.5.3");
58
  define ("WS_PLUGIN__S2MEMBER_MIN_PHP_VERSION", "5.2");
59
  define ("WS_PLUGIN__S2MEMBER_MIN_WP_VERSION", "3.0");
60
+ define ("WS_PLUGIN__S2MEMBER_MIN_PRO_VERSION", "1.5.3");
61
  /*
62
  Compatibility checks.
63
  */