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

Version Description

  • Simple Conditionals. Staring with s2Member v3.2.1, "Simple Conditionals" are now available to you from within WordPress, using Shortcodes that are fully compatible with both the Visual Editor, and also the HTML Tab in WordPress. We've been through all of the documentation for s2Member, and updated ALL code samples to provide you with Shortcode equivalents. You can learn more about these new Shortcodes in your WP Dashboard, under: s2Member -> API Scripting -> Simple Conditionals. There are three new Shortcodes all together: s2All, s2Any, and s2Get - which allows you to pull all sorts of information from your WordPress installation, without a single line of PHP code. All compatible with the Visual Editor. We also suggest a re-review of s2Member's API Constants, under: s2Member -> API Scripting -> Constants. This will NOT affect any existing Conditionals that you've written. Simple Conditionals are a NEW feature, and they'll have no affect on Advanced Conditionals; which have always been available for s2Member.
  • Feature. s2Member now comes equipped with an advanced behavioral setting; specifically geared toward two special events ( Refunds/Reversals ). With s2Member v3.2.1+, you will find a new option which gives you more control over the way s2Member handles these two events. In your WP Dashboard, see: s2Member -> PayPal Options -> EOT Behavior.
  • Bug fix. s2Member's bbPress Bridge integration was using a hard-coded reference to wp_capabilities, instead of using an option call to determine the WordPress table prefix that was needed for some installations. This was affecting installations of WordPress that were using a non-standard wp_ prefix. Corrected in s2Member v3.2.1. In addition, another bug was found, causing the error: missing argument in preg_replace. This has also been corrected with s2Member v3.2.1+.
  • Bug fix. Invalid method WP_User->hap_cap(). This should have been WP_User->has_cap(). This was negatively affecting the new Custom Capabilities per-Post/Page introduced in the previous release of s2Member v3.2. This bug has been resolved with s2Member v3.2.1+.
  • Hooks/Filters. Several new Hooks/Filters for Custom Fields. The upcoming release of s2Member v3.3 will include many new features for Custom Fields. In the mean time, these new Hooks/Filters integrated into /includes/functions/register-access.inc.php will make it easier for developers to maniuplate the display of Custom Fields. One such example is the Filter ws_plugin__s2member_during_custom_registration_fields_during_custom_fields_display.
  • Forcing SSL w/ PayPal Pro integration. The Custom Field s2member_force_ssl=yes is now more powerful. s2Member is now capable of forcing SSL ( i.e. https:// ) on certain Posts/Pages, WITHOUT causing a site-wide conversion to https. In other words, s2Member can now buffer content without affecting href tags within that content, and/or in your navigation menus. Improvements to this routine make integrations of PayPal Pro Forms easier than ever. Just add this Custom Field to any Post/Page that you want to force SSL on: s2member_force_ssl=yes. This is compatible with almost ANY WordPress theme. Or, if your host requires a specific port number in the URL, use this instead: s2member_force_ssl=443. This Custom Field can be added in your Post/Page editing stations; inside WordPress. ( * This is also compatible with the Quick Cache plugin for WordPress, so that PayPal Pro Forms can be cached initially for speed optimization. )
  • IP Restrictions ( i.e. s2Member -> General Options -> IP Restrictions ), have been enhanced to provide better security against slower attacks that may span several weeks/months. s2Member's IP Restrictions are now capable of internal concurrency timeouts on a per-IP basis, as opposed to just a per entry-point basis. In addition, s2Member is now smarter about the way it enforces your configured Punishment Period. Some additional documentation on how IP Restrictions work, is now available in your s2Member General Options panel. There's nothing you need to change though; just review the updated details on this topic in your General Options panel for s2Member.
  • Bug fix. The new Meta Box panel that was made available in the previous release of s2Member ( e.g. in your Post/Page editing stations ), was saving an empty array when there were no Custom Capabilities being specified/required. This is/was harmless; however, it WAS causing s2member_ccaps_req to appear in the Custom Fields drop-down menu for each Post/Page; even with no Custom Capabilities were required. This confusing behavior has been resolved with s2Member v3.2.1+.
  • Bug fix. A new feature added in the previous release of s2Member, making it possible to Add A User through WordPress ( including all s2Member fields initially, without a subsequent Edit ), was working with Multisite enabled, but broken WITHOUT Multisite enabled. This has been resolved with s2Member v3.2.1+. This feature is now working with or without Multisite Networking enabled.
Download this release

Release Info

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

Code changes from version 3.2 to 3.2.1

Files changed (91) hide show
  1. includes/codes.inc.php +13 -1
  2. includes/dropins/bridges/_s2member-bbpress-bridge.php +9 -5
  3. includes/functions/api-functions.inc.php +152 -0
  4. includes/functions/force-ssl.inc.php +32 -3
  5. includes/functions/ip-restrictions.inc.php +40 -21
  6. includes/functions/login-customizations.inc.php +5 -4
  7. includes/functions/meta-boxes.inc.php +27 -17
  8. includes/functions/page-level-access.inc.php +1 -1
  9. includes/functions/paypal-button.inc.php +11 -11
  10. includes/functions/paypal-notify.inc.php +20 -6
  11. includes/functions/post-level-access.inc.php +1 -1
  12. includes/functions/register-access.inc.php +38 -17
  13. includes/functions/sc-conditionals.inc.php +168 -0
  14. includes/functions/sc-get-details.inc.php +77 -0
  15. includes/functions/users-list.inc.php +19 -8
  16. includes/functions/utilities.inc.php +0 -44
  17. includes/hooks.inc.php +3 -1
  18. includes/menu-pages/code-samples/current-user-access-label.php +5 -1
  19. includes/menu-pages/code-samples/current-user-access-level-conditional-upgrades.php +23 -1
  20. includes/menu-pages/code-samples/current-user-access-level.php +27 -1
  21. includes/menu-pages/code-samples/current-user-can-ccaps-1.php +22 -2
  22. includes/menu-pages/code-samples/current-user-can-ccaps-2.php +38 -2
  23. includes/menu-pages/code-samples/current-user-can-full-access.php +1 -1
  24. includes/menu-pages/code-samples/current-user-can-specific-content.php +0 -13
  25. includes/menu-pages/code-samples/current-user-custom.php +5 -1
  26. includes/menu-pages/code-samples/current-user-display-name.php +5 -1
  27. includes/menu-pages/code-samples/current-user-downloads-allowed-days.php +5 -1
  28. includes/menu-pages/code-samples/current-user-downloads-allowed-is-unlimited.php +5 -1
  29. includes/menu-pages/code-samples/current-user-downloads-allowed.php +5 -1
  30. includes/menu-pages/code-samples/current-user-downloads-currently.php +5 -1
  31. includes/menu-pages/code-samples/current-user-email.php +5 -1
  32. includes/menu-pages/code-samples/current-user-fields.php +17 -1
  33. includes/menu-pages/code-samples/current-user-first-name.php +5 -1
  34. includes/menu-pages/code-samples/current-user-id.php +5 -1
  35. includes/menu-pages/code-samples/current-user-ip.php +5 -1
  36. includes/menu-pages/code-samples/current-user-is-logged-in-as-member.php +7 -1
  37. includes/menu-pages/code-samples/current-user-is-logged-in.php +7 -1
  38. includes/menu-pages/code-samples/current-user-is-specific-content.php +13 -0
  39. includes/menu-pages/code-samples/current-user-last-name.php +5 -1
  40. includes/menu-pages/code-samples/current-user-login.php +5 -1
  41. includes/menu-pages/code-samples/current-user-profile-modification-page-url-1.php +5 -1
  42. includes/menu-pages/code-samples/current-user-registration-days-dripping.php +7 -1
  43. includes/menu-pages/code-samples/current-user-registration-days.php +7 -1
  44. includes/menu-pages/code-samples/current-user-registration-time.php +5 -1
  45. includes/menu-pages/code-samples/current-user-subscr-id.php +5 -1
  46. includes/menu-pages/code-samples/current-user-value-for-pp-on0-os0.php +6 -1
  47. includes/menu-pages/code-samples/file-download-inline-extensions.php +5 -1
  48. includes/menu-pages/code-samples/file-download-limit-exceeded-page-url.php +5 -1
  49. includes/menu-pages/code-samples/level0-file-downloads-allowed-days.php +5 -1
  50. includes/menu-pages/code-samples/level0-file-downloads-allowed.php +5 -1
  51. includes/menu-pages/code-samples/level0-label.php +5 -1
  52. includes/menu-pages/code-samples/level1-file-downloads-allowed-days.php +5 -1
  53. includes/menu-pages/code-samples/level1-file-downloads-allowed.php +5 -1
  54. includes/menu-pages/code-samples/level1-label.php +5 -1
  55. includes/menu-pages/code-samples/level2-file-downloads-allowed-days.php +5 -1
  56. includes/menu-pages/code-samples/level2-file-downloads-allowed.php +5 -1
  57. includes/menu-pages/code-samples/level2-label.php +5 -1
  58. includes/menu-pages/code-samples/level3-file-downloads-allowed-days.php +5 -1
  59. includes/menu-pages/code-samples/level3-file-downloads-allowed.php +5 -1
  60. includes/menu-pages/code-samples/level3-label.php +5 -1
  61. includes/menu-pages/code-samples/level4-file-downloads-allowed-days.php +5 -1
  62. includes/menu-pages/code-samples/level4-file-downloads-allowed.php +5 -1
  63. includes/menu-pages/code-samples/level4-label.php +5 -1
  64. includes/menu-pages/code-samples/login-page-url.php +5 -1
  65. includes/menu-pages/code-samples/login-welcome-page-url.php +5 -1
  66. includes/menu-pages/code-samples/logout-page-url.php +5 -1
  67. includes/menu-pages/code-samples/membership-options-page-url.php +5 -1
  68. includes/menu-pages/code-samples/paypal-business.php +5 -1
  69. includes/menu-pages/code-samples/paypal-endpoint.php +5 -1
  70. includes/menu-pages/code-samples/paypal-notify-url.php +5 -1
  71. includes/menu-pages/code-samples/paypal-return-url.php +5 -1
  72. includes/menu-pages/code-samples/reg-email-from-email.php +5 -1
  73. includes/menu-pages/code-samples/reg-email-from-name.php +5 -1
  74. includes/menu-pages/code-samples/s2-conditional-supplements-1.php +7 -0
  75. includes/menu-pages/code-samples/s2-conditional-supplements-2.php +7 -0
  76. includes/menu-pages/code-samples/s2-conditional-supplements-3.php +18 -0
  77. includes/menu-pages/code-samples/sc-current-user-can-full-access.php +7 -0
  78. includes/menu-pages/code-samples/sc-current-user-is-specific-content.php +23 -0
  79. includes/menu-pages/code-samples/sc-is-user-logged-in.php +7 -0
  80. includes/menu-pages/code-samples/sc-s2-conditional-supplements-1.php +28 -0
  81. includes/menu-pages/code-samples/sc-s2-conditional-supplements-2.php +34 -0
  82. includes/menu-pages/code-samples/sc-s2-conditional-supplements-3.php +31 -0
  83. includes/menu-pages/code-samples/version.php +5 -1
  84. includes/menu-pages/options.inc.php +33 -21
  85. includes/menu-pages/paypal-ops.inc.php +26 -2
  86. includes/menu-pages/scripting.inc.php +100 -10
  87. includes/menu-pages/start.inc.php +1 -1
  88. includes/profile.inc.php +48 -0
  89. includes/syscon.inc.php +9 -5
  90. readme.txt +15 -4
  91. s2member.php +4 -4
includes/codes.inc.php CHANGED
@@ -17,5 +17,17 @@ if (realpath (__FILE__) === realpath ($_SERVER["SCRIPT_FILENAME"]))
17
  Add WordPress® Editor Shortcodes.
18
  http://codex.wordpress.org/Shortcode_API
19
  */
20
- add_shortcode ("s2Member-PayPal-Button", "ws_plugin__s2member_paypal_button");
 
 
 
 
 
 
 
 
 
 
 
 
21
  ?>
17
  Add WordPress® Editor Shortcodes.
18
  http://codex.wordpress.org/Shortcode_API
19
  */
20
+ add_shortcode ("s2Get", "ws_plugin__s2member_sc_get_details");
21
+ /**/
22
+ add_shortcode ("s2All", "ws_plugin__s2member_sc_conditionals");
23
+ add_shortcode ("_s2All", "ws_plugin__s2member_sc_conditionals");
24
+ add_shortcode ("__s2All", "ws_plugin__s2member_sc_conditionals");
25
+ add_shortcode ("___s2All", "ws_plugin__s2member_sc_conditionals");
26
+ /**/
27
+ add_shortcode ("s2Any", "ws_plugin__s2member_sc_conditionals");
28
+ add_shortcode ("_s2Any", "ws_plugin__s2member_sc_conditionals");
29
+ add_shortcode ("__s2Any", "ws_plugin__s2member_sc_conditionals");
30
+ add_shortcode ("___s2Any", "ws_plugin__s2member_sc_conditionals");
31
+ /**/
32
+ add_shortcode ("s2Member-PayPal-Button", "ws_plugin__s2member_sc_paypal_button");
33
  ?>
includes/dropins/bridges/_s2member-bbpress-bridge.php CHANGED
@@ -1,7 +1,7 @@
1
  <?php
2
  /*
3
- Version: 1.0.1
4
- Stable tag: 1.0.1
5
  Framework: WS-BB-DIP-1.0
6
 
7
  Tested up to: 1.0.2
@@ -42,11 +42,13 @@ add_action ("bb_init", "ws_plugin__s2member_bridge_bbpress_roles");
42
  /**/
43
  function ws_plugin__s2member_bridge_bbpress_roles () /* On-the-fly. */
44
  {
 
 
45
  if (is_object ($user = bb_get_current_user ()) && $user->ID) /* Logged in? */
46
  /**/
47
  if (empty ($user->roles)) /* Only when no bbPress® Role has been assigned yet. */
48
  /**/
49
- foreach ($user->wp_capabilities as $wp_cap => $v) /* Check ^s2member_level[1-4]+ */
50
  /**/
51
  if (preg_match ("/^s2member_level[0-4]$/", $wp_cap)) /* An s2Member Role? */
52
  {
@@ -69,6 +71,8 @@ function ws_plugin__s2member_bridge_bbpress_access () /* Check Access. */
69
  /**/
70
  $location = bb_get_location (); /* The current navigation location. */
71
  /**/
 
 
72
  if (!in_array ($location, array ("login-page", "register-page")))
73
  {
74
  if (!bb_is_user_logged_in () || !bb_current_user_can ("participate"))
@@ -89,11 +93,11 @@ function ws_plugin__s2member_bridge_bbpress_access () /* Check Access. */
89
  /**/
90
  else if (is_object ($user = bb_get_current_user ()) && $user->ID) /* Logged in? / Got User object? */
91
  /**/
92
- foreach ($user->wp_capabilities as $wp_cap => $v) /* Looking for ^(subscriber|s2member_level[0-4])$. */
93
  /**/
94
  if (preg_match ("/^(subscriber|s2member_level[0-4])$/", $wp_cap)) /* Subscribers and/or s2Member Roles. */
95
  /**/
96
- if (($wp_cap === "subscriber" && $min > 0) || !strlen ($level = preg_replace ("/[^0-9]/", $wp_cap)) || $level < $min)
97
  /**/
98
  if ($url = bb_get_option ("wp_siteurl")) /* WordPress® is integrated? */
99
  {
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
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 when no bbPress® Role has been assigned yet. */
50
  /**/
51
+ foreach ($user->$wp_capabilities as $wp_cap => $v) /* Check ^s2member_level[1-4]+ */
52
  /**/
53
  if (preg_match ("/^s2member_level[0-4]$/", $wp_cap)) /* An s2Member Role? */
54
  {
71
  /**/
72
  $location = bb_get_location (); /* The current navigation location. */
73
  /**/
74
+ $wp_capabilities = bb_get_option ("wp_table_prefix") . "capabilities";
75
+ /**/
76
  if (!in_array ($location, array ("login-page", "register-page")))
77
  {
78
  if (!bb_is_user_logged_in () || !bb_current_user_can ("participate"))
93
  /**/
94
  else if (is_object ($user = bb_get_current_user ()) && $user->ID) /* Logged in? / Got User object? */
95
  /**/
96
+ foreach ($user->$wp_capabilities as $wp_cap => $v) /* Looking for ^(subscriber|s2member_level[0-4])$. */
97
  /**/
98
  if (preg_match ("/^(subscriber|s2member_level[0-4])$/", $wp_cap)) /* Subscribers and/or s2Member Roles. */
99
  /**/
100
+ if (($wp_cap === "subscriber" && $min > 0) || ($level = preg_replace ("/[^0-9]/", "", $wp_cap)) < $min)
101
  /**/
102
  if ($url = bb_get_option ("wp_siteurl")) /* WordPress® is integrated? */
103
  {
includes/functions/api-functions.inc.php ADDED
@@ -0,0 +1,152 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
+ API function for Conditionals.
18
+ This matches up with a Simple Conditional made available through a Shortcode.
19
+ Function `is_user_logged_in()` already exists in WordPress® core.
20
+ */
21
+ if (!function_exists ("is_user_not_logged_in"))
22
+ {
23
+ function is_user_not_logged_in ()
24
+ {
25
+ return (!is_user_logged_in ());
26
+ }
27
+ }
28
+ /*
29
+ API function for Conditionals.
30
+ This matches up with a Simple Conditional made available through a Shortcode.
31
+ Function `current_user_can()` already exists in WordPress® core.
32
+ */
33
+ if (!function_exists ("current_user_is"))
34
+ {
35
+ function current_user_is ($role = FALSE)
36
+ {
37
+ $role = ($role === "s2member_level0") ? "subscriber" : $role;
38
+ return current_user_can (preg_replace ("/^access_/i", "", $role));
39
+ }
40
+ }
41
+ /*
42
+ API function for Conditionals.
43
+ This matches up with a Simple Conditional made available through a Shortcode.
44
+ Function `current_user_can()` already exists in WordPress® core.
45
+ */
46
+ if (!function_exists ("current_user_is_not"))
47
+ {
48
+ function current_user_is_not ($role = FALSE)
49
+ {
50
+ $role = ($role === "s2member_level0") ? "subscriber" : $role;
51
+ return (!current_user_can (preg_replace ("/^access_/i", "", $role)));
52
+ }
53
+ }
54
+ /*
55
+ API function for Conditionals.
56
+ This matches up with a Simple Conditional made available through a Shortcode.
57
+ Function `current_user_can_for_blog()` already exists in WordPress® core.
58
+ */
59
+ if (!function_exists ("current_user_is_for_blog"))
60
+ {
61
+ function current_user_is_for_blog ($blog_id = FALSE, $role = FALSE)
62
+ {
63
+ $role = ($role === "s2member_level0") ? "subscriber" : $role;
64
+ return current_user_can_for_blog ($blog_id, preg_replace ("/^access_/i", "", $role));
65
+ }
66
+ }
67
+ /*
68
+ API function for Conditionals.
69
+ This matches up with a Simple Conditional made available through a Shortcode.
70
+ Function `current_user_can_for_blog()` already exists in WordPress® core.
71
+ */
72
+ if (!function_exists ("current_user_is_not_for_blog"))
73
+ {
74
+ function current_user_is_not_for_blog ($blog_id = FALSE, $role = FALSE)
75
+ {
76
+ $role = ($role === "s2member_level0") ? "subscriber" : $role;
77
+ return (!current_user_can_for_blog ($blog_id, preg_replace ("/^access_/i", "", $role)));
78
+ }
79
+ }
80
+ /*
81
+ API function for Conditionals.
82
+ This matches up with a Simple Conditional made available through a Shortcode.
83
+ Function `current_user_can()` already exists in WordPress® core.
84
+ */
85
+ if (!function_exists ("current_user_cannot"))
86
+ {
87
+ function current_user_cannot ($capability = FALSE)
88
+ {
89
+ return (!current_user_can ($capability));
90
+ }
91
+ }
92
+ /*
93
+ API function for Conditionals.
94
+ This matches up with a Simple Conditional made available through a Shortcode.
95
+ Function `current_user_can_for_blog()` already exists in WordPress® core.
96
+ */
97
+ if (!function_exists ("current_user_cannot_for_blog"))
98
+ {
99
+ function current_user_cannot_for_blog ($blog_id = FALSE, $capability = FALSE)
100
+ {
101
+ return (!current_user_can_for_blog ($blog_id, $capability));
102
+ }
103
+ }
104
+ /*
105
+ Alias function for API Scripting usage.
106
+ Deprecated in v3.0.5. This will be removed in a future release.
107
+ Alias to: `ws_plugin__s2member_encrypt()`.
108
+ */
109
+ if (!function_exists ("s2member_encrypt"))
110
+ {
111
+ function s2member_encrypt ($string = FALSE, $key = FALSE)
112
+ {
113
+ return ws_plugin__s2member_encrypt ($string, $key);
114
+ }
115
+ }
116
+ /*
117
+ Alias function for API Scripting usage.
118
+ Deprecated in v3.0.5. This will be removed in a future release.
119
+ Alias to: `ws_plugin__s2member_decrypt()`.
120
+ */
121
+ if (!function_exists ("s2member_decrypt"))
122
+ {
123
+ function s2member_decrypt ($base64 = FALSE, $key = FALSE)
124
+ {
125
+ return ws_plugin__s2member_decrypt ($base64, $key);
126
+ }
127
+ }
128
+ /*
129
+ Alias function for API Scripting usage.
130
+ Deprecated in v3.0.5. This will be removed in a future release.
131
+ Alias to: `ws_plugin__s2member_xencrypt()`.
132
+ */
133
+ if (!function_exists ("s2member_xencrypt"))
134
+ {
135
+ function s2member_xencrypt ($string = FALSE, $key = FALSE)
136
+ {
137
+ return ws_plugin__s2member_xencrypt ($string, $key);
138
+ }
139
+ }
140
+ /*
141
+ Alias function for API Scripting usage.
142
+ Deprecated in v3.0.5. This will be removed in a future release.
143
+ Alias to: `ws_plugin__s2member_xdecrypt()`.
144
+ */
145
+ if (!function_exists ("s2member_xdecrypt"))
146
+ {
147
+ function s2member_xdecrypt ($base64 = FALSE, $key = FALSE)
148
+ {
149
+ return ws_plugin__s2member_xdecrypt ($base64, $key);
150
+ }
151
+ }
152
+ ?>
includes/functions/force-ssl.inc.php CHANGED
@@ -19,6 +19,11 @@ Attach to: add_action("template_redirect");
19
 
20
  Triggered by Custom Field:
21
  s2member_force_ssl = yes
 
 
 
 
 
22
  */
23
  if (!function_exists ("ws_plugin__s2member_check_force_ssl"))
24
  {
@@ -39,8 +44,27 @@ if (!function_exists ("ws_plugin__s2member_check_force_ssl"))
39
  wp_redirect ("https://" . $ssl_host_port . $_SERVER["REQUEST_URI"]);
40
  exit (); /* ^ So let's redirect to the SSL enabled version. */
41
  }
42
- else /* Otherwise, we buffer the output, and switch everything to https. */
43
  {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
44
  function _ws_plugin__s2member_force_ssl_buffer ($buffer = FALSE)
45
  {
46
  $o_pcre = ini_get ("pcre.backtrack_limit");
@@ -61,10 +85,15 @@ if (!function_exists ("ws_plugin__s2member_check_force_ssl"))
61
  /**/
62
  function _ws_plugin__s2member_force_ssl_buffer_callback ($m = FALSE)
63
  {
64
- return preg_replace ("/http\:\/\//i", "https://", $m[0]);
 
 
 
 
 
65
  }
66
  /**/
67
- ob_start ("_ws_plugin__s2member_force_ssl_buffer");
68
  }
69
  }
70
  /**/
19
 
20
  Triggered by Custom Field:
21
  s2member_force_ssl = yes
22
+ ( i.e. https://www.example.com/ )
23
+
24
+ Or with a specific port number:
25
+ s2member_force_ssl = 443 ( or whatever port you require )
26
+ ( i.e. https://www.example.com:443/ )
27
  */
28
  if (!function_exists ("ws_plugin__s2member_check_force_ssl"))
29
  {
44
  wp_redirect ("https://" . $ssl_host_port . $_SERVER["REQUEST_URI"]);
45
  exit (); /* ^ So let's redirect to the SSL enabled version. */
46
  }
47
+ else /* Otherwise, we buffer all output, and switch all content over to https. */
48
  {
49
+ $ssl_host = preg_replace ("/\:[0-9]+$/", "", $_SERVER["HTTP_HOST"]);
50
+ $ssl_port = (is_numeric ($force_ssl) && $force_ssl > 1) ? $force_ssl : 0;
51
+ $ssl_host_port = $ssl_host . (($ssl_port) ? ":" . $ssl_port : "");
52
+ /**/
53
+ define ("_ws_plugin__s2member_force_ssl_host", $ssl_host);
54
+ define ("_ws_plugin__s2member_force_ssl_port", $ssl_port);
55
+ define ("_ws_plugin__s2member_force_ssl_host_port", $ssl_host_port);
56
+ /**/
57
+ /* Except these. We do NOT want to create a sitewide https conversion! */
58
+ add_filter ("home_url", "_ws_plugin__s2member_force_non_ssl_scheme", 10, 3);
59
+ add_filter ("network_home_url", "_ws_plugin__s2member_force_non_ssl_scheme", 10, 3);
60
+ add_filter ("site_url", "_ws_plugin__s2member_force_non_ssl_scheme", 10, 3);
61
+ add_filter ("network_site_url", "_ws_plugin__s2member_force_non_ssl_scheme", 10, 3);
62
+ /**/
63
+ function _ws_plugin__s2member_force_non_ssl_scheme ($url = FALSE, $path = FALSE, $scheme = FALSE)
64
+ {
65
+ return ($scheme) ? $url : preg_replace ("/^https\:\/\//i", "http://", $url);
66
+ }
67
+ /**/
68
  function _ws_plugin__s2member_force_ssl_buffer ($buffer = FALSE)
69
  {
70
  $o_pcre = ini_get ("pcre.backtrack_limit");
85
  /**/
86
  function _ws_plugin__s2member_force_ssl_buffer_callback ($m = FALSE)
87
  {
88
+ $c = preg_replace ("/http\:\/\//i", "https://", $m[0]);
89
+ /**/
90
+ if (_ws_plugin__s2member_force_ssl_port && _ws_plugin__s2member_force_ssl_host && _ws_plugin__s2member_force_ssl_host_port) /* Do we ALSO need port conversions? */
91
+ $c = preg_replace ("/\/" . preg_quote (_ws_plugin__s2member_force_ssl_host, "/") . "(\:[0-9]+)?\//i", "/" . _ws_plugin__s2member_force_ssl_host_port . "/", $c);
92
+ /**/
93
+ return $c; /* Return string with conversions. */
94
  }
95
  /**/
96
+ ob_start ("_ws_plugin__s2member_force_ssl_buffer"); /* Buffer. */
97
  }
98
  }
99
  /**/
includes/functions/ip-restrictions.inc.php CHANGED
@@ -12,7 +12,7 @@ If not, see: <http://www.gnu.org/licenses/>.
12
  Direct access denial.
13
  */
14
  if (realpath (__FILE__) === realpath ($_SERVER["SCRIPT_FILENAME"]))
15
- exit ("Do not access this file directly.");
16
  /*
17
  Function for handling IP Restrictions.
18
  IP addresses are stored in a Transient field.
@@ -21,46 +21,65 @@ if (!function_exists ("ws_plugin__s2member_ip_restrictions_ok"))
21
  {
22
  function ws_plugin__s2member_ip_restrictions_ok ($ip = FALSE, $restriction = FALSE)
23
  {
24
- eval ('foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;');
25
  do_action ("ws_plugin__s2member_before_ip_restrictions_ok", get_defined_vars ());
26
  unset ($__refs, $__v); /* Unset defined __refs, __v. */
27
  /**/
28
- if ($restriction) /* There MUST be a restriction. However, the IP *can* be empty. */
29
  {
30
- if (is_array ($ips = get_transient ($transient = md5 ("s2member_ip_restrictions_" . $restriction))))
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
31
  {
32
- if (!in_array ($ip, $ips)) /* Already on record? */
33
- $ips[] = $ip;
 
 
 
 
 
 
 
34
  /**/
35
- $new_ips = $ips;
36
  }
37
- else /* Otherwise, create a new IPs array. */
38
- $new_ips[] = $ip;
39
- /*
40
- Now check to see if this is a security breach; with too many IP addresses.
41
- */
42
- if (count ($new_ips) > $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["max_ip_restriction"])
43
  {
44
- ws_plugin__s2member_nocache_constants (true) . wp_clear_auth_cookie ();
 
 
 
45
  /**/
46
  do_action ("ws_plugin__s2member_during_ip_restrictions_ok_no", get_defined_vars ());
47
  /**/
48
- header ("HTTP/1.0 503 Service Temporarily Unavailable");
49
  /**/
50
  echo '<strong>503: Service Temporarily Unavailable</strong><br />' . "\n";
51
- echo 'Too many IP addresses accessing one account/link!<br />' . "\n";
52
- echo 'Please contact Support if you need assistance.';
53
  /**/
54
  exit ();
55
  }
56
- else /* Looks legit. Continue updating the Transient array of IP addresses. */
57
  {
58
- eval ('foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;');
59
  do_action ("ws_plugin__s2member_during_ip_restrictions_ok_yes", get_defined_vars ());
60
  unset ($__refs, $__v); /* Unset defined __refs, __v. */
61
  /**/
62
- set_transient ($transient, $new_ips, $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["max_ip_restriction_time"]);
63
- /**/
64
  return apply_filters ("ws_plugin__s2member_ip_restrictions_ok", true, get_defined_vars ());
65
  }
66
  }
12
  Direct access denial.
13
  */
14
  if (realpath (__FILE__) === realpath ($_SERVER["SCRIPT_FILENAME"]))
15
+ exit("Do not access this file directly.");
16
  /*
17
  Function for handling IP Restrictions.
18
  IP addresses are stored in a Transient field.
21
  {
22
  function ws_plugin__s2member_ip_restrictions_ok ($ip = FALSE, $restriction = FALSE)
23
  {
24
+ eval('foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;');
25
  do_action ("ws_plugin__s2member_before_ip_restrictions_ok", get_defined_vars ());
26
  unset ($__refs, $__v); /* Unset defined __refs, __v. */
27
  /**/
28
+ if ($restriction) /* There MUST be a restriction. However, the IP *could* be empty. */
29
  {
30
+ $ip = ($ip) ? $ip : "empty"; /* Allow empty IPs; we need to track them too. */
31
+ /**/
32
+ $entries = (array)get_transient ($transient = md5 ("s2member_ip_restrictions_" . $restriction));
33
+ /**/
34
+ $conc_filter = "ws_plugin__s2member_ip_restrictions__concurrency_time_per_ip";
35
+ $concurrency = apply_filters ($conc_filter, "30 days");
36
+ /**/
37
+ foreach ($entries as $_entry => $_time) /* Auto-expire entries. */
38
+ if ($_time < strtotime ("-" . $concurrency))
39
+ unset($entries[$_entry]);
40
+ /**/
41
+ $entries[$ip] = strtotime ("now"); /* Log this entry. */
42
+ set_transient ($transient, $entries, 2 * (strtotime ("+" . $concurrency) - strtotime ("now")));
43
+ /*
44
+ Now check to see if this is a security breach; or if it has too many IP addresses.
45
+ */
46
+ if (get_transient (md5 ("s2member_ip_restrictions_" . $restriction . "_breached")))
47
  {
48
+ ws_plugin__s2member_nocache_constants(true) . wp_clear_auth_cookie ();
49
+ /**/
50
+ do_action ("ws_plugin__s2member_during_ip_restrictions_ok_no", get_defined_vars ());
51
+ /**/
52
+ header("HTTP/1.0 503 Service Temporarily Unavailable"); /* Sends a status header. */
53
+ /**/
54
+ echo '<strong>503: Service Temporarily Unavailable</strong><br />' . "\n";
55
+ echo 'Too many IP addresses accessing one secure area<em>!</em><br />' . "\n";
56
+ echo 'Please contact Support if you require assistance.';
57
  /**/
58
+ exit ();
59
  }
60
+ else if (count ($entries) > $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["max_ip_restriction"])
 
 
 
 
 
61
  {
62
+ ws_plugin__s2member_nocache_constants(true) . wp_clear_auth_cookie ();
63
+ /**/
64
+ $p = $punish = $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["max_ip_restriction_time"];
65
+ set_transient (md5 ("s2member_ip_restrictions_" . $restriction . "_breached"), "1", $p);
66
  /**/
67
  do_action ("ws_plugin__s2member_during_ip_restrictions_ok_no", get_defined_vars ());
68
  /**/
69
+ header("HTTP/1.0 503 Service Temporarily Unavailable"); /* Sends a status header. */
70
  /**/
71
  echo '<strong>503: Service Temporarily Unavailable</strong><br />' . "\n";
72
+ echo 'Too many IP addresses accessing one secure area<em>!</em><br />' . "\n";
73
+ echo 'Please contact Support if you require assistance.';
74
  /**/
75
  exit ();
76
  }
77
+ else /* OK, this looks legitimate. Continue updating the Transient array of IP addresses. */
78
  {
79
+ eval('foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;');
80
  do_action ("ws_plugin__s2member_during_ip_restrictions_ok_yes", get_defined_vars ());
81
  unset ($__refs, $__v); /* Unset defined __refs, __v. */
82
  /**/
 
 
83
  return apply_filters ("ws_plugin__s2member_ip_restrictions_ok", true, get_defined_vars ());
84
  }
85
  }
includes/functions/login-customizations.inc.php CHANGED
@@ -12,7 +12,7 @@ If not, see: <http://www.gnu.org/licenses/>.
12
  Direct access denial.
13
  */
14
  if (realpath (__FILE__) === realpath ($_SERVER["SCRIPT_FILENAME"]))
15
- exit("Do not access this file directly.");
16
  /*
17
  Function for filtering the login logo url.
18
  Attach to: add_filter("login_headerurl");
@@ -53,7 +53,7 @@ if (!function_exists ("ws_plugin__s2member_login_header_styles"))
53
  {
54
  $s = ""; /* Initialize here to give hooks a chance. */
55
  /**/
56
- eval('foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;');
57
  do_action ("ws_plugin__s2member_before_login_header_styles", get_defined_vars ());
58
  unset ($__refs, $__v); /* Unset defined __refs, __v. */
59
  /**/
@@ -77,14 +77,15 @@ if (!function_exists ("ws_plugin__s2member_login_header_styles"))
77
  $s .= 'div#login form input[type="submit"], div#login form input[type="submit"]:hover, div#login form input[type="submit"]:active, div#login form input[type="submit"]:focus { color: #333333 !important; border: 1px solid #666666 !important; background: #CCCCCC !important; padding: 5px !important; -moz-border-radius: 3px !important; -webkit-border-radius: 3px !important; -khtml-border-radius: 3px !important; border-radius: 3px !important; }' . "\n";
78
  $s .= 'div#login form input[type="submit"]:hover, div#login form input[type="submit"]:active, div#login form input[type="submit"]:focus { color: #000000 !important; border: 1px solid #000000 !important; }' . "\n";
79
  /**/
80
- $s .= 'div#login form input.ws-plugin--s2member-custom-reg-field { background:none repeat scroll 0 0 #FBFBFB; border:1px solid #E5E5E5; font-size:24px; margin-bottom:16px; margin-right:6px; margin-top:2px; padding:3px; width:97%; }' . "\n";
 
81
  /**/
82
  if ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["custom_reg_password"])
83
  $s .= 'p#reg_passmail { display: none; }' . "\n";
84
  /**/
85
  $s .= '</style>' . "\n\n";
86
  /**/
87
- eval('foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;');
88
  do_action ("ws_plugin__s2member_during_login_header_styles", get_defined_vars ());
89
  unset ($__refs, $__v); /* Unset defined __refs, __v. */
90
  /**/
12
  Direct access denial.
13
  */
14
  if (realpath (__FILE__) === realpath ($_SERVER["SCRIPT_FILENAME"]))
15
+ exit ("Do not access this file directly.");
16
  /*
17
  Function for filtering the login logo url.
18
  Attach to: add_filter("login_headerurl");
53
  {
54
  $s = ""; /* Initialize here to give hooks a chance. */
55
  /**/
56
+ eval ('foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;');
57
  do_action ("ws_plugin__s2member_before_login_header_styles", get_defined_vars ());
58
  unset ($__refs, $__v); /* Unset defined __refs, __v. */
59
  /**/
77
  $s .= 'div#login form input[type="submit"], div#login form input[type="submit"]:hover, div#login form input[type="submit"]:active, div#login form input[type="submit"]:focus { color: #333333 !important; border: 1px solid #666666 !important; background: #CCCCCC !important; padding: 5px !important; -moz-border-radius: 3px !important; -webkit-border-radius: 3px !important; -khtml-border-radius: 3px !important; border-radius: 3px !important; }' . "\n";
78
  $s .= 'div#login form input[type="submit"]:hover, div#login form input[type="submit"]:active, div#login form input[type="submit"]:focus { color: #000000 !important; border: 1px solid #000000 !important; }' . "\n";
79
  /**/
80
+ $s .= 'div#login form input.ws-plugin--s2member-custom-reg-field, div#login form select.ws-plugin--s2member-custom-reg-field { background:none repeat scroll 0 0 #FBFBFB; border:1px solid #E5E5E5; font-size:24px; margin-bottom:16px; margin-right:6px; margin-top:2px; padding:3px; width:97%; }' . "\n";
81
+ $s .= 'div#login form select.ws-plugin--s2member-custom-reg-field { width:99%; }' . "\n"; /* Adjust select fields. */
82
  /**/
83
  if ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["custom_reg_password"])
84
  $s .= 'p#reg_passmail { display: none; }' . "\n";
85
  /**/
86
  $s .= '</style>' . "\n\n";
87
  /**/
88
+ eval ('foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;');
89
  do_action ("ws_plugin__s2member_during_login_header_styles", get_defined_vars ());
90
  unset ($__refs, $__v); /* Unset defined __refs, __v. */
91
  /**/
includes/functions/meta-boxes.inc.php CHANGED
@@ -12,7 +12,7 @@ If not, see: <http://www.gnu.org/licenses/>.
12
  Direct access denial.
13
  */
14
  if (realpath (__FILE__) === realpath ($_SERVER["SCRIPT_FILENAME"]))
15
- exit ("Do not access this file directly.");
16
  /*
17
  Function adds meta boxes to Post/Page editing stations.
18
  Attach to: add_action("admin_menu");
@@ -40,7 +40,7 @@ if (!function_exists ("ws_plugin__s2member_security_meta_box"))
40
  {
41
  function ws_plugin__s2member_security_meta_box ($post = FALSE)
42
  {
43
- eval ('foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;');
44
  do_action ("ws_plugin__s2member_before_security_meta_box", get_defined_vars ());
45
  unset ($__refs, $__v); /* Unset defined __refs, __v. */
46
  /**/
@@ -121,7 +121,7 @@ if (!function_exists ("ws_plugin__s2member_save_meta_boxes"))
121
  {
122
  function ws_plugin__s2member_save_meta_boxes ($post_id = FALSE)
123
  {
124
- eval ('foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;');
125
  do_action ("ws_plugin__s2member_before_save_meta_boxes", get_defined_vars ());
126
  unset ($__refs, $__v); /* Unset defined __refs, __v. */
127
  /**/
@@ -144,15 +144,15 @@ if (!function_exists ("ws_plugin__s2member_save_meta_boxes"))
144
  $pages["4"] = array_unique (preg_split ("/[\r\n\t\s;,]+/", $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["level4_pages"]));
145
  /**/
146
  if (($i = array_search ($page_id, $pages["0"])) !== false) /* Remove $page_id from existing options. */
147
- unset ($pages["0"][$i]);
148
  else if (($i = array_search ($page_id, $pages["1"])) !== false)
149
- unset ($pages["1"][$i]);
150
  else if (($i = array_search ($page_id, $pages["2"])) !== false)
151
- unset ($pages["2"][$i]);
152
  else if (($i = array_search ($page_id, $pages["3"])) !== false)
153
- unset ($pages["3"][$i]);
154
  else if (($i = array_search ($page_id, $pages["4"])) !== false)
155
- unset ($pages["4"][$i]);
156
  /**/
157
  if (strlen ($_p["ws_plugin__s2member_security_meta_box_level"]) && is_array ($pages[$_p["ws_plugin__s2member_security_meta_box_level"]]))
158
  if (!$pages[$_p["ws_plugin__s2member_security_meta_box_level"]] !== array ("all"))
@@ -160,7 +160,7 @@ if (!function_exists ("ws_plugin__s2member_save_meta_boxes"))
160
  /**/
161
  $new_options = array_merge ((array)$new_options, array ("ws_plugin__s2member_level0_pages" => implode (",", $pages[0]), "ws_plugin__s2member_level1_pages" => implode (",", $pages[1]), "ws_plugin__s2member_level2_pages" => implode (",", $pages[2]), "ws_plugin__s2member_level3_pages" => implode (",", $pages[3]), "ws_plugin__s2member_level4_pages" => implode (",", $pages[4])));
162
  /**/
163
- eval ('foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;');
164
  do_action ("ws_plugin__s2member_during_save_meta_boxes", get_defined_vars ());
165
  unset ($__refs, $__v); /* Unset defined __refs, __v. */
166
  /**/
@@ -179,15 +179,15 @@ if (!function_exists ("ws_plugin__s2member_save_meta_boxes"))
179
  $posts["4"] = array_unique (preg_split ("/[\r\n\t\s;,]+/", $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["level4_posts"]));
180
  /**/
181
  if (($i = array_search ($post_id, $posts["0"])) !== false) /* Remove $post_id from existing options. */
182
- unset ($posts["0"][$i]);
183
  else if (($i = array_search ($post_id, $posts["1"])) !== false)
184
- unset ($posts["1"][$i]);
185
  else if (($i = array_search ($post_id, $posts["2"])) !== false)
186
- unset ($posts["2"][$i]);
187
  else if (($i = array_search ($post_id, $posts["3"])) !== false)
188
- unset ($posts["3"][$i]);
189
  else if (($i = array_search ($post_id, $posts["4"])) !== false)
190
- unset ($posts["4"][$i]);
191
  /**/
192
  if (strlen ($_p["ws_plugin__s2member_security_meta_box_level"]) && is_array ($posts[$_p["ws_plugin__s2member_security_meta_box_level"]]))
193
  if (!$posts[$_p["ws_plugin__s2member_security_meta_box_level"]] !== array ("all"))
@@ -195,7 +195,7 @@ if (!function_exists ("ws_plugin__s2member_save_meta_boxes"))
195
  /**/
196
  $new_options = array_merge ((array)$new_options, array ("ws_plugin__s2member_level0_posts" => implode (",", $posts[0]), "ws_plugin__s2member_level1_posts" => implode (",", $posts[1]), "ws_plugin__s2member_level2_posts" => implode (",", $posts[2]), "ws_plugin__s2member_level3_posts" => implode (",", $posts[3]), "ws_plugin__s2member_level4_posts" => implode (",", $posts[4])));
197
  /**/
198
- eval ('foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;');
199
  do_action ("ws_plugin__s2member_during_save_meta_boxes", get_defined_vars ());
200
  unset ($__refs, $__v); /* Unset defined __refs, __v. */
201
  /**/
@@ -209,7 +209,12 @@ if (!function_exists ("ws_plugin__s2member_save_meta_boxes"))
209
  {
210
  $ccaps_req = trim (strtolower ($_p["ws_plugin__s2member_security_meta_box_ccaps"]), ",");
211
  $ccaps_req = trim (preg_replace ("/[^a-z_0-9,]/", "", $ccaps_req), ","); /* Now clean up. */
212
- update_post_meta ($page_id, "s2member_ccaps_req", preg_split ("/[\r\n\t\s;,]+/", $ccaps_req));
 
 
 
 
 
213
  }
214
  }
215
  /**/
@@ -219,7 +224,12 @@ if (!function_exists ("ws_plugin__s2member_save_meta_boxes"))
219
  {
220
  $ccaps_req = trim (strtolower ($_p["ws_plugin__s2member_security_meta_box_ccaps"]), ",");
221
  $ccaps_req = trim (preg_replace ("/[^a-z_0-9,]/", "", $ccaps_req), ","); /* Now clean up. */
222
- update_post_meta ($post_id, "s2member_ccaps_req", preg_split ("/[\r\n\t\s;,]+/", $ccaps_req));
 
 
 
 
 
223
  }
224
  }
225
  }
12
  Direct access denial.
13
  */
14
  if (realpath (__FILE__) === realpath ($_SERVER["SCRIPT_FILENAME"]))
15
+ exit("Do not access this file directly.");
16
  /*
17
  Function adds meta boxes to Post/Page editing stations.
18
  Attach to: add_action("admin_menu");
40
  {
41
  function ws_plugin__s2member_security_meta_box ($post = FALSE)
42
  {
43
+ eval('foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;');
44
  do_action ("ws_plugin__s2member_before_security_meta_box", get_defined_vars ());
45
  unset ($__refs, $__v); /* Unset defined __refs, __v. */
46
  /**/
121
  {
122
  function ws_plugin__s2member_save_meta_boxes ($post_id = FALSE)
123
  {
124
+ eval('foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;');
125
  do_action ("ws_plugin__s2member_before_save_meta_boxes", get_defined_vars ());
126
  unset ($__refs, $__v); /* Unset defined __refs, __v. */
127
  /**/
144
  $pages["4"] = array_unique (preg_split ("/[\r\n\t\s;,]+/", $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["level4_pages"]));
145
  /**/
146
  if (($i = array_search ($page_id, $pages["0"])) !== false) /* Remove $page_id from existing options. */
147
+ unset($pages["0"][$i]);
148
  else if (($i = array_search ($page_id, $pages["1"])) !== false)
149
+ unset($pages["1"][$i]);
150
  else if (($i = array_search ($page_id, $pages["2"])) !== false)
151
+ unset($pages["2"][$i]);
152
  else if (($i = array_search ($page_id, $pages["3"])) !== false)
153
+ unset($pages["3"][$i]);
154
  else if (($i = array_search ($page_id, $pages["4"])) !== false)
155
+ unset($pages["4"][$i]);
156
  /**/
157
  if (strlen ($_p["ws_plugin__s2member_security_meta_box_level"]) && is_array ($pages[$_p["ws_plugin__s2member_security_meta_box_level"]]))
158
  if (!$pages[$_p["ws_plugin__s2member_security_meta_box_level"]] !== array ("all"))
160
  /**/
161
  $new_options = array_merge ((array)$new_options, array ("ws_plugin__s2member_level0_pages" => implode (",", $pages[0]), "ws_plugin__s2member_level1_pages" => implode (",", $pages[1]), "ws_plugin__s2member_level2_pages" => implode (",", $pages[2]), "ws_plugin__s2member_level3_pages" => implode (",", $pages[3]), "ws_plugin__s2member_level4_pages" => implode (",", $pages[4])));
162
  /**/
163
+ eval('foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;');
164
  do_action ("ws_plugin__s2member_during_save_meta_boxes", get_defined_vars ());
165
  unset ($__refs, $__v); /* Unset defined __refs, __v. */
166
  /**/
179
  $posts["4"] = array_unique (preg_split ("/[\r\n\t\s;,]+/", $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["level4_posts"]));
180
  /**/
181
  if (($i = array_search ($post_id, $posts["0"])) !== false) /* Remove $post_id from existing options. */
182
+ unset($posts["0"][$i]);
183
  else if (($i = array_search ($post_id, $posts["1"])) !== false)
184
+ unset($posts["1"][$i]);
185
  else if (($i = array_search ($post_id, $posts["2"])) !== false)
186
+ unset($posts["2"][$i]);
187
  else if (($i = array_search ($post_id, $posts["3"])) !== false)
188
+ unset($posts["3"][$i]);
189
  else if (($i = array_search ($post_id, $posts["4"])) !== false)
190
+ unset($posts["4"][$i]);
191
  /**/
192
  if (strlen ($_p["ws_plugin__s2member_security_meta_box_level"]) && is_array ($posts[$_p["ws_plugin__s2member_security_meta_box_level"]]))
193
  if (!$posts[$_p["ws_plugin__s2member_security_meta_box_level"]] !== array ("all"))
195
  /**/
196
  $new_options = array_merge ((array)$new_options, array ("ws_plugin__s2member_level0_posts" => implode (",", $posts[0]), "ws_plugin__s2member_level1_posts" => implode (",", $posts[1]), "ws_plugin__s2member_level2_posts" => implode (",", $posts[2]), "ws_plugin__s2member_level3_posts" => implode (",", $posts[3]), "ws_plugin__s2member_level4_posts" => implode (",", $posts[4])));
197
  /**/
198
+ eval('foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;');
199
  do_action ("ws_plugin__s2member_during_save_meta_boxes", get_defined_vars ());
200
  unset ($__refs, $__v); /* Unset defined __refs, __v. */
201
  /**/
209
  {
210
  $ccaps_req = trim (strtolower ($_p["ws_plugin__s2member_security_meta_box_ccaps"]), ",");
211
  $ccaps_req = trim (preg_replace ("/[^a-z_0-9,]/", "", $ccaps_req), ","); /* Now clean up. */
212
+ /**/
213
+ if (($s2member_ccaps_req = preg_split ("/[\r\n\t\s;,]+/", $ccaps_req)))
214
+ update_post_meta ($page_id, "s2member_ccaps_req", $s2member_ccaps_req);
215
+ /**/
216
+ else /* Otherwise, the array is empty. Safe to delete. */
217
+ delete_post_meta ($page_id, "s2member_ccaps_req");
218
  }
219
  }
220
  /**/
224
  {
225
  $ccaps_req = trim (strtolower ($_p["ws_plugin__s2member_security_meta_box_ccaps"]), ",");
226
  $ccaps_req = trim (preg_replace ("/[^a-z_0-9,]/", "", $ccaps_req), ","); /* Now clean up. */
227
+ /**/
228
+ if (($s2member_ccaps_req = preg_split ("/[\r\n\t\s;,]+/", $ccaps_req)))
229
+ update_post_meta ($post_id, "s2member_ccaps_req", $s2member_ccaps_req);
230
+ /**/
231
+ else /* Otherwise, the array is empty. Safe to delete. */
232
+ delete_post_meta ($post_id, "s2member_ccaps_req");
233
  }
234
  }
235
  }
includes/functions/page-level-access.inc.php CHANGED
@@ -77,7 +77,7 @@ if (!function_exists ("ws_plugin__s2member_check_page_level_access"))
77
  /**/
78
  else if (is_array ($ccaps_req = get_post_meta ($page_ID, "s2member_ccaps_req", true))) /* Check for per Post Custom Capability requirements. */
79
  foreach ($ccaps_req as $ccap) /* The $current_user MUST satisfy ALL Custom Capability requirements. These are all stored as a serialized array. */
80
- if (strlen ($ccap) && (!$current_user || !$current_user->hap_cap ("access_s2member_ccap_" . $ccap)))
81
  {
82
  wp_redirect(add_query_arg ("s2member_ccap_req", $ccap, get_page_link ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["membership_options_page"])));
83
  exit ();
77
  /**/
78
  else if (is_array ($ccaps_req = get_post_meta ($page_ID, "s2member_ccaps_req", true))) /* Check for per Post Custom Capability requirements. */
79
  foreach ($ccaps_req as $ccap) /* The $current_user MUST satisfy ALL Custom Capability requirements. These are all stored as a serialized array. */
80
+ if (strlen ($ccap) && (!$current_user || !$current_user->has_cap ("access_s2member_ccap_" . $ccap)))
81
  {
82
  wp_redirect(add_query_arg ("s2member_ccap_req", $ccap, get_page_link ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["membership_options_page"])));
83
  exit ();
includes/functions/paypal-button.inc.php CHANGED
@@ -21,16 +21,16 @@ Attach to: add_shortcode("s2Member-PayPal-Button");
21
  [s2Member-PayPal-Button page="0" exp="72" desc="Specific Post/Page Access" ps="paypal" cc="USD" custom="www.domain.com" ra="0.01" sp="1" image="default" /]
22
  The image="" attribute will be used as a custom image; when provided; and not equal to "default".
23
 
24
- PayPal® Cancellation Buttons are identified by cancel="1".
25
- PayPal® Specific Post/Page Buttons are identified by sp="1".
26
- PayPal® Modification Buttons are identified by modify="1".
27
  */
28
- if (!function_exists ("ws_plugin__s2member_paypal_button"))
29
  {
30
- function ws_plugin__s2member_paypal_button ($attr = FALSE, $content = FALSE, $shortcode = FALSE)
31
  {
32
  eval('foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;');
33
- do_action ("ws_plugin__s2member_before_paypal_button", get_defined_vars ());
34
  unset ($__refs, $__v); /* Unset defined __refs, __v. */
35
  /**/
36
  $attr = ws_plugin__s2member_trim_quot_deep ($attr); /* Fix &quot; in Shortcode attrs
@@ -50,7 +50,7 @@ if (!function_exists ("ws_plugin__s2member_paypal_button"))
50
  $attr = shortcode_atts (array ("ids" => "0", "exp" => "72", "level" => "1", "ccaps" => "", "desc" => "", "ps" => "paypal", "cc" => "USD", "custom" => $_SERVER["HTTP_HOST"], "tp" => "0", "tt" => "D", "ra" => "0.01", "rp" => "1", "rt" => "M", "rr" => "1", "modify" => "0", "cancel" => "0", "sp" => "0", "image" => "default"), $attr);
51
  /**/
52
  eval('foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;');
53
- do_action ("ws_plugin__s2member_before_paypal_button_after_shortcode_atts", get_defined_vars ());
54
  unset ($__refs, $__v); /* Unset defined __refs, __v. */
55
  /**/
56
  if ($attr["cancel"]) /* This is a special routine for Cancellation Buttons. Cancellation Buttons use a different template. */
@@ -62,7 +62,7 @@ if (!function_exists ("ws_plugin__s2member_paypal_button"))
62
  $code = ($attr["image"] && $attr["image"] !== "default") ? preg_replace ('/ src\="(.*?)"/', ' src="' . ws_plugin__s2member_esc_ds (esc_attr ($attr["image"])) . '"', $code) : $code;
63
  /**/
64
  eval('foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;');
65
- do_action ("ws_plugin__s2member_during_paypal_cancellation_button", get_defined_vars ());
66
  unset ($__refs, $__v); /* Unset defined __refs, __v. */
67
  }
68
  /**/
@@ -88,7 +88,7 @@ if (!function_exists ("ws_plugin__s2member_paypal_button"))
88
  $code = ($attr["image"] && $attr["image"] !== "default") ? preg_replace ('/ src\="(.*?)"/', ' src="' . ws_plugin__s2member_esc_ds (esc_attr ($attr["image"])) . '"', $code) : $code;
89
  /**/
90
  eval('foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;');
91
- do_action ("ws_plugin__s2member_during_paypal_sp_button", get_defined_vars ());
92
  unset ($__refs, $__v); /* Unset defined __refs, __v. */
93
  }
94
  else /* Otherwise, we'll process this Button normally, using the Membership routines. Also handles Modification Buttons. */
@@ -134,11 +134,11 @@ if (!function_exists ("ws_plugin__s2member_paypal_button"))
134
  $code = ($attr["image"] && $attr["image"] !== "default") ? preg_replace ('/ src\="(.*?)"/', ' src="' . ws_plugin__s2member_esc_ds (esc_attr ($attr["image"])) . '"', $code) : $code;
135
  /**/
136
  eval('foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;');
137
- ($attr["modify"]) ? do_action ("ws_plugin__s2member_during_paypal_modification_button", get_defined_vars ()) : do_action ("ws_plugin__s2member_during_paypal_button", get_defined_vars ());
138
  unset ($__refs, $__v); /* Unset defined __refs, __v. */
139
  }
140
  /**/
141
- return apply_filters ("ws_plugin__s2member_paypal_button", $code, get_defined_vars ());
142
  }
143
  }
144
  ?>
21
  [s2Member-PayPal-Button page="0" exp="72" desc="Specific Post/Page Access" ps="paypal" cc="USD" custom="www.domain.com" ra="0.01" sp="1" image="default" /]
22
  The image="" attribute will be used as a custom image; when provided; and not equal to "default".
23
 
24
+ - PayPal® Cancellation Buttons are identified by cancel="1".
25
+ - PayPal® Specific Post/Page Buttons are identified by sp="1".
26
+ - PayPal® Modification Buttons are identified by modify="1".
27
  */
28
+ if (!function_exists ("ws_plugin__s2member_sc_paypal_button"))
29
  {
30
+ function ws_plugin__s2member_sc_paypal_button ($attr = FALSE, $content = FALSE, $shortcode = FALSE)
31
  {
32
  eval('foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;');
33
+ do_action ("ws_plugin__s2member_before_sc_paypal_button", get_defined_vars ());
34
  unset ($__refs, $__v); /* Unset defined __refs, __v. */
35
  /**/
36
  $attr = ws_plugin__s2member_trim_quot_deep ($attr); /* Fix &quot; in Shortcode attrs
50
  $attr = shortcode_atts (array ("ids" => "0", "exp" => "72", "level" => "1", "ccaps" => "", "desc" => "", "ps" => "paypal", "cc" => "USD", "custom" => $_SERVER["HTTP_HOST"], "tp" => "0", "tt" => "D", "ra" => "0.01", "rp" => "1", "rt" => "M", "rr" => "1", "modify" => "0", "cancel" => "0", "sp" => "0", "image" => "default"), $attr);
51
  /**/
52
  eval('foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;');
53
+ do_action ("ws_plugin__s2member_before_sc_paypal_button_after_shortcode_atts", get_defined_vars ());
54
  unset ($__refs, $__v); /* Unset defined __refs, __v. */
55
  /**/
56
  if ($attr["cancel"]) /* This is a special routine for Cancellation Buttons. Cancellation Buttons use a different template. */
62
  $code = ($attr["image"] && $attr["image"] !== "default") ? preg_replace ('/ src\="(.*?)"/', ' src="' . ws_plugin__s2member_esc_ds (esc_attr ($attr["image"])) . '"', $code) : $code;
63
  /**/
64
  eval('foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;');
65
+ do_action ("ws_plugin__s2member_during_sc_paypal_cancellation_button", get_defined_vars ());
66
  unset ($__refs, $__v); /* Unset defined __refs, __v. */
67
  }
68
  /**/
88
  $code = ($attr["image"] && $attr["image"] !== "default") ? preg_replace ('/ src\="(.*?)"/', ' src="' . ws_plugin__s2member_esc_ds (esc_attr ($attr["image"])) . '"', $code) : $code;
89
  /**/
90
  eval('foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;');
91
+ do_action ("ws_plugin__s2member_during_sc_paypal_sp_button", get_defined_vars ());
92
  unset ($__refs, $__v); /* Unset defined __refs, __v. */
93
  }
94
  else /* Otherwise, we'll process this Button normally, using the Membership routines. Also handles Modification Buttons. */
134
  $code = ($attr["image"] && $attr["image"] !== "default") ? preg_replace ('/ src\="(.*?)"/', ' src="' . ws_plugin__s2member_esc_ds (esc_attr ($attr["image"])) . '"', $code) : $code;
135
  /**/
136
  eval('foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;');
137
+ ($attr["modify"]) ? do_action ("ws_plugin__s2member_during_sc_paypal_modification_button", get_defined_vars ()) : do_action ("ws_plugin__s2member_during_sc_paypal_button", get_defined_vars ());
138
  unset ($__refs, $__v); /* Unset defined __refs, __v. */
139
  }
140
  /**/
141
+ return apply_filters ("ws_plugin__s2member_sc_paypal_button", $code, get_defined_vars ());
142
  }
143
  }
144
  ?>
includes/functions/paypal-notify.inc.php CHANGED
@@ -779,13 +779,19 @@ if (!function_exists ("ws_plugin__s2member_paypal_notify"))
779
  do_action ("ws_plugin__s2member_during_paypal_notify_before_subscr_eot", get_defined_vars ());
780
  unset ($__refs, $__v); /* Unset defined __refs, __v. */
781
  /**/
 
 
 
 
782
  $paypal["s2member_log"][] = "s2Member txn_type identified as (subscr_eot|recurring_payment_expired|recurring_payment_suspended_due_to_max_failed_payment) - or - recurring_payment_profile_cancel w/ initial_payment_status (failed) - or - new_case w/ case_type (chargeback) - or - !txn_type w/ payment_status (refunded|reversed).";
783
  /**/
784
  if (($user_id = ws_plugin__s2member_paypal_user_id ($paypal["subscr_id"], $paypal["option_selection1"])) && is_object ($user = new WP_User ($user_id)) && $user->ID)
785
  {
786
- if (!get_user_option ("s2member_auto_eot_time", $user_id) || /* Respect Auto-EOT; EXCEPT on refund/reverals. */
787
- (!$paypal["txn_type"] && preg_match ("/^(refunded|reversed)$/i", $paypal["payment_status"]) && $paypal["parent_txn_id"]))
788
- /* A refund/reversal will ALWAYS trigger an immediate EOT; even if there is already an Auto-EOT set. */
 
 
789
  {
790
  if (!$user->has_cap ("administrator")) /* Do NOT process this routine on Administrators. */
791
  {
@@ -882,9 +888,17 @@ if (!function_exists ("ws_plugin__s2member_paypal_notify"))
882
  $paypal["s2member_log"][] = "Unable to (demote|delete) Member. The existing User ID is associated with an Administrator. Stopping here. Otherwise, an Administrator could lose access.";
883
  }
884
  }
885
- else
 
 
 
 
 
 
 
 
886
  {
887
- $paypal["s2member_log"][] = "Skipping (demote|delete) Member, for now. An Auto-EOT Time is already set. When an Auto-EOT Time has been recorded, s2Member will handle EOT (demote|delete) events using it's own Auto-EOT System.";
888
  }
889
  }
890
  else
@@ -897,7 +911,7 @@ if (!function_exists ("ws_plugin__s2member_paypal_notify"))
897
  Since this routine ignores the processing check, it is *possible* that Refund/Reversal Notification URLs will be contacted more than once.
898
  If you're writing scripts that depend on Refund/Reversal Notifications, please keep this in mind.
899
  */
900
- if (!$paypal["txn_type"] && preg_match ("/^(refunded|reversed)$/i", $paypal["payment_status"]) && $paypal["parent_txn_id"])
901
  {
902
  if ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["ref_rev_notification_urls"] && is_array ($cv = preg_split ("/\|/", $paypal["custom"])))
903
  {
779
  do_action ("ws_plugin__s2member_during_paypal_notify_before_subscr_eot", get_defined_vars ());
780
  unset ($__refs, $__v); /* Unset defined __refs, __v. */
781
  /**/
782
+ $is_refund = (!$paypal["txn_type"] && preg_match ("/^refunded$/i", $paypal["payment_status"]) && $paypal["parent_txn_id"]);
783
+ $is_reversal = (!$paypal["txn_type"] && preg_match ("/^reversed$/i", $paypal["payment_status"]) && $paypal["parent_txn_id"]);
784
+ $is_refund_or_reversal = (!$paypal["txn_type"] && preg_match ("/^(refunded|reversed)$/i", $paypal["payment_status"]) && $paypal["parent_txn_id"]);
785
+ /**/
786
  $paypal["s2member_log"][] = "s2Member txn_type identified as (subscr_eot|recurring_payment_expired|recurring_payment_suspended_due_to_max_failed_payment) - or - recurring_payment_profile_cancel w/ initial_payment_status (failed) - or - new_case w/ case_type (chargeback) - or - !txn_type w/ payment_status (refunded|reversed).";
787
  /**/
788
  if (($user_id = ws_plugin__s2member_paypal_user_id ($paypal["subscr_id"], $paypal["option_selection1"])) && is_object ($user = new WP_User ($user_id)) && $user->ID)
789
  {
790
+ if ( /* Here we take action, but based on some advanced behavioral settings. */
791
+ (!$is_refund_or_reversal && !get_user_option ("s2member_auto_eot_time", $user_id))/**/
792
+ || ($is_refund_or_reversal && $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["triggers_immediate_eot"] === "refunds,reversals")/**/
793
+ || ($is_reversal && $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["triggers_immediate_eot"] === "reversals")/**/
794
+ || ($is_refund && $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["triggers_immediate_eot"] === "refunds")/**/)
795
  {
796
  if (!$user->has_cap ("administrator")) /* Do NOT process this routine on Administrators. */
797
  {
888
  $paypal["s2member_log"][] = "Unable to (demote|delete) Member. The existing User ID is associated with an Administrator. Stopping here. Otherwise, an Administrator could lose access.";
889
  }
890
  }
891
+ else if (!$is_refund_or_reversal)
892
+ {
893
+ $paypal["s2member_log"][] = "Skipping (demote|delete) Member, for now. An Auto-EOT Time is already set for this account. When an Auto-EOT Time has been recorded, s2Member will handle EOT (demote|delete) events using it's own Auto-EOT System - internally.";
894
+ }
895
+ else if ($is_reversal)
896
+ {
897
+ $paypal["s2member_log"][] = "Skipping (demote|delete) Member. Your configuration dictates that s2Member should NOT take any immediate action on an EOT associated with a Chargeback Reversal. An s2Member API Notification will still be processed however.";
898
+ }
899
+ else if ($is_refund)
900
  {
901
+ $paypal["s2member_log"][] = "Skipping (demote|delete) Member. Your configuration dictates that s2Member should NOT take any immediate action on an EOT associated with a Refund. An s2Member API Notification will still be processed however.";
902
  }
903
  }
904
  else
911
  Since this routine ignores the processing check, it is *possible* that Refund/Reversal Notification URLs will be contacted more than once.
912
  If you're writing scripts that depend on Refund/Reversal Notifications, please keep this in mind.
913
  */
914
+ if ($is_refund_or_reversal) /* Here we access this variable that was previously assigned as a quick method of Refund/Reversal detection. */
915
  {
916
  if ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["ref_rev_notification_urls"] && is_array ($cv = preg_split ("/\|/", $paypal["custom"])))
917
  {
includes/functions/post-level-access.inc.php CHANGED
@@ -68,7 +68,7 @@ if (!function_exists ("ws_plugin__s2member_check_post_level_access"))
68
  /**/
69
  else if (is_array ($ccaps_req = get_post_meta ($post_ID, "s2member_ccaps_req", true))) /* Check for per Post Custom Capability requirements. */
70
  foreach ($ccaps_req as $ccap) /* The $current_user MUST satisfy ALL Custom Capability requirements. These are all stored as a serialized array. */
71
- if (strlen ($ccap) && (!$current_user || !$current_user->hap_cap ("access_s2member_ccap_" . $ccap)))
72
  {
73
  wp_redirect (add_query_arg ("s2member_ccap_req", $ccap, get_page_link ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["membership_options_page"])));
74
  exit ();
68
  /**/
69
  else if (is_array ($ccaps_req = get_post_meta ($post_ID, "s2member_ccaps_req", true))) /* Check for per Post Custom Capability requirements. */
70
  foreach ($ccaps_req as $ccap) /* The $current_user MUST satisfy ALL Custom Capability requirements. These are all stored as a serialized array. */
71
+ if (strlen ($ccap) && (!$current_user || !$current_user->has_cap ("access_s2member_ccap_" . $ccap)))
72
  {
73
  wp_redirect (add_query_arg ("s2member_ccap_req", $ccap, get_page_link ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["membership_options_page"])));
74
  exit ();
includes/functions/register-access.inc.php CHANGED
@@ -416,10 +416,15 @@ if (!function_exists ("_ws_plugin__s2member_admin_user_new_fields"))
416
  $field_var = preg_replace ("/[^a-z0-9]/i", "_", strtolower ($field));
417
  $field_id_class = preg_replace ("/_/", "-", $field_var);
418
  /**/
419
- $unfs .= '<tr>' . "\n";
420
- $unfs .= '<th><label>' . esc_html ($field) . ':</label></th>' . "\n";
421
- $unfs .= '<td><input type="text" name="ws_plugin__s2member_user_new_' . $field_var . '" value="' . format_to_edit ($_POST["ws_plugin__s2member_user_new_" . $field_var]) . '" class="regular-text" /></td>' . "\n";
422
- $unfs .= '</tr>' . "\n";
 
 
 
 
 
423
  /**/
424
  eval ('foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;');
425
  do_action ("_ws_plugin__s2member_during_admin_user_new_fields_during_custom_fields_after", get_defined_vars ());
@@ -528,9 +533,14 @@ if (!function_exists ("ws_plugin__s2member_ms_custom_registration_fields"))
528
  $field_var = preg_replace ("/[^a-z0-9]/i", "_", strtolower ($field));
529
  $field_id_class = preg_replace ("/_/", "-", $field_var);
530
  /**/
531
- echo '<label for="ws-plugin--s2member-custom-reg-field-' . $field_id_class . '">' . esc_html ($field) . (($req) ? " *" : "") . '</label>' . "\n";
532
- echo '<input' . $req . ' type="text" maxlength="100" name="ws_plugin__s2member_custom_reg_field_' . $field_var . '" id="ws-plugin--s2member-custom-reg-field-' . $field_id_class . '" class="ws-plugin--s2member-custom-reg-field input" size="25" value="' . format_to_edit ($_POST["ws_plugin__s2member_custom_reg_field_" . $field_var]) . '" />' . "\n";
533
- echo '<br />' . "\n";
 
 
 
 
 
534
  /**/
535
  eval ('foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;');
536
  do_action ("ws_plugin__s2member_during_ms_custom_registration_fields_after_custom_fields", get_defined_vars ());
@@ -651,12 +661,17 @@ if (!function_exists ("ws_plugin__s2member_custom_registration_fields"))
651
  $field_var = preg_replace ("/[^a-z0-9]/i", "_", strtolower ($field));
652
  $field_id_class = preg_replace ("/_/", "-", $field_var);
653
  /**/
654
- echo '<p>' . "\n";
655
- echo '<label>' . "\n";
656
- echo esc_html ($field) . (($req) ? " *" : "") . "\n";
657
- echo '<input' . $req . ' type="text" maxlength="100" name="ws_plugin__s2member_custom_reg_field_' . $field_var . '" id="ws-plugin--s2member-custom-reg-field-' . $field_id_class . '" class="ws-plugin--s2member-custom-reg-field input" size="25" value="' . format_to_edit ($_POST["ws_plugin__s2member_custom_reg_field_" . $field_var]) . '" tabindex="' . esc_attr (($tabindex = $tabindex + 10)) . '" />' . "\n";
658
- echo '</label>' . "\n";
659
- echo '</p>';
 
 
 
 
 
660
  /**/
661
  eval ('foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;');
662
  do_action ("ws_plugin__s2member_during_custom_registration_fields_after_custom_fields", get_defined_vars ());
@@ -938,10 +953,16 @@ if (!function_exists ("ws_plugin__s2member_configure_user_registration"))
938
  /**/
939
  && $user_id && is_object ($user = new WP_User ($user_id)) && $user->ID && ($processed = true)) /* Process only once. */
940
  {
 
 
 
 
 
 
941
  if (!is_admin () && ($_POST["ws_plugin__s2member_custom_reg_field_s2member_custom"] || $_POST["ws_plugin__s2member_custom_reg_field_s2member_subscr_id"] || $_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"]))
942
  exit ("s2Member security violation. You attempted to POST variables that will NOT be trusted!");
943
  /**/
944
- $_pm = array_merge ((array)$_POST, (array)$meta); /* Merge these two data sources together. */
945
  /**/
946
  if (!is_admin () /* Only run this particular routine whenever a Member [1-4] is registering themselves with cookies. */
947
  && ($subscr_id = ws_plugin__s2member_decrypt ($_COOKIE["s2member_subscr_id"])) && preg_match ("/^" . preg_quote (preg_replace ("/\:([0-9]+)$/", "", $_SERVER["HTTP_HOST"]), "/") . "/i", ($custom = ws_plugin__s2member_decrypt ($_COOKIE["s2member_custom"]))) && preg_match ("/^[1-4](\:|$)([a-z_0-9,]+)?(\:)?([0-9]+ [A-Z])?$/", ($level = ws_plugin__s2member_decrypt ($_COOKIE["s2member_level"])))/**/
@@ -1163,7 +1184,7 @@ if (!function_exists ("ws_plugin__s2member_configure_user_registration"))
1163
  unset ($__refs, $__v); /* Unset defined __refs, __v. */
1164
  }
1165
  /**/
1166
- else if (is_admin () && $pagenow === "user-new.php") /* Else, if we're on this admin page. */
1167
  { /*
1168
  This routine can ONLY be processed through `user-new.php` inside the Dashboard.
1169
  */
@@ -1344,8 +1365,8 @@ if (!function_exists ("wp_generate_password"))
1344
  Function hides password fields for demo users.
1345
 
1346
  Demo accounts ( where the Username MUST be "demo" ), will NOT be allowed to change their password.
1347
- Any other restrictions you need to impose must be done through custom programming, using s2Member's Advanced Conditionals.
1348
- See `s2Member -> API Scripting -> Advanced Conditionals`.
1349
 
1350
  Attach to: add_filter("show_password_fields");
1351
  */
416
  $field_var = preg_replace ("/[^a-z0-9]/i", "_", strtolower ($field));
417
  $field_id_class = preg_replace ("/_/", "-", $field_var);
418
  /**/
419
+ eval ('foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;');
420
+ if (apply_filters ("_ws_plugin__s2member_during_admin_user_new_fields_during_custom_fields_display", true, get_defined_vars ()))
421
+ {
422
+ $unfs .= '<tr>' . "\n";
423
+ $unfs .= '<th><label>' . esc_html ($field) . ':</label></th>' . "\n";
424
+ $unfs .= '<td><input type="text" name="ws_plugin__s2member_user_new_' . $field_var . '" value="' . format_to_edit ($_POST["ws_plugin__s2member_user_new_" . $field_var]) . '" class="regular-text" /></td>' . "\n";
425
+ $unfs .= '</tr>' . "\n";
426
+ }
427
+ unset ($__refs, $__v); /* Unset defined __refs, __v. */
428
  /**/
429
  eval ('foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;');
430
  do_action ("_ws_plugin__s2member_during_admin_user_new_fields_during_custom_fields_after", get_defined_vars ());
533
  $field_var = preg_replace ("/[^a-z0-9]/i", "_", strtolower ($field));
534
  $field_id_class = preg_replace ("/_/", "-", $field_var);
535
  /**/
536
+ eval ('foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;');
537
+ if (apply_filters ("ws_plugin__s2member_during_ms_custom_registration_fields_during_custom_fields_display", true, get_defined_vars ()))
538
+ {
539
+ echo '<label for="ws-plugin--s2member-custom-reg-field-' . $field_id_class . '">' . esc_html ($field) . (($req) ? " *" : "") . '</label>' . "\n";
540
+ echo '<input' . $req . ' type="text" maxlength="100" name="ws_plugin__s2member_custom_reg_field_' . $field_var . '" id="ws-plugin--s2member-custom-reg-field-' . $field_id_class . '" class="ws-plugin--s2member-custom-reg-field input" size="25" value="' . format_to_edit ($_POST["ws_plugin__s2member_custom_reg_field_" . $field_var]) . '" />' . "\n";
541
+ echo '<br />' . "\n";
542
+ }
543
+ unset ($__refs, $__v); /* Unset defined __refs, __v. */
544
  /**/
545
  eval ('foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;');
546
  do_action ("ws_plugin__s2member_during_ms_custom_registration_fields_after_custom_fields", get_defined_vars ());
661
  $field_var = preg_replace ("/[^a-z0-9]/i", "_", strtolower ($field));
662
  $field_id_class = preg_replace ("/_/", "-", $field_var);
663
  /**/
664
+ eval ('foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;');
665
+ if (apply_filters ("ws_plugin__s2member_during_custom_registration_fields_during_custom_fields_display", true, get_defined_vars ()))
666
+ {
667
+ echo '<p>' . "\n";
668
+ echo '<label>' . "\n";
669
+ echo esc_html ($field) . (($req) ? " *" : "") . "\n";
670
+ echo '<input' . $req . ' type="text" maxlength="100" name="ws_plugin__s2member_custom_reg_field_' . $field_var . '" id="ws-plugin--s2member-custom-reg-field-' . $field_id_class . '" class="ws-plugin--s2member-custom-reg-field input" size="25" value="' . format_to_edit ($_POST["ws_plugin__s2member_custom_reg_field_" . $field_var]) . '" tabindex="' . esc_attr (($tabindex = $tabindex + 10)) . '" />' . "\n";
671
+ echo '</label>' . "\n";
672
+ echo '</p>';
673
+ }
674
+ unset ($__refs, $__v); /* Unset defined __refs, __v. */
675
  /**/
676
  eval ('foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;');
677
  do_action ("ws_plugin__s2member_during_custom_registration_fields_after_custom_fields", get_defined_vars ());
953
  /**/
954
  && $user_id && is_object ($user = new WP_User ($user_id)) && $user->ID && ($processed = true)) /* Process only once. */
955
  {
956
+ foreach ((array)$_POST as $key => $value) /* Scan $_POST vars; adding `custom_reg_field` uniformity keys. */
957
+ if (preg_match ("/^ws_plugin__s2member_user_new_/", $key)) /* Looking for `user_new` keys here. */
958
+ if ($key = preg_replace ("/_user_new_/", "_custom_reg_field_", $key))
959
+ $_POST[$key] = $value; /* Add these keys for uniformity. */
960
+ unset ($key, $value); /* Prevents bleeding vars into Hooks/Filters. */
961
+ /**/
962
  if (!is_admin () && ($_POST["ws_plugin__s2member_custom_reg_field_s2member_custom"] || $_POST["ws_plugin__s2member_custom_reg_field_s2member_subscr_id"] || $_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"]))
963
  exit ("s2Member security violation. You attempted to POST variables that will NOT be trusted!");
964
  /**/
965
+ $_pm = array_merge ((array)$_POST, (array)$meta); /* Merge these two data sources together now. However, ALWAYS after the security routine above ^. */
966
  /**/
967
  if (!is_admin () /* Only run this particular routine whenever a Member [1-4] is registering themselves with cookies. */
968
  && ($subscr_id = ws_plugin__s2member_decrypt ($_COOKIE["s2member_subscr_id"])) && preg_match ("/^" . preg_quote (preg_replace ("/\:([0-9]+)$/", "", $_SERVER["HTTP_HOST"]), "/") . "/i", ($custom = ws_plugin__s2member_decrypt ($_COOKIE["s2member_custom"]))) && preg_match ("/^[1-4](\:|$)([a-z_0-9,]+)?(\:)?([0-9]+ [A-Z])?$/", ($level = ws_plugin__s2member_decrypt ($_COOKIE["s2member_level"])))/**/
1184
  unset ($__refs, $__v); /* Unset defined __refs, __v. */
1185
  }
1186
  /**/
1187
+ else if (is_admin () && $pagenow === "user-new.php") /* Else, if we're on this page. */
1188
  { /*
1189
  This routine can ONLY be processed through `user-new.php` inside the Dashboard.
1190
  */
1365
  Function hides password fields for demo users.
1366
 
1367
  Demo accounts ( where the Username MUST be "demo" ), will NOT be allowed to change their password.
1368
+ Any other restrictions you need to impose must be done through custom programming, using s2Member's Conditionals.
1369
+ See `s2Member -> API Scripting`.
1370
 
1371
  Attach to: add_filter("show_password_fields");
1372
  */
includes/functions/sc-conditionals.inc.php ADDED
@@ -0,0 +1,168 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
+ Function that handles the Shortcode for [s2All ... simple conditionals][/s2All].
18
+ Function that handles the Shortcode for [s2Any ... simple conditionals][/s2Any].
19
+
20
+ Attach to: add_shortcode("s2All"), add_shortcode("_s2All"), add_shortcode("__s2All"), add_shortcode("___s2All");
21
+ Attach to: add_shortcode("s2Any"), add_shortcode("_s2Any"), add_shortcode("__s2Any"), add_shortcode("___s2Any");
22
+
23
+ [s2All is_user_logged_in="yes" current_user_can="access_s2member_level1"]
24
+
25
+ Content appears here for Members with access to Level #1.
26
+
27
+ [_s2All current_user_can="access_s2member_ccap_free_gift"]
28
+ Free gift here with nested Custom Capability check.
29
+ [/_s2All]
30
+
31
+ [/s2All]
32
+
33
+
34
+ [s2Any current_user_is="s2member_level1" current_user_is="s2member_level2"]
35
+
36
+ Content appears here for Members at Level #1 and Level #2.
37
+
38
+ [_s2Any current_user_can="access_s2member_ccap_free_gift"]
39
+ Free gift here with nested Custom Capability check.
40
+ [/_s2Any]
41
+
42
+ [/s2Any]
43
+
44
+ */
45
+ if (!function_exists ("ws_plugin__s2member_sc_conditionals"))
46
+ {
47
+ function ws_plugin__s2member_sc_conditionals ($attr = FALSE, $content = FALSE, $shortcode = FALSE)
48
+ {
49
+ eval('foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;');
50
+ do_action ("ws_plugin__s2member_before_sc_conditionals", get_defined_vars ());
51
+ unset ($__refs, $__v); /* Unset defined __refs, __v. */
52
+ /**/
53
+ $attr = ws_plugin__s2member_trim_quot_deep ($attr); /* Fix &quot; in Shortcode attrs
54
+ that have been corrupted by a non-default visual editor; ( i.e. CKEditor does this ). */
55
+ /**/
56
+ if (is_multisite () && ws_plugin__s2member_is_multisite_farm () && !is_main_site ()) /* Restrict to a subset of the most useful Conditionals on a Blog Farm. */
57
+ $attr = shortcode_atts (array ("is_user_logged_in" => "", "is_user_not_logged_in" => "", "current_user_is" => "", "current_user_is_not" => "", "current_user_is_for_blog" => "", "current_user_is_not_for_blog" => "", "current_user_can" => "", "current_user_cannot" => "", "current_user_can_for_blog" => "", "current_user_cannot_for_blog" => "", "is_404" => "", "is_home" => "", "is_front_page" => "", "is_singular" => "", "is_single" => "", "is_page" => "", "is_page_template" => "", "is_attachment" => "", "is_feed" => "", "is_archive" => "", "is_search" => "", "is_category" => "", "is_tax" => "", "is_tag" => "", "has_tag" => "", "is_author" => "", "is_date" => "", "is_day" => "", "is_month" => "", "is_time" => "", "is_year" => "", "is_sticky" => "", "is_paged" => "", "is_preview" => "", "in_the_loop" => "", "comments_open" => "", "pings_open" => "", "has_excerpt" => "", "has_post_image" => ""), $attr);
58
+ /**/
59
+ eval('foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;');
60
+ do_action ("ws_plugin__s2member_before_sc_conditionals_after_shortcode_atts", get_defined_vars ());
61
+ unset ($__refs, $__v); /* Unset defined __refs, __v. */
62
+ /**/
63
+ if (preg_match ("/^(_*)s2All$/i", $shortcode)) /* This is the AND variation. This routine analyzes conditionals using AND logic, instead of OR. */
64
+ {
65
+ foreach ($attr as $conditional => $_args) /* All conditions must evaluate to true; except for basic yes|no argument values that are = "no". */
66
+ {
67
+ if (strlen ($_args) && strlen ($_args = preg_replace ("/^array\(/i", "(", $_args))) /* Remove array() prefixes and leave only the () indicator. */
68
+ if (strlen ($_args = preg_replace ("/[\r\n\t\s ]/", "", $_args)) && is_array ($args = preg_split ("/[;,]+/", $_args, 0, PREG_SPLIT_NO_EMPTY)) && !empty ($args))
69
+ {
70
+ $args_are_yes_no = preg_match ("/^(true|yes|false|no)$/", $_args); /* Args can be passed as a simple yes|no. ( is_tag="yes" ). */
71
+ $args_are_yes = ($args_are_yes_no && preg_match ("/^(true|yes)$/", $_args)); /* Passed as a simple yes|no. ( is_tag="yes" ). */
72
+ $args_are_array = (!$args_are_yes_no && preg_match ("/^\((.+?)\)$/", $_args)); /* Example: has_tag="(cheese,butter,salt)" */
73
+ /**/
74
+ try /* Using try/catch here to protect this routine from errors due to invalid arguments passed through Shortcode attrs. */
75
+ {
76
+ if ($args_are_yes_no) /* No args. Only testing the return value. */
77
+ {
78
+ if ($args_are_yes && !call_user_func ($conditional))
79
+ {
80
+ $condition_failed = true;
81
+ break;
82
+ }
83
+ /**/
84
+ else if (call_user_func ($conditional))
85
+ {
86
+ $condition_failed = true;
87
+ break;
88
+ }
89
+ }
90
+ /**/
91
+ else if ($args_are_array && !call_user_func ($conditional, $args))
92
+ {
93
+ $condition_failed = true;
94
+ break;
95
+ }
96
+ /**/
97
+ else if (!call_user_func_array ($conditional, $args))
98
+ {
99
+ $condition_failed = true;
100
+ break;
101
+ }
102
+ }
103
+ /**/
104
+ catch (Exception $e) /* Catch errors silently. */
105
+ {
106
+ $condition_failed = true;
107
+ break;
108
+ }
109
+ }
110
+ }
111
+ /* Supports nested Shortcodes. */
112
+ return do_shortcode (apply_filters ("ws_plugin__s2member_sc_conditionals", (($condition_failed) ? "" : $content), get_defined_vars ()));
113
+ }
114
+ /**/
115
+ else if (preg_match ("/^(_*)s2Any$/i", $shortcode)) /* This is the OR variation. This routine analyzes conditionals using OR logic, instead of AND. */
116
+ {
117
+ foreach ($attr as $conditional => $_args) /* Any condition can evaluate to true; except for basic yes|no argument values that are = "no". */
118
+ {
119
+ if (strlen ($_args) && strlen ($_args = preg_replace ("/^array\(/i", "(", $_args))) /* Remove array() prefixes and leave only the () indicator. */
120
+ if (strlen ($_args = preg_replace ("/[\r\n\t\s ]/", "", $_args)) && is_array ($args = preg_split ("/[;,]+/", $_args, 0, PREG_SPLIT_NO_EMPTY)) && !empty ($args))
121
+ {
122
+ $args_are_yes_no = preg_match ("/^(true|yes|false|no)$/", $_args); /* Args can be passed as a simple yes|no. ( is_tag="yes" ). */
123
+ $args_are_yes = ($args_are_yes_no && preg_match ("/^(true|yes)$/", $_args)); /* Passed as a simple yes|no. ( is_tag="yes" ). */
124
+ $args_are_array = (!$args_are_yes_no && preg_match ("/^\((.+?)\)$/", $_args)); /* Example: has_tag="(cheese,butter,salt)" */
125
+ /**/
126
+ try /* Using try/catch here to protect this routine from errors due to invalid arguments passed through Shortcode attrs. */
127
+ {
128
+ if ($args_are_yes_no) /* No args. Only testing the return value. */
129
+ {
130
+ if ($args_are_yes && call_user_func ($conditional))
131
+ {
132
+ $condition_succeeded = true;
133
+ break;
134
+ }
135
+ /**/
136
+ else if (!call_user_func ($conditional))
137
+ {
138
+ $condition_succeeded = true;
139
+ break;
140
+ }
141
+ }
142
+ /**/
143
+ else if ($args_are_array && call_user_func ($conditional, $args))
144
+ {
145
+ $condition_succeeded = true;
146
+ break;
147
+ }
148
+ /**/
149
+ else if (call_user_func_array ($conditional, $args))
150
+ {
151
+ $condition_succeeded = true;
152
+ break;
153
+ }
154
+ }
155
+ /**/
156
+ catch (Exception $e) /* Catch errors silently. */
157
+ {
158
+ $condition_succeeded = false;
159
+ break;
160
+ }
161
+ }
162
+ }
163
+ /* Supports nested Shortcodes. */
164
+ return do_shortcode (apply_filters ("ws_plugin__s2member_sc_conditionals", (($condition_succeeded) ? $content : ""), get_defined_vars ()));
165
+ }
166
+ }
167
+ }
168
+ ?>
includes/functions/sc-get-details.inc.php ADDED
@@ -0,0 +1,77 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
+ Function that handles the Shortcode for [s2Get constant="S2MEMBER_CURRENT_USER_FIRST_NAME" user_option="s2member_subscr_id" /].
18
+ Attach to: add_shortcode("s2Get");
19
+ */
20
+ if (!function_exists ("ws_plugin__s2member_sc_get_details"))
21
+ {
22
+ function ws_plugin__s2member_sc_get_details ($attr = FALSE, $content = FALSE, $shortcode = FALSE)
23
+ {
24
+ static $current_user; /* Optimizes this routine a bit. */
25
+ $current_user = (!isset ($current_user)) ? wp_get_current_user () : $current_user;
26
+ /**/
27
+ eval('foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;');
28
+ do_action ("ws_plugin__s2member_before_sc_get_details", get_defined_vars ());
29
+ unset ($__refs, $__v); /* Unset defined __refs, __v. */
30
+ /**/
31
+ $attr = ws_plugin__s2member_trim_quot_deep ($attr); /* Fix &quot; in Shortcode attrs
32
+ that have been corrupted by a non-default visual editor; ( i.e. CKEditor does this ). */
33
+ /**/
34
+ $attr = shortcode_atts (array ("constant" => "", "custom_field" => "", "user_option" => ""), $attr);
35
+ /**/
36
+ eval('foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;');
37
+ do_action ("ws_plugin__s2member_before_sc_get_details_after_shortcode_atts", get_defined_vars ());
38
+ unset ($__refs, $__v); /* Unset defined __refs, __v. */
39
+ /**/
40
+ if ($attr["constant"] && defined ($attr["constant"])) /* Security check here. It must start with S2MEMBER_ on a Blog Farm. */
41
+ {
42
+ if (!is_multisite () || !ws_plugin__s2member_is_multisite_farm () || is_main_site () || preg_match ("/^S2MEMBER_/i", $attr["constant"]))
43
+ $get = constant ($attr["constant"]);
44
+ }
45
+ /**/
46
+ else if ($attr["custom_field"] && $current_user) /* Pull details out of the DB, matching a Custom Field being requested. */
47
+ {
48
+ if (preg_match ("/^(first_name|First Name)$/i", $attr["custom_field"]))
49
+ $get = $current_user->first_name;
50
+ /**/
51
+ else if (preg_match ("/^(last_name|Last Name)$/i", $attr["custom_field"]))
52
+ $get = $current_user->last_name;
53
+ /**/
54
+ else if (preg_match ("/^(email|E-mail|Email Address|E-mail Address)$/i", $attr["custom_field"]))
55
+ $get = $current_user->user_email;
56
+ /**/
57
+ else if (isset ($current_user->$attr["custom_field"]))
58
+ $get = $current_user->$attr["custom_field"];
59
+ /**/
60
+ else /* Otherwise, we assume it's an actual Custom Field. */
61
+ {
62
+ $field = trim ($attr["custom_field"], "^* \t\n\r\0\x0B");
63
+ $field_var = preg_replace ("/[^a-z0-9]/i", "_", strtolower ($field));
64
+ /**/
65
+ $fields = get_user_option ("s2member_custom_fields");
66
+ /**/
67
+ $get = $fields[$field_var];
68
+ }
69
+ }
70
+ /**/
71
+ else if ($attr["user_option"] && $current_user) /* Else pull details from meta table. */
72
+ $get = get_user_option ($attr["user_option"]);
73
+ /**/
74
+ return apply_filters ("ws_plugin__s2member_sc_get_details", $get, get_defined_vars ());
75
+ }
76
+ }
77
+ ?>
includes/functions/users-list.inc.php CHANGED
@@ -256,10 +256,13 @@ if (!function_exists ("ws_plugin__s2member_users_list_edit_cols"))
256
  $field_var = preg_replace ("/[^a-z0-9]/i", "_", strtolower ($field));
257
  $field_id_class = preg_replace ("/_/", "-", $field_var);
258
  /**/
259
- echo '<tr>' . "\n";
260
- echo '<th><label>' . esc_html ($field) . ':</label></th>' . "\n";
261
- echo '<td><input type="text" name="ws_plugin__s2member_profile_' . $field_var . '" value="' . format_to_edit ($fields[$field_var]) . '" class="regular-text" /></td>' . "\n";
262
- echo '</tr>' . "\n";
 
 
 
263
  /**/
264
  eval('foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;');
265
  do_action ("ws_plugin__s2member_during_users_list_edit_cols_during_custom_fields_after", get_defined_vars ());
@@ -325,6 +328,9 @@ if (!function_exists ("ws_plugin__s2member_users_list_edit_cols"))
325
  $une = preg_match ("/\^/", $field); /* Preventing this field from being edited? */
326
  $une = ($une) ? ' disabled="disabled"' : ''; /* Prevent this field from being edited. */
327
  /**/
 
 
 
328
  if ($field = trim ($field, "^* \t\n\r\0\x0B")) /* Don't process empty fields. */
329
  {
330
  eval('foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;');
@@ -334,10 +340,15 @@ if (!function_exists ("ws_plugin__s2member_users_list_edit_cols"))
334
  $field_var = preg_replace ("/[^a-z0-9]/i", "_", strtolower ($field));
335
  $field_id_class = preg_replace ("/_/", "-", $field_var);
336
  /**/
337
- echo '<tr>' . "\n";
338
- echo '<th><label>' . esc_html ($field) . ':</label></th>' . "\n";
339
- echo '<td><input' . $une . ' type="text" name="ws_plugin__s2member_profile_' . $field_var . '" value="' . format_to_edit ($fields[$field_var]) . '" class="regular-text" /></td>' . "\n";
340
- echo '</tr>' . "\n";
 
 
 
 
 
341
  /**/
342
  eval('foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;');
343
  do_action ("ws_plugin__s2member_during_users_list_edit_cols_during_custom_fields_after", get_defined_vars ());
256
  $field_var = preg_replace ("/[^a-z0-9]/i", "_", strtolower ($field));
257
  $field_id_class = preg_replace ("/_/", "-", $field_var);
258
  /**/
259
+ if (apply_filters ("ws_plugin__s2member_during_users_list_edit_cols_during_custom_fields_display", true, get_defined_vars ()))
260
+ {
261
+ echo '<tr>' . "\n";
262
+ echo '<th><label>' . esc_html ($field) . ':</label></th>' . "\n";
263
+ echo '<td><input type="text" name="ws_plugin__s2member_profile_' . $field_var . '" value="' . format_to_edit ($fields[$field_var]) . '" class="regular-text" /></td>' . "\n";
264
+ echo '</tr>' . "\n";
265
+ }
266
  /**/
267
  eval('foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;');
268
  do_action ("ws_plugin__s2member_during_users_list_edit_cols_during_custom_fields_after", get_defined_vars ());
328
  $une = preg_match ("/\^/", $field); /* Preventing this field from being edited? */
329
  $une = ($une) ? ' disabled="disabled"' : ''; /* Prevent this field from being edited. */
330
  /**/
331
+ $req = preg_match ("/\*/", $field); /* Required fields should be wrapped inside asterisks. */
332
+ $req = ($req) ? ' aria-required="true"' : ''; /* Has JavaScript validation applied. */
333
+ /**/
334
  if ($field = trim ($field, "^* \t\n\r\0\x0B")) /* Don't process empty fields. */
335
  {
336
  eval('foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;');
340
  $field_var = preg_replace ("/[^a-z0-9]/i", "_", strtolower ($field));
341
  $field_id_class = preg_replace ("/_/", "-", $field_var);
342
  /**/
343
+ eval('foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;');
344
+ if (apply_filters ("ws_plugin__s2member_during_users_list_edit_cols_during_custom_fields_display", true, get_defined_vars ()))
345
+ {
346
+ echo '<tr>' . "\n";
347
+ echo '<th><label>' . esc_html ($field) . ':</label></th>' . "\n";
348
+ echo '<td><input' . $une . $req . ' type="text" name="ws_plugin__s2member_profile_' . $field_var . '" value="' . format_to_edit ($fields[$field_var]) . '" class="regular-text" /></td>' . "\n";
349
+ echo '</tr>' . "\n";
350
+ }
351
+ unset ($__refs, $__v); /* Unset defined __refs, __v. */
352
  /**/
353
  eval('foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;');
354
  do_action ("ws_plugin__s2member_during_users_list_edit_cols_during_custom_fields_after", get_defined_vars ());
includes/functions/utilities.inc.php CHANGED
@@ -297,17 +297,6 @@ if (!function_exists ("ws_plugin__s2member_encrypt"))
297
  }
298
  }
299
  /*
300
- Alias function for API Scripting usage.
301
- Deprecated in v3.0.5. This will be removed in a future release.
302
- */
303
- if (!function_exists ("s2member_encrypt"))
304
- {
305
- function s2member_encrypt ($string = FALSE, $key = FALSE)
306
- {
307
- return ws_plugin__s2member_encrypt ($string, $key);
308
- }
309
- }
310
- /*
311
  RIJNDAEL 256: two-way encryption/decryption, with a url-safe base64 wrapper.
312
  Includes a built-in fallback on XOR encryption when mcrypt is not available.
313
  */
@@ -340,17 +329,6 @@ if (!function_exists ("ws_plugin__s2member_decrypt"))
340
  }
341
  }
342
  /*
343
- Alias function for API Scripting usage.
344
- Deprecated in v3.0.5. This will be removed in a future release.
345
- */
346
- if (!function_exists ("s2member_decrypt"))
347
- {
348
- function s2member_decrypt ($base64 = FALSE, $key = FALSE)
349
- {
350
- return ws_plugin__s2member_decrypt ($base64, $key);
351
- }
352
- }
353
- /*
354
  XOR two-way encryption/decryption, with a base64 wrapper.
355
  */
356
  if (!function_exists ("ws_plugin__s2member_xencrypt"))
@@ -378,17 +356,6 @@ if (!function_exists ("ws_plugin__s2member_xencrypt"))
378
  }
379
  }
380
  /*
381
- Alias function for API Scripting usage.
382
- Deprecated in v3.0.5. This will be removed in a future release.
383
- */
384
- if (!function_exists ("s2member_xencrypt"))
385
- {
386
- function s2member_xencrypt ($string = FALSE, $key = FALSE)
387
- {
388
- return ws_plugin__s2member_xencrypt ($string, $key);
389
- }
390
- }
391
- /*
392
  XOR two-way encryption/decryption, with a base64 wrapper.
393
  */
394
  if (!function_exists ("ws_plugin__s2member_xdecrypt"))
@@ -420,17 +387,6 @@ if (!function_exists ("ws_plugin__s2member_xdecrypt"))
420
  }
421
  }
422
  /*
423
- Alias function for API Scripting usage.
424
- Deprecated in v3.0.5. This will be removed in a future release.
425
- */
426
- if (!function_exists ("s2member_xdecrypt"))
427
- {
428
- function s2member_xdecrypt ($base64 = FALSE, $key = FALSE)
429
- {
430
- return ws_plugin__s2member_xdecrypt ($base64, $key);
431
- }
432
- }
433
- /*
434
  Function generates a random string with letters/numbers/symbols.
435
  */
436
  if (!function_exists ("ws_plugin__s2member_random_str_gen"))
297
  }
298
  }
299
  /*
 
 
 
 
 
 
 
 
 
 
 
300
  RIJNDAEL 256: two-way encryption/decryption, with a url-safe base64 wrapper.
301
  Includes a built-in fallback on XOR encryption when mcrypt is not available.
302
  */
329
  }
330
  }
331
  /*
 
 
 
 
 
 
 
 
 
 
 
332
  XOR two-way encryption/decryption, with a base64 wrapper.
333
  */
334
  if (!function_exists ("ws_plugin__s2member_xencrypt"))
356
  }
357
  }
358
  /*
 
 
 
 
 
 
 
 
 
 
 
359
  XOR two-way encryption/decryption, with a base64 wrapper.
360
  */
361
  if (!function_exists ("ws_plugin__s2member_xdecrypt"))
387
  }
388
  }
389
  /*
 
 
 
 
 
 
 
 
 
 
 
390
  Function generates a random string with letters/numbers/symbols.
391
  */
392
  if (!function_exists ("ws_plugin__s2member_random_str_gen"))
includes/hooks.inc.php CHANGED
@@ -12,7 +12,7 @@ If not, see: <http://www.gnu.org/licenses/>.
12
  Direct access denial.
13
  */
14
  if (realpath (__FILE__) === realpath ($_SERVER["SCRIPT_FILENAME"]))
15
- exit ("Do not access this file directly.");
16
  /*
17
  Add the plugin actions/filters here.
18
  */
@@ -41,6 +41,8 @@ add_action ("template_redirect", "ws_plugin__s2member_check_ptag_level_access",
41
  add_action ("template_redirect", "ws_plugin__s2member_check_post_level_access", 1);
42
  add_action ("template_redirect", "ws_plugin__s2member_check_page_level_access", 1);
43
  /**/
 
 
44
  add_action ("wp_print_styles", "ws_plugin__s2member_add_css");
45
  add_action ("wp_print_scripts", "ws_plugin__s2member_add_js_w_globals");
46
  add_filter ("gettext", "ws_plugin__s2member_translation_mangler", 10, 3);
12
  Direct access denial.
13
  */
14
  if (realpath (__FILE__) === realpath ($_SERVER["SCRIPT_FILENAME"]))
15
+ exit("Do not access this file directly.");
16
  /*
17
  Add the plugin actions/filters here.
18
  */
41
  add_action ("template_redirect", "ws_plugin__s2member_check_post_level_access", 1);
42
  add_action ("template_redirect", "ws_plugin__s2member_check_page_level_access", 1);
43
  /**/
44
+ add_filter ("widget_text", "do_shortcode"); /* Shortcodes in widgets. */
45
+ /**/
46
  add_action ("wp_print_styles", "ws_plugin__s2member_add_css");
47
  add_action ("wp_print_scripts", "ws_plugin__s2member_add_js_w_globals");
48
  add_filter ("gettext", "ws_plugin__s2member_translation_mangler", 10, 3);
includes/menu-pages/code-samples/current-user-access-label.php CHANGED
@@ -1,3 +1,7 @@
1
  <?php echo S2MEMBER_CURRENT_USER_ACCESS_LABEL; ?>
2
  This may output something like: Gold Membership
3
- ( or whatever Label you've configured for their Membership Level )
 
 
 
 
1
  <?php echo S2MEMBER_CURRENT_USER_ACCESS_LABEL; ?>
2
  This may output something like: Gold Membership
3
+ ( or whatever Label you've configured for their Membership Level )
4
+
5
+ ---- s2member Shortcode Equivalent ----
6
+
7
+ [s2Get constant="S2MEMBER_CURRENT_USER_ACCESS_LABEL" /].
includes/menu-pages/code-samples/current-user-access-level-conditional-upgrades.php CHANGED
@@ -8,4 +8,26 @@
8
  Insert Modification Button here. Upgrade Level 1 Members to Level 2 or higher.
9
  <?php } else if(S2MEMBER_CURRENT_USER_ACCESS_LEVEL === 0){ ?>
10
  Insert Modification Button here. Let Free Subscribers become a Member.
11
- <?php } ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
8
  Insert Modification Button here. Upgrade Level 1 Members to Level 2 or higher.
9
  <?php } else if(S2MEMBER_CURRENT_USER_ACCESS_LEVEL === 0){ ?>
10
  Insert Modification Button here. Let Free Subscribers become a Member.
11
+ <?php } ?>
12
+
13
+ ---- s2member Shortcode Equivalents ----
14
+
15
+ [s2All current_user_is="s2member_level4"]
16
+ Member is already at the highest Level. No Modification Button displayed here.
17
+ [/s2All]
18
+
19
+ [s2All current_user_is="s2member_level3"]
20
+ Insert Modification Button here. Upgrade Level 3 Members to highest Level 4.
21
+ [/s2All]
22
+
23
+ [s2All current_user_is="s2member_level2"]
24
+ Insert Modification Button here. Upgrade Level 2 Members to Level 3 or higher.
25
+ [/s2All]
26
+
27
+ [s2All current_user_is="s2member_level1"]
28
+ Insert Modification Button here. Upgrade Level 1 Members to Level 2 or higher.
29
+ [/s2All]
30
+
31
+ [s2All current_user_is="s2member_level0"]
32
+ Insert Modification Button here. Let Free Subscribers become a Member.
33
+ [/s2All]
includes/menu-pages/code-samples/current-user-access-level.php CHANGED
@@ -10,4 +10,30 @@
10
  A User is logged in as a Free Subscriber.
11
  <?php } else if(S2MEMBER_CURRENT_USER_ACCESS_LEVEL === -1){ ?>
12
  A User is not logged in at all.
13
- <?php } ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
10
  A User is logged in as a Free Subscriber.
11
  <?php } else if(S2MEMBER_CURRENT_USER_ACCESS_LEVEL === -1){ ?>
12
  A User is not logged in at all.
13
+ <?php } ?>
14
+
15
+ ---- s2member Shortcode Equivalent ----
16
+
17
+ [s2All current_user_is="s2member_level4"]
18
+ Some premium content for Level 4 Members.
19
+ [/s2All]
20
+
21
+ [s2All current_user_is="s2member_level3"]
22
+ Some premium content for Level 3 Members.
23
+ [/s2All]
24
+
25
+ [s2All current_user_is="s2member_level2"]
26
+ Some premium content for Level 2 Members.
27
+ [/s2All]
28
+
29
+ [s2All current_user_is="s2member_level1"]
30
+ Some premium content for Level 1 Members.
31
+ [/s2All]
32
+
33
+ [s2All current_user_is="s2member_level0"]
34
+ Some content for Free Subscribers.
35
+ [/s2All]
36
+
37
+ [s2All is_user_logged_in="no"]
38
+ Some public content.
39
+ [/s2All]
includes/menu-pages/code-samples/current-user-can-ccaps-1.php CHANGED
@@ -1,4 +1,4 @@
1
- <?php if (is_user_logged_in() && current_user_can("access_s2member_level1")){ ?>
2
 
3
  Some premium content for all Level 1 Members.
4
 
@@ -12,4 +12,24 @@
12
 
13
  <?php } else { ?>
14
  Some public content.
15
- <?php } ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php if (current_user_can("access_s2member_level1")){ ?>
2
 
3
  Some premium content for all Level 1 Members.
4
 
12
 
13
  <?php } else { ?>
14
  Some public content.
15
+ <?php } ?>
16
+
17
+ ---- s2member Shortcode Equivalents ----
18
+
19
+ [s2All current_user_can="access_s2member_level1"]
20
+
21
+ Some premium content for all Level 1 Members.
22
+
23
+ [_s2All current_user_can="access_s2member_ccap_music"]
24
+ Display links for music as well.
25
+ [/_s2All]
26
+
27
+ [_s2All current_user_can="access_s2member_ccap_videos"]
28
+ Display videos as well.
29
+ [/_s2All]
30
+
31
+ [/s2All]
32
+
33
+ [s2All current_user_cannot="access_s2member_level1"]
34
+ Some public content.
35
+ [/s2All]
includes/menu-pages/code-samples/current-user-can-ccaps-2.php CHANGED
@@ -1,4 +1,4 @@
1
- <?php if (is_user_logged_in() && current_user_can("access_s2member_level1")){ ?>
2
 
3
  Some premium content for all Level 1 Members.
4
 
@@ -25,4 +25,40 @@
25
 
26
  <?php } else { ?>
27
  Some public content.
28
- <?php } ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php if (current_user_can("access_s2member_level1")){ ?>
2
 
3
  Some premium content for all Level 1 Members.
4
 
25
 
26
  <?php } else { ?>
27
  Some public content.
28
+ <?php } ?>
29
+
30
+ ---- s2member Shortcode Equivalents ----
31
+
32
+ [s2All current_user_can="access_s2member_level1"]
33
+
34
+ Some premium content for all Level 1 Members.
35
+
36
+ [_s2All current_user_can="access_s2member_ccap_ebooks"]
37
+ Display links for downloading your eBooks.
38
+ [/_s2All]
39
+ [_s2All current_user_cannot="access_s2member_ccap_ebooks"]
40
+ Insert a PayPal® Modification Button that includes the Custom Capability: ebooks
41
+ This might read, "Upgrade Your Membership for access to my eBooks!".
42
+ [/_s2All]
43
+
44
+ [_s2All current_user_can="access_s2member_ccap_reports"]
45
+ Display links for accessing your reports.
46
+ [/_s2All]
47
+ [_s2All current_user_cannot="access_s2member_ccap_reports"]
48
+ Insert a PayPal® Modification Button that includes the Custom Capability: reports
49
+ This might read, "Upgrade Your Membership for access to my reports!".
50
+ [/_s2All]
51
+
52
+ [_s2All current_user_can="access_s2member_ccap_tips"]
53
+ Display tips.
54
+ [/_s2All]
55
+ [_s2All current_user_cannot="access_s2member_ccap_tips"]
56
+ Insert a PayPal® Modification Button that includes the Custom Capability: tips
57
+ This might read, "Upgrade Your Membership for access to my tips!".
58
+ [/_s2All]
59
+
60
+ [/s2All]
61
+
62
+ [s2All current_user_cannot="access_s2member_level1"]
63
+ Some public content.
64
+ [/s2All]
includes/menu-pages/code-samples/current-user-can-full-access.php CHANGED
@@ -1,4 +1,4 @@
1
- <?php if (is_user_logged_in() && current_user_can("access_s2member_level1")){ ?>
2
  Some content for Members who are logged in with an s2Member Level >= 1.
3
  <?php } else { ?>
4
  Some public content.
1
+ <?php if (current_user_can("access_s2member_level1")){ ?>
2
  Some content for Members who are logged in with an s2Member Level >= 1.
3
  <?php } else { ?>
4
  Some public content.
includes/menu-pages/code-samples/current-user-can-specific-content.php DELETED
@@ -1,13 +0,0 @@
1
- <?php if (is_user_logged_in() && current_user_can("access_s2member_level4")){ ?>
2
- Some premium content for Level 4 Members.
3
- <?php } else if (is_user_logged_in() && current_user_can("access_s2member_level3")){ ?>
4
- Some premium content for Level 3 Members.
5
- <?php } else if (is_user_logged_in() && current_user_can("access_s2member_level2")){ ?>
6
- Some premium content for Level 2 Members.
7
- <?php } else if (is_user_logged_in() && current_user_can("access_s2member_level1")){ ?>
8
- Some premium content for Level 1 Members.
9
- <?php } else if (is_user_logged_in() && current_user_can("access_s2member_level0")){ ?>
10
- Some content for Free Subscribers.
11
- <?php } else { ?>
12
- Some public content.
13
- <?php } ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
includes/menu-pages/code-samples/current-user-custom.php CHANGED
@@ -1,3 +1,7 @@
1
  <?php echo S2MEMBER_CURRENT_USER_CUSTOM; ?>
2
  This may output something like: www.yourdomain.com|cv1|cv2|cv3
3
- ( this is the PayPal input field value for the `custom` variable )
 
 
 
 
1
  <?php echo S2MEMBER_CURRENT_USER_CUSTOM; ?>
2
  This may output something like: www.yourdomain.com|cv1|cv2|cv3
3
+ ( this is the PayPal input field value for the `custom` variable )
4
+
5
+ ---- s2member Shortcode Equivalent ----
6
+
7
+ [s2Get constant="S2MEMBER_CURRENT_USER_CUSTOM" /]
includes/menu-pages/code-samples/current-user-display-name.php CHANGED
@@ -1,3 +1,7 @@
1
  <?php echo S2MEMBER_CURRENT_USER_DISPLAY_NAME; ?>
2
  This may output something like: Johnny
3
- ( this is the User's display name )
 
 
 
 
1
  <?php echo S2MEMBER_CURRENT_USER_DISPLAY_NAME; ?>
2
  This may output something like: Johnny
3
+ ( this is the User's display name )
4
+
5
+ ---- s2member Shortcode Equivalent ----
6
+
7
+ [s2Get constant="S2MEMBER_CURRENT_USER_DISPLAY_NAME" /]
includes/menu-pages/code-samples/current-user-downloads-allowed-days.php CHANGED
@@ -1,3 +1,7 @@
1
  <?php echo S2MEMBER_CURRENT_USER_DOWNLOADS_ALLOWED_DAYS; ?>
2
  This will output the number of days ( the period ) in which stats are being kept.
3
- ( users are allowed to download X number of files every X number of days )
 
 
 
 
1
  <?php echo S2MEMBER_CURRENT_USER_DOWNLOADS_ALLOWED_DAYS; ?>
2
  This will output the number of days ( the period ) in which stats are being kept.
3
+ ( users are allowed to download X number of files every X number of days )
4
+
5
+ ---- s2member Shortcode Equivalent ----
6
+
7
+ [s2Get constant="S2MEMBER_CURRENT_USER_DOWNLOADS_ALLOWED_DAYS" /]
includes/menu-pages/code-samples/current-user-downloads-allowed-is-unlimited.php CHANGED
@@ -1,2 +1,6 @@
1
  You are allowed to download <?php echo (S2MEMBER_CURRENT_USER_DOWNLOADS_ALLOWED_IS_UNLIMITED) ? 'Unlimited' : S2MEMBER_LEVEL2_FILE_DOWNLOADS_ALLOWED; ?> files
2
- every <?php S2MEMBER_LEVEL2_FILE_DOWNLOADS_ALLOWED_DAYS; ?> days.
 
 
 
 
1
  You are allowed to download <?php echo (S2MEMBER_CURRENT_USER_DOWNLOADS_ALLOWED_IS_UNLIMITED) ? 'Unlimited' : S2MEMBER_LEVEL2_FILE_DOWNLOADS_ALLOWED; ?> files
2
+ every <?php S2MEMBER_LEVEL2_FILE_DOWNLOADS_ALLOWED_DAYS; ?> days.
3
+
4
+ ---- s2member Shortcode Equivalent ----
5
+
6
+ There is NO equivalent for this logic yet.
includes/menu-pages/code-samples/current-user-downloads-allowed.php CHANGED
@@ -1,3 +1,7 @@
1
  <?php echo S2MEMBER_CURRENT_USER_DOWNLOADS_ALLOWED; ?>
2
  This will output the number of files they're allowed to download.
3
- ( the number of files allowed is based on their membership level )
 
 
 
 
1
  <?php echo S2MEMBER_CURRENT_USER_DOWNLOADS_ALLOWED; ?>
2
  This will output the number of files they're allowed to download.
3
+ ( the number of files allowed is based on their membership level )
4
+
5
+ ---- s2member Shortcode Equivalent ----
6
+
7
+ [s2Get constant="S2MEMBER_CURRENT_USER_DOWNLOADS_ALLOWED" /]
includes/menu-pages/code-samples/current-user-downloads-currently.php CHANGED
@@ -1,3 +1,7 @@
1
  <?php echo S2MEMBER_CURRENT_USER_DOWNLOADS_CURRENTLY; ?>
2
  This will output the number of files they've downloaded recently.
3
- ( that is, the number of files within the last X days, according to your configuration )
 
 
 
 
1
  <?php echo S2MEMBER_CURRENT_USER_DOWNLOADS_CURRENTLY; ?>
2
  This will output the number of files they've downloaded recently.
3
+ ( that is, the number of files within the last X days, according to your configuration )
4
+
5
+ ---- s2member Shortcode Equivalent ----
6
+
7
+ [s2Get constant="S2MEMBER_CURRENT_USER_DOWNLOADS_CURRENTLY" /]
includes/menu-pages/code-samples/current-user-email.php CHANGED
@@ -1,3 +1,7 @@
1
  <?php echo S2MEMBER_CURRENT_USER_EMAIL; ?>
2
  This may output something like: johnsmith@example.com
3
- ( or whatever their email address is )
 
 
 
 
1
  <?php echo S2MEMBER_CURRENT_USER_EMAIL; ?>
2
  This may output something like: johnsmith@example.com
3
+ ( or whatever their email address is )
4
+
5
+ ---- s2member Shortcode Equivalent ----
6
+
7
+ [s2Get constant="S2MEMBER_CURRENT_USER_EMAIL" /]
includes/menu-pages/code-samples/current-user-fields.php CHANGED
@@ -4,4 +4,20 @@ This would output the first and last name for the current user.
4
 
5
  Custom Fields are also included in the JSON decoded array.
6
  <?php print_r(json_decode(S2MEMBER_CURRENT_USER_FIELDS, true)); ?>
7
- ( Displays a full list of all associative array elements. )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4
 
5
  Custom Fields are also included in the JSON decoded array.
6
  <?php print_r(json_decode(S2MEMBER_CURRENT_USER_FIELDS, true)); ?>
7
+ ( Displays a full list of all associative array elements. )
8
+
9
+ ---- s2member Shortcode Equivalents ----
10
+
11
+ [s2Get custom_field="first_name" /]
12
+ [s2Get custom_field="last_name" /]
13
+ [s2Get custom_field="Website URL" /]
14
+ [s2Get custom_field="My Custom Field Name" /]
15
+ [s2Get custom_field="my_custom_field_name" /]
16
+ [s2Get custom_field="any other WP_User property" /]
17
+
18
+ You can also pull details from the meta table.
19
+ [s2Get user_option="s2member_custom" /]
20
+ [s2Get user_option="s2member_subscr_id" /]
21
+ [s2Get user_option="s2member_last_payment_time" /]
22
+ [s2Get user_option="s2member_auto_eot_time" /]
23
+ [s2Get user_option="any other meta_key" /]
includes/menu-pages/code-samples/current-user-first-name.php CHANGED
@@ -1,3 +1,7 @@
1
  <?php echo S2MEMBER_CURRENT_USER_FIRST_NAME; ?>
2
  This may output something like: John
3
- ( or whatever their first name is )
 
 
 
 
1
  <?php echo S2MEMBER_CURRENT_USER_FIRST_NAME; ?>
2
  This may output something like: John
3
+ ( or whatever their first name is )
4
+
5
+ ---- s2member Shortcode Equivalent ----
6
+
7
+ [s2Get constant="S2MEMBER_CURRENT_USER_FIRST_NAME" /]
includes/menu-pages/code-samples/current-user-id.php CHANGED
@@ -1,3 +1,7 @@
1
  <?php echo S2MEMBER_CURRENT_USER_ID; ?>
2
  This may output something like: 5547
3
- ( or whatever their user ID# is )
 
 
 
 
1
  <?php echo S2MEMBER_CURRENT_USER_ID; ?>
2
  This may output something like: 5547
3
+ ( or whatever their user ID# is )
4
+
5
+ ---- s2member Shortcode Equivalent ----
6
+
7
+ [s2Get constant="S2MEMBER_CURRENT_USER_ID" /]
includes/menu-pages/code-samples/current-user-ip.php CHANGED
@@ -1,3 +1,7 @@
1
  <?php echo S2MEMBER_CURRENT_USER_IP; ?>
2
  This may output something like: 123.456.789.111
3
- ( or whatever the current user's IP address happens to be )
 
 
 
 
1
  <?php echo S2MEMBER_CURRENT_USER_IP; ?>
2
  This may output something like: 123.456.789.111
3
+ ( or whatever the current user's IP address happens to be )
4
+
5
+ ---- s2member Shortcode Equivalent ----
6
+
7
+ [s2Get constant="S2MEMBER_CURRENT_USER_IP" /]
includes/menu-pages/code-samples/current-user-is-logged-in-as-member.php CHANGED
@@ -1,3 +1,9 @@
1
  <?php if (S2MEMBER_CURRENT_USER_IS_LOGGED_IN_AS_MEMBER){ ?>
2
  A Member is logged in, with an Access Level >= 1.
3
- <?php } ?>
 
 
 
 
 
 
1
  <?php if (S2MEMBER_CURRENT_USER_IS_LOGGED_IN_AS_MEMBER){ ?>
2
  A Member is logged in, with an Access Level >= 1.
3
+ <?php } ?>
4
+
5
+ ---- s2member Shortcode Equivalent ----
6
+
7
+ [s2All is_user_logged_in="yes" current_user_can="access_s2member_level1"]
8
+ content goes here
9
+ [/s2All]
includes/menu-pages/code-samples/current-user-is-logged-in.php CHANGED
@@ -1,3 +1,9 @@
1
  <?php if (S2MEMBER_CURRENT_USER_IS_LOGGED_IN){ ?>
2
  A User/Member is logged in, with an Access Level >= 0.
3
- <?php } ?>
 
 
 
 
 
 
1
  <?php if (S2MEMBER_CURRENT_USER_IS_LOGGED_IN){ ?>
2
  A User/Member is logged in, with an Access Level >= 0.
3
+ <?php } ?>
4
+
5
+ ---- s2member Shortcode Equivalent ----
6
+
7
+ [s2All is_user_logged_in="yes"]
8
+ content goes here
9
+ [/s2All]
includes/menu-pages/code-samples/current-user-is-specific-content.php ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php if (current_user_is("s2member_level4")){ ?>
2
+ Some premium content for Level 4 Members.
3
+ <?php } else if (current_user_is("s2member_level3")){ ?>
4
+ Some premium content for Level 3 Members.
5
+ <?php } else if (current_user_is("s2member_level2")){ ?>
6
+ Some premium content for Level 2 Members.
7
+ <?php } else if (current_user_is("s2member_level1")){ ?>
8
+ Some premium content for Level 1 Members.
9
+ <?php } else if (current_user_is("s2member_level0")){ ?>
10
+ Some content for Free Subscribers.
11
+ <?php } else { ?>
12
+ Some public content.
13
+ <?php } ?>
includes/menu-pages/code-samples/current-user-last-name.php CHANGED
@@ -1,3 +1,7 @@
1
  <?php echo S2MEMBER_CURRENT_USER_LAST_NAME; ?>
2
  This may output something like: Smith
3
- ( or whatever their last name is )
 
 
 
 
1
  <?php echo S2MEMBER_CURRENT_USER_LAST_NAME; ?>
2
  This may output something like: Smith
3
+ ( or whatever their last name is )
4
+
5
+ ---- s2member Shortcode Equivalent ----
6
+
7
+ [s2Get constant="S2MEMBER_CURRENT_USER_LAST_NAME" /]
includes/menu-pages/code-samples/current-user-login.php CHANGED
@@ -1,3 +1,7 @@
1
  <?php echo S2MEMBER_CURRENT_USER_LOGIN; ?>
2
  This may output something like: johnsmith22
3
- ( or whatever their login/username is )
 
 
 
 
1
  <?php echo S2MEMBER_CURRENT_USER_LOGIN; ?>
2
  This may output something like: johnsmith22
3
+ ( or whatever their login/username is )
4
+
5
+ ---- s2member Shortcode Equivalent ----
6
+
7
+ [s2Get constant="S2MEMBER_CURRENT_USER_LOGIN" /]
includes/menu-pages/code-samples/current-user-profile-modification-page-url-1.php CHANGED
@@ -1 +1,5 @@
1
- <a href="<?php echo S2MEMBER_CURRENT_USER_PROFILE_MODIFICATION_PAGE_URL; ?>">Modify Profile</a>
 
 
 
 
1
+ <a href="<?php echo S2MEMBER_CURRENT_USER_PROFILE_MODIFICATION_PAGE_URL; ?>">Modify Profile</a>
2
+
3
+ ---- s2member Shortcode Equivalent ----
4
+
5
+ [s2Get constant="S2MEMBER_CURRENT_USER_PROFILE_MODIFICATION_PAGE_URL" /]
includes/menu-pages/code-samples/current-user-registration-days-dripping.php CHANGED
@@ -14,4 +14,10 @@
14
  Drip content to Members who are more than 90 days old.
15
  <?php } ?>
16
 
17
- <?php } ?>
 
 
 
 
 
 
14
  Drip content to Members who are more than 90 days old.
15
  <?php } ?>
16
 
17
+ <?php } ?>
18
+
19
+ ---- s2member Shortcode Equivalent ----
20
+
21
+ [s2Get constant="S2MEMBER_CURRENT_USER_REGISTRATION_DAYS" /]
22
+
23
+ There is NO Shortcode equivalent for this logic yet. Coming soon.
includes/menu-pages/code-samples/current-user-registration-days.php CHANGED
@@ -19,4 +19,10 @@ Here's how you Drip Content. The longer they've been a Member, the more they get
19
  Drip content to Members who are more than 90 days old.
20
  <?php } ?>
21
 
22
- <?php } ?>
 
 
 
 
 
 
19
  Drip content to Members who are more than 90 days old.
20
  <?php } ?>
21
 
22
+ <?php } ?>
23
+
24
+ ---- s2member Shortcode Equivalent ----
25
+
26
+ [s2Get constant="S2MEMBER_CURRENT_USER_REGISTRATION_DAYS" /]
27
+
28
+ There is NO Shortcode equivalent for this logic yet. Coming soon.
includes/menu-pages/code-samples/current-user-registration-time.php CHANGED
@@ -1,3 +1,7 @@
1
  <?php echo S2MEMBER_CURRENT_USER_REGISTRATION_TIME; ?>
2
  This may output something like: 1270537981
3
- ( this is a Unix timestamp, which is based on seconds )
 
 
 
 
1
  <?php echo S2MEMBER_CURRENT_USER_REGISTRATION_TIME; ?>
2
  This may output something like: 1270537981
3
+ ( this is a Unix timestamp, which is based on seconds )
4
+
5
+ ---- s2member Shortcode Equivalent ----
6
+
7
+ [s2Get constant="S2MEMBER_CURRENT_USER_REGISTRATION_TIME" /]
includes/menu-pages/code-samples/current-user-subscr-id.php CHANGED
@@ -2,4 +2,8 @@
2
  This may output something like: S-82234JD0923423
3
  ( this is the PayPal Subscription ID associated with their account )
4
  ( if the User is a Free Subscriber, this is their Free Subscriber ID )
5
- ( for Lifetime subscriptions sold through Buy It Now buttons, this will hold the PayPal Transaction ID associated with their purchase )
 
 
 
 
2
  This may output something like: S-82234JD0923423
3
  ( this is the PayPal Subscription ID associated with their account )
4
  ( if the User is a Free Subscriber, this is their Free Subscriber ID )
5
+ ( for Lifetime subscriptions sold through Buy It Now buttons, this will hold the PayPal Transaction ID associated with their purchase )
6
+
7
+ ---- s2member Shortcode Equivalent ----
8
+
9
+ [s2Get constant="S2MEMBER_CURRENT_USER_SUBSCR_ID" /]
includes/menu-pages/code-samples/current-user-value-for-pp-on0-os0.php CHANGED
@@ -1,4 +1,9 @@
1
  <!-- Identifies/Updates An Existing Member After Checkout -->
2
  <input type="hidden" name="on0" value="<?php echo S2MEMBER_CURRENT_USER_VALUE_FOR_PP_ON0; ?>" />
3
  <input type="hidden" name="os0" value="<?php echo S2MEMBER_CURRENT_USER_VALUE_FOR_PP_OS0; ?>" />
4
- <input type="hidden" name="modify" value="1" />
 
 
 
 
 
1
  <!-- Identifies/Updates An Existing Member After Checkout -->
2
  <input type="hidden" name="on0" value="<?php echo S2MEMBER_CURRENT_USER_VALUE_FOR_PP_ON0; ?>" />
3
  <input type="hidden" name="os0" value="<?php echo S2MEMBER_CURRENT_USER_VALUE_FOR_PP_OS0; ?>" />
4
+ <input type="hidden" name="modify" value="1" />
5
+
6
+ ---- s2member Shortcode Equivalents ----
7
+
8
+ [s2Get constant="S2MEMBER_CURRENT_USER_VALUE_FOR_PP_ON0" /]
9
+ [s2Get constant="S2MEMBER_CURRENT_USER_VALUE_FOR_PP_OS0" /]
includes/menu-pages/code-samples/file-download-inline-extensions.php CHANGED
@@ -1,3 +1,7 @@
1
  <?php echo S2MEMBER_FILE_DOWNLOAD_INLINE_EXTENSIONS; ?>
2
  This may output something like: pdf,jpg,jpeg,jpe,png
3
- ( s2Member will display these extensions inline )
 
 
 
 
1
  <?php echo S2MEMBER_FILE_DOWNLOAD_INLINE_EXTENSIONS; ?>
2
  This may output something like: pdf,jpg,jpeg,jpe,png
3
+ ( s2Member will display these extensions inline )
4
+
5
+ ---- s2member Shortcode Equivalent ----
6
+
7
+ [s2Get constant="S2MEMBER_FILE_DOWNLOAD_INLINE_EXTENSIONS" /]
includes/menu-pages/code-samples/file-download-limit-exceeded-page-url.php CHANGED
@@ -1,3 +1,7 @@
1
  <?php if (S2MEMBER_CURRENT_USER_DOWNLOADS_CURRENTLY > S2MEMBER_CURRENT_USER_DOWNLOADS_ALLOWED){ ?>
2
  Limit Exceeded, <a href="<?php echo S2MEMBER_FILE_DOWNLOAD_LIMIT_EXCEEDED_PAGE_URL; ?>">click here for details</a>.
3
- <?php } ?>
 
 
 
 
1
  <?php if (S2MEMBER_CURRENT_USER_DOWNLOADS_CURRENTLY > S2MEMBER_CURRENT_USER_DOWNLOADS_ALLOWED){ ?>
2
  Limit Exceeded, <a href="<?php echo S2MEMBER_FILE_DOWNLOAD_LIMIT_EXCEEDED_PAGE_URL; ?>">click here for details</a>.
3
+ <?php } ?>
4
+
5
+ ---- s2member Shortcode Equivalent ----
6
+
7
+ [s2Get constant="S2MEMBER_FILE_DOWNLOAD_LIMIT_EXCEEDED_PAGE_URL" /]
includes/menu-pages/code-samples/level0-file-downloads-allowed-days.php CHANGED
@@ -1,3 +1,7 @@
1
  Level #0 Users are allowed to download
2
  <?php echo S2MEMBER_LEVEL0_FILE_DOWNLOADS_ALLOWED; ?> files
3
- every <?php S2MEMBER_LEVEL0_FILE_DOWNLOADS_ALLOWED_DAYS; ?> days.
 
 
 
 
1
  Level #0 Users are allowed to download
2
  <?php echo S2MEMBER_LEVEL0_FILE_DOWNLOADS_ALLOWED; ?> files
3
+ every <?php S2MEMBER_LEVEL0_FILE_DOWNLOADS_ALLOWED_DAYS; ?> days.
4
+
5
+ ---- s2member Shortcode Equivalent ----
6
+
7
+ [s2Get constant="S2MEMBER_LEVEL0_FILE_DOWNLOADS_ALLOWED_DAYS" /]
includes/menu-pages/code-samples/level0-file-downloads-allowed.php CHANGED
@@ -1,3 +1,7 @@
1
  Level #0 Users are allowed to download
2
  <?php echo S2MEMBER_LEVEL0_FILE_DOWNLOADS_ALLOWED; ?> files
3
- every <?php S2MEMBER_LEVEL0_FILE_DOWNLOADS_ALLOWED_DAYS; ?> days.
 
 
 
 
1
  Level #0 Users are allowed to download
2
  <?php echo S2MEMBER_LEVEL0_FILE_DOWNLOADS_ALLOWED; ?> files
3
+ every <?php S2MEMBER_LEVEL0_FILE_DOWNLOADS_ALLOWED_DAYS; ?> days.
4
+
5
+ ---- s2member Shortcode Equivalent ----
6
+
7
+ [s2Get constant="S2MEMBER_LEVEL0_FILE_DOWNLOADS_ALLOWED" /]
includes/menu-pages/code-samples/level0-label.php CHANGED
@@ -1,3 +1,7 @@
1
  <?php echo S2MEMBER_LEVEL0_LABEL; ?>
2
  This may output something like: Free
3
- ( or whatever Label you've configured for Level #0 )
 
 
 
 
1
  <?php echo S2MEMBER_LEVEL0_LABEL; ?>
2
  This may output something like: Free
3
+ ( or whatever Label you've configured for Level #0 )
4
+
5
+ ---- s2member Shortcode Equivalent ----
6
+
7
+ [s2Get constant="S2MEMBER_LEVEL0_LABEL" /]
includes/menu-pages/code-samples/level1-file-downloads-allowed-days.php CHANGED
@@ -1,3 +1,7 @@
1
  Level #1 Members are allowed to download
2
  <?php echo S2MEMBER_LEVEL1_FILE_DOWNLOADS_ALLOWED; ?> files
3
- every <?php S2MEMBER_LEVEL1_FILE_DOWNLOADS_ALLOWED_DAYS; ?> days.
 
 
 
 
1
  Level #1 Members are allowed to download
2
  <?php echo S2MEMBER_LEVEL1_FILE_DOWNLOADS_ALLOWED; ?> files
3
+ every <?php S2MEMBER_LEVEL1_FILE_DOWNLOADS_ALLOWED_DAYS; ?> days.
4
+
5
+ ---- s2member Shortcode Equivalent ----
6
+
7
+ [s2Get constant="S2MEMBER_LEVEL1_FILE_DOWNLOADS_ALLOWED_DAYS" /]
includes/menu-pages/code-samples/level1-file-downloads-allowed.php CHANGED
@@ -1,3 +1,7 @@
1
  Level #1 Members are allowed to download
2
  <?php echo S2MEMBER_LEVEL1_FILE_DOWNLOADS_ALLOWED; ?> files
3
- every <?php S2MEMBER_LEVEL1_FILE_DOWNLOADS_ALLOWED_DAYS; ?> days.
 
 
 
 
1
  Level #1 Members are allowed to download
2
  <?php echo S2MEMBER_LEVEL1_FILE_DOWNLOADS_ALLOWED; ?> files
3
+ every <?php S2MEMBER_LEVEL1_FILE_DOWNLOADS_ALLOWED_DAYS; ?> days.
4
+
5
+ ---- s2member Shortcode Equivalent ----
6
+
7
+ [s2Get constant="S2MEMBER_LEVEL1_FILE_DOWNLOADS_ALLOWED" /]
includes/menu-pages/code-samples/level1-label.php CHANGED
@@ -1,3 +1,7 @@
1
  <?php echo S2MEMBER_LEVEL1_LABEL; ?>
2
  This may output something like: Bronze Membership
3
- ( or whatever Label you've configured for Level #1 )
 
 
 
 
1
  <?php echo S2MEMBER_LEVEL1_LABEL; ?>
2
  This may output something like: Bronze Membership
3
+ ( or whatever Label you've configured for Level #1 )
4
+
5
+ ---- s2member Shortcode Equivalent ----
6
+
7
+ [s2Get constant="S2MEMBER_LEVEL1_LABEL" /]
includes/menu-pages/code-samples/level2-file-downloads-allowed-days.php CHANGED
@@ -1,3 +1,7 @@
1
  Level #2 Members are allowed to download
2
  <?php echo S2MEMBER_LEVEL2_FILE_DOWNLOADS_ALLOWED; ?> files
3
- every <?php S2MEMBER_LEVEL2_FILE_DOWNLOADS_ALLOWED_DAYS; ?> days.
 
 
 
 
1
  Level #2 Members are allowed to download
2
  <?php echo S2MEMBER_LEVEL2_FILE_DOWNLOADS_ALLOWED; ?> files
3
+ every <?php S2MEMBER_LEVEL2_FILE_DOWNLOADS_ALLOWED_DAYS; ?> days.
4
+
5
+ ---- s2member Shortcode Equivalent ----
6
+
7
+ [s2Get constant="S2MEMBER_LEVEL2_FILE_DOWNLOADS_ALLOWED_DAYS" /]
includes/menu-pages/code-samples/level2-file-downloads-allowed.php CHANGED
@@ -1,3 +1,7 @@
1
  Level #2 Members are allowed to download
2
  <?php echo S2MEMBER_LEVEL2_FILE_DOWNLOADS_ALLOWED; ?> files
3
- every <?php S2MEMBER_LEVEL2_FILE_DOWNLOADS_ALLOWED_DAYS; ?> days.
 
 
 
 
1
  Level #2 Members are allowed to download
2
  <?php echo S2MEMBER_LEVEL2_FILE_DOWNLOADS_ALLOWED; ?> files
3
+ every <?php S2MEMBER_LEVEL2_FILE_DOWNLOADS_ALLOWED_DAYS; ?> days.
4
+
5
+ ---- s2member Shortcode Equivalent ----
6
+
7
+ [s2Get constant="S2MEMBER_LEVEL2_FILE_DOWNLOADS_ALLOWED" /]
includes/menu-pages/code-samples/level2-label.php CHANGED
@@ -1,3 +1,7 @@
1
  <?php echo S2MEMBER_LEVEL2_LABEL; ?>
2
  This may output something like: Silver Membership
3
- ( or whatever Label you've configured for Level #2 )
 
 
 
 
1
  <?php echo S2MEMBER_LEVEL2_LABEL; ?>
2
  This may output something like: Silver Membership
3
+ ( or whatever Label you've configured for Level #2 )
4
+
5
+ ---- s2member Shortcode Equivalent ----
6
+
7
+ [s2Get constant="S2MEMBER_LEVEL2_LABEL" /]
includes/menu-pages/code-samples/level3-file-downloads-allowed-days.php CHANGED
@@ -1,3 +1,7 @@
1
  Level #3 Members are allowed to download
2
  <?php echo S2MEMBER_LEVEL3_FILE_DOWNLOADS_ALLOWED; ?> files
3
- every <?php S2MEMBER_LEVEL3_FILE_DOWNLOADS_ALLOWED_DAYS; ?> days.
 
 
 
 
1
  Level #3 Members are allowed to download
2
  <?php echo S2MEMBER_LEVEL3_FILE_DOWNLOADS_ALLOWED; ?> files
3
+ every <?php S2MEMBER_LEVEL3_FILE_DOWNLOADS_ALLOWED_DAYS; ?> days.
4
+
5
+ ---- s2member Shortcode Equivalent ----
6
+
7
+ [s2Get constant="S2MEMBER_LEVEL3_FILE_DOWNLOADS_ALLOWED_DAYS" /]
includes/menu-pages/code-samples/level3-file-downloads-allowed.php CHANGED
@@ -1,3 +1,7 @@
1
  Level #3 Members are allowed to download
2
  <?php echo S2MEMBER_LEVEL3_FILE_DOWNLOADS_ALLOWED; ?> files
3
- every <?php S2MEMBER_LEVEL3_FILE_DOWNLOADS_ALLOWED_DAYS; ?> days.
 
 
 
 
1
  Level #3 Members are allowed to download
2
  <?php echo S2MEMBER_LEVEL3_FILE_DOWNLOADS_ALLOWED; ?> files
3
+ every <?php S2MEMBER_LEVEL3_FILE_DOWNLOADS_ALLOWED_DAYS; ?> days.
4
+
5
+ ---- s2member Shortcode Equivalent ----
6
+
7
+ [s2Get constant="S2MEMBER_LEVEL3_FILE_DOWNLOADS_ALLOWED" /]
includes/menu-pages/code-samples/level3-label.php CHANGED
@@ -1,3 +1,7 @@
1
  <?php echo S2MEMBER_LEVEL3_LABEL; ?>
2
  This may output something like: Gold Membership
3
- ( or whatever Label you've configured for Level #3 )
 
 
 
 
1
  <?php echo S2MEMBER_LEVEL3_LABEL; ?>
2
  This may output something like: Gold Membership
3
+ ( or whatever Label you've configured for Level #3 )
4
+
5
+ ---- s2member Shortcode Equivalent ----
6
+
7
+ [s2Get constant="S2MEMBER_LEVEL3_LABEL" /]
includes/menu-pages/code-samples/level4-file-downloads-allowed-days.php CHANGED
@@ -1,3 +1,7 @@
1
  Level #4 Members are allowed to download
2
  <?php echo S2MEMBER_LEVEL4_FILE_DOWNLOADS_ALLOWED; ?> files
3
- every <?php S2MEMBER_LEVEL4_FILE_DOWNLOADS_ALLOWED_DAYS; ?> days.
 
 
 
 
1
  Level #4 Members are allowed to download
2
  <?php echo S2MEMBER_LEVEL4_FILE_DOWNLOADS_ALLOWED; ?> files
3
+ every <?php S2MEMBER_LEVEL4_FILE_DOWNLOADS_ALLOWED_DAYS; ?> days.
4
+
5
+ ---- s2member Shortcode Equivalent ----
6
+
7
+ [s2Get constant="S2MEMBER_LEVEL4_FILE_DOWNLOADS_ALLOWED_DAYS" /]
includes/menu-pages/code-samples/level4-file-downloads-allowed.php CHANGED
@@ -1,3 +1,7 @@
1
  Level #4 Members are allowed to download
2
  <?php echo S2MEMBER_LEVEL4_FILE_DOWNLOADS_ALLOWED; ?> files
3
- every <?php S2MEMBER_LEVEL4_FILE_DOWNLOADS_ALLOWED_DAYS; ?> days.
 
 
 
 
1
  Level #4 Members are allowed to download
2
  <?php echo S2MEMBER_LEVEL4_FILE_DOWNLOADS_ALLOWED; ?> files
3
+ every <?php S2MEMBER_LEVEL4_FILE_DOWNLOADS_ALLOWED_DAYS; ?> days.
4
+
5
+ ---- s2member Shortcode Equivalent ----
6
+
7
+ [s2Get constant="S2MEMBER_LEVEL4_FILE_DOWNLOADS_ALLOWED" /]
includes/menu-pages/code-samples/level4-label.php CHANGED
@@ -1,3 +1,7 @@
1
  <?php echo S2MEMBER_LEVEL4_LABEL; ?>
2
  This may output something like: Platinum Membership
3
- ( or whatever Label you've configured for Level #4 )
 
 
 
 
1
  <?php echo S2MEMBER_LEVEL4_LABEL; ?>
2
  This may output something like: Platinum Membership
3
+ ( or whatever Label you've configured for Level #4 )
4
+
5
+ ---- s2member Shortcode Equivalent ----
6
+
7
+ [s2Get constant="S2MEMBER_LEVEL4_LABEL" /]
includes/menu-pages/code-samples/login-page-url.php CHANGED
@@ -1,4 +1,8 @@
1
  <?php if (!S2MEMBER_CURRENT_USER_IS_LOGGED_IN){ ?>
2
  <a href="<?php echo S2MEMBER_MEMBERSHIP_OPTIONS_PAGE_URL; ?>">Please Signup</a>
3
  | <a href="<?php echo S2MEMBER_LOGIN_PAGE_URL; ?>">Or Login</a>
4
- <?php } ?>
 
 
 
 
1
  <?php if (!S2MEMBER_CURRENT_USER_IS_LOGGED_IN){ ?>
2
  <a href="<?php echo S2MEMBER_MEMBERSHIP_OPTIONS_PAGE_URL; ?>">Please Signup</a>
3
  | <a href="<?php echo S2MEMBER_LOGIN_PAGE_URL; ?>">Or Login</a>
4
+ <?php } ?>
5
+
6
+ ---- s2member Shortcode Equivalent ----
7
+
8
+ [s2Get constant="S2MEMBER_LOGIN_PAGE_URL" /]
includes/menu-pages/code-samples/login-welcome-page-url.php CHANGED
@@ -1,4 +1,8 @@
1
  <?php if (S2MEMBER_CURRENT_USER_IS_LOGGED_IN){ ?>
2
  <a href="<?php echo S2MEMBER_LOGIN_WELCOME_PAGE_URL; ?>">My Account</a>
3
  | <a href="<?php echo S2MEMBER_LOGOUT_PAGE_URL; ?>">Logout</a>
4
- <?php } ?>
 
 
 
 
1
  <?php if (S2MEMBER_CURRENT_USER_IS_LOGGED_IN){ ?>
2
  <a href="<?php echo S2MEMBER_LOGIN_WELCOME_PAGE_URL; ?>">My Account</a>
3
  | <a href="<?php echo S2MEMBER_LOGOUT_PAGE_URL; ?>">Logout</a>
4
+ <?php } ?>
5
+
6
+ ---- s2member Shortcode Equivalent ----
7
+
8
+ [s2Get constant="S2MEMBER_LOGIN_WELCOME_PAGE_URL" /]
includes/menu-pages/code-samples/logout-page-url.php CHANGED
@@ -1,4 +1,8 @@
1
  <?php if (S2MEMBER_CURRENT_USER_IS_LOGGED_IN){ ?>
2
  <a href="<?php echo S2MEMBER_LOGIN_WELCOME_PAGE_URL; ?>">My Account</a>
3
  | <a href="<?php echo S2MEMBER_LOGOUT_PAGE_URL; ?>">Logout</a>
4
- <?php } ?>
 
 
 
 
1
  <?php if (S2MEMBER_CURRENT_USER_IS_LOGGED_IN){ ?>
2
  <a href="<?php echo S2MEMBER_LOGIN_WELCOME_PAGE_URL; ?>">My Account</a>
3
  | <a href="<?php echo S2MEMBER_LOGOUT_PAGE_URL; ?>">Logout</a>
4
+ <?php } ?>
5
+
6
+ ---- s2member Shortcode Equivalent ----
7
+
8
+ [s2Get constant="S2MEMBER_LOGOUT_PAGE_URL" /]
includes/menu-pages/code-samples/membership-options-page-url.php CHANGED
@@ -1,4 +1,8 @@
1
  <?php if (!S2MEMBER_CURRENT_USER_IS_LOGGED_IN){ ?>
2
  <a href="<?php echo S2MEMBER_MEMBERSHIP_OPTIONS_PAGE_URL; ?>">Please Signup</a>
3
  | <a href="<?php echo S2MEMBER_LOGIN_PAGE_URL; ?>">Or Login</a>
4
- <?php } ?>
 
 
 
 
1
  <?php if (!S2MEMBER_CURRENT_USER_IS_LOGGED_IN){ ?>
2
  <a href="<?php echo S2MEMBER_MEMBERSHIP_OPTIONS_PAGE_URL; ?>">Please Signup</a>
3
  | <a href="<?php echo S2MEMBER_LOGIN_PAGE_URL; ?>">Or Login</a>
4
+ <?php } ?>
5
+
6
+ ---- s2member Shortcode Equivalent ----
7
+
8
+ [s2Get constant="S2MEMBER_MEMBERSHIP_OPTIONS_PAGE_URL" /]
includes/menu-pages/code-samples/paypal-business.php CHANGED
@@ -1,3 +1,7 @@
1
  <?php echo S2MEMBER_PAYPAL_BUSINESS; ?>
2
  This may output something like: paypal@example.com
3
- ( or whatever you have configured as your paypal email address )
 
 
 
 
1
  <?php echo S2MEMBER_PAYPAL_BUSINESS; ?>
2
  This may output something like: paypal@example.com
3
+ ( or whatever you have configured as your paypal email address )
4
+
5
+ ---- s2member Shortcode Equivalent ----
6
+
7
+ [s2Get constant="S2MEMBER_PAYPAL_BUSINESS" /]
includes/menu-pages/code-samples/paypal-endpoint.php CHANGED
@@ -1,3 +1,7 @@
1
  <?php echo S2MEMBER_PAYPAL_ENDPOINT; ?>
2
  This will output the paypal endpoint domain: www.paypal.com
3
- ( if sandbox testing is enabled, it will output www.sandbox.paypal.com )
 
 
 
 
1
  <?php echo S2MEMBER_PAYPAL_ENDPOINT; ?>
2
  This will output the paypal endpoint domain: www.paypal.com
3
+ ( if sandbox testing is enabled, it will output www.sandbox.paypal.com )
4
+
5
+ ---- s2member Shortcode Equivalent ----
6
+
7
+ [s2Get constant="S2MEMBER_PAYPAL_ENDPOINT" /]
includes/menu-pages/code-samples/paypal-notify-url.php CHANGED
@@ -1,3 +1,7 @@
1
  <?php echo S2MEMBER_PAYPAL_NOTIFY_URL; ?>
2
  This will output something like: http://www.example.com/?s2member_paypal_notify=1
3
- ( this is used silently behind the scenes to communicate back and forth with PayPal )
 
 
 
 
1
  <?php echo S2MEMBER_PAYPAL_NOTIFY_URL; ?>
2
  This will output something like: http://www.example.com/?s2member_paypal_notify=1
3
+ ( this is used silently behind the scenes to communicate back and forth with PayPal )
4
+
5
+ ---- s2member Shortcode Equivalent ----
6
+
7
+ [s2Get constant="S2MEMBER_PAYPAL_NOTIFY_URL" /]
includes/menu-pages/code-samples/paypal-return-url.php CHANGED
@@ -1,3 +1,7 @@
1
  <?php echo S2MEMBER_PAYPAL_RETURN_URL; ?>
2
  This will output something like: http://www.example.com/?s2member_paypal_return=1
3
- ( this is used as the Signup Confirmation Page, and also handles PDT/Auto-Return )
 
 
 
 
1
  <?php echo S2MEMBER_PAYPAL_RETURN_URL; ?>
2
  This will output something like: http://www.example.com/?s2member_paypal_return=1
3
+ ( this is used as the Signup Confirmation Page, and also handles PDT/Auto-Return )
4
+
5
+ ---- s2member Shortcode Equivalent ----
6
+
7
+ [s2Get constant="S2MEMBER_PAYPAL_RETURN_URL" /]
includes/menu-pages/code-samples/reg-email-from-email.php CHANGED
@@ -1,3 +1,7 @@
1
  <?php echo S2MEMBER_REG_EMAIL_FROM_EMAIL; ?>
2
  This may output something like: support@example.com
3
- ( or whatever you have configured as your From: email )
 
 
 
 
1
  <?php echo S2MEMBER_REG_EMAIL_FROM_EMAIL; ?>
2
  This may output something like: support@example.com
3
+ ( or whatever you have configured as your From: email )
4
+
5
+ ---- s2member Shortcode Equivalent ----
6
+
7
+ [s2Get constant="S2MEMBER_REG_EMAIL_FROM_EMAIL" /]
includes/menu-pages/code-samples/reg-email-from-name.php CHANGED
@@ -1,3 +1,7 @@
1
  <?php echo S2MEMBER_REG_EMAIL_FROM_NAME; ?>
2
  This may output something like: Member Support
3
- ( or whatever you have configured as your From: name )
 
 
 
 
1
  <?php echo S2MEMBER_REG_EMAIL_FROM_NAME; ?>
2
  This may output something like: Member Support
3
+ ( or whatever you have configured as your From: name )
4
+
5
+ ---- s2member Shortcode Equivalent ----
6
+
7
+ [s2Get constant="S2MEMBER_REG_EMAIL_FROM_NAME" /]
includes/menu-pages/code-samples/s2-conditional-supplements-1.php ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
1
+ <?php if (current_user_is("s2member_level1")){ ?>
2
+ Content for Members at exactly Level# 1.
3
+ <?php } else if(current_user_is_not("s2member_level4")) { ?>
4
+ Some content for those who are NOT at Level #4.
5
+ <?php } else if(is_user_not_logged_in()) { ?>
6
+ Some public content.
7
+ <?php } ?>
includes/menu-pages/code-samples/s2-conditional-supplements-2.php ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
1
+ <?php if (current_user_cannot("access_s2member_level1")){ ?>
2
+ Content for Members who CANNOT access Level #1 on this Blog.
3
+ <?php } else if(current_user_cannot_for_blog(24, "access_s2member_level1")) { ?>
4
+ Content for Members who CANNOT access Level #1 on Blog ID# 24. ( i.e. Multisite Networking )
5
+ <?php } else if(is_user_not_logged_in()) { ?>
6
+ Some public content.
7
+ <?php } ?>
includes/menu-pages/code-samples/s2-conditional-supplements-3.php ADDED
@@ -0,0 +1,18 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php if(current_user_cannot("access_s2member_level4") && (current_user_can("access_s2member_level2") || current_user_can_for_blog(24, "access_s2member_level2"))) { ?>
2
+
3
+ This Member CANNOT access Level #4, but...
4
+ they CAN access Level #2 on this Blog, OR (||) on Blog ID# 24. ( i.e. Multisite Networking )
5
+
6
+ <?php if(current_user_can("access_s2member_ccap_free_gift")){ ?>
7
+ Also display free gift here. This is a Custom Capability check, using a nested Conditional.
8
+ <?php } ?>
9
+
10
+ <?php } else if(current_user_can("access_s2member_level1") || current_user_can_for_blog(24, "access_s2member_level1")) { ?>
11
+
12
+ Content for Members who can access Level #1 on this Blog, OR (||) on Blog ID# 24. ( i.e. Multisite Networking )
13
+
14
+ <?php } else if(is_user_not_logged_in()) { ?>
15
+
16
+ Some public content.
17
+
18
+ <?php } ?>
includes/menu-pages/code-samples/sc-current-user-can-full-access.php ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
1
+ [s2All current_user_can="access_s2member_level1"]
2
+ Some content for Members who are logged in with an s2Member Level >= 1.
3
+ [/s2All]
4
+
5
+ [s2All current_user_cannot="access_s2member_level1"]
6
+ Some public content.
7
+ [/s2All]
includes/menu-pages/code-samples/sc-current-user-is-specific-content.php ADDED
@@ -0,0 +1,23 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ [s2All current_user_is="s2member_level4"]
2
+ Some premium content for Level 4 Members.
3
+ [/s2All]
4
+
5
+ [s2All current_user_is="s2member_level3"]
6
+ Some premium content for Level 3 Members.
7
+ [/s2All]
8
+
9
+ [s2All current_user_is="s2member_level2"]
10
+ Some premium content for Level 2 Members.
11
+ [/s2All]
12
+
13
+ [s2All current_user_is="s2member_level1"]
14
+ Some premium content for Level 1 Members.
15
+ [/s2All]
16
+
17
+ [s2All current_user_is="s2member_level0"]
18
+ Some content for Free Subscribers.
19
+ [/s2All]
20
+
21
+ [s2All current_user_cannot="access_s2member_level0"]
22
+ Some public content.
23
+ [/s2All]
includes/menu-pages/code-samples/sc-is-user-logged-in.php ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
1
+ [s2All is_user_logged_in="yes"]
2
+ Content for anyone that is logged in, regardless of their Membership Level.
3
+ [/s2All]
4
+
5
+ [s2All is_user_logged_in="no"]
6
+ Some public content. They're NOT logged in.
7
+ [/s2All]
includes/menu-pages/code-samples/sc-s2-conditional-supplements-1.php ADDED
@@ -0,0 +1,28 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ [s2All current_user_is="s2member_level1"]
2
+ Content for Members at exactly Level# 1, on this Blog.
3
+ [/s2All]
4
+
5
+ [s2Any current_user_is="s2member_level2" current_user_is_for_blog="24,s2member_level2"]
6
+
7
+ They are either a Level #2 Member on this Blog,
8
+ OR ... they're at Level# 2 on Blog ID# 24 ( i.e. Multisite Networking )
9
+
10
+ * Note the use of `s2Any` here. True if ANY/either condition is met.
11
+
12
+ [/s2Any]
13
+
14
+ [s2Any current_user_is="s2member_level3" current_user_is="s2member_level4"]
15
+
16
+ Content for Level #3 - and/or - Level #4 Members. Either/or.
17
+
18
+ Hi there [s2Get constant="S2MEMBER_CURRENT_USER_DISPLAY_NAME" /].
19
+ You have a [s2Get constant="S2MEMBER_CURRENT_USER_ACCESS_LABEL" /] Membership.
20
+
21
+ ^ This uses the s2Get Shortcode to retrive the value of s2Member API Constants.
22
+ These are also documented under: `s2Member -> API Scripting`.
23
+
24
+ So, this might come out to something like:
25
+ `Hi there John.
26
+ You have a Gold Membership.`
27
+
28
+ [/s2Any]
includes/menu-pages/code-samples/sc-s2-conditional-supplements-2.php ADDED
@@ -0,0 +1,34 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ [s2All current_user_can="access_s2member_ccap_free_gift"]
2
+ Display free gift here. This Member has access to a Custom Capability that supplies a free gift.
3
+ [/s2All]
4
+
5
+ [s2All current_user_cannot="access_s2member_level4"]
6
+
7
+ Content for someone who does NOT have Level #4 access.
8
+ Possibly an Upgrade Button here.
9
+
10
+ Nested PayPal Form/Button Shortcodes ARE fine.
11
+ [s2Member-PayPal-Button level="4" ra="49.95" /]
12
+
13
+ [/s2All]
14
+
15
+ [s2All current_user_is="administrator"]
16
+ Content specifically for a WordPress® Administrator.
17
+ [/s2All]
18
+
19
+ [s2All current_user_is="editor"]
20
+ Content specifically for a WordPress® Editor.
21
+ [/s2All]
22
+
23
+ [s2All current_user_is="author"]
24
+ Content specifically for a WordPress® Author.
25
+ [/s2All]
26
+
27
+ [s2All current_user_is="contributor"]
28
+ Content specifically for a WordPress® Contributor.
29
+ [/s2All]
30
+
31
+ [s2All current_user_is="subscriber"]
32
+ Content specifically for a WordPress® Subscriber.
33
+ ( aka: s2member_level0 )
34
+ [/s2All]
includes/menu-pages/code-samples/sc-s2-conditional-supplements-3.php ADDED
@@ -0,0 +1,31 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ [s2All current_user_cannot="access_s2member_level4" current_user_can="access_s2member_level2"]
2
+
3
+ This Member CANNOT access Level #4,
4
+ but... they CAN access Level #2.
5
+
6
+ [_s2All current_user_can="access_s2member_ccap_free_gift"]
7
+
8
+ Display free gift here. This is a Custom Capability check, using a nested Conditional.
9
+ Notice that NESTED Conditionals require a preceding underscore ( i.e. _s2All ).
10
+ You can go up to three levels deep ( ___s2All ).
11
+
12
+ Nested PayPal Form/Button Shortcodes ARE fine too.
13
+ However, you do NOT need a preceding underscore on Form/Button codes. Or any other Shortcode for that matter.
14
+ You ONLY need the preceding underscore on _s2All _s2Any Conditionals that are being nested into each other.
15
+
16
+ ( Hi [s2Get constant="S2MEMBER_CURRENT_USER_DISPLAY_NAME" /], upgrade now to Level #4! )
17
+ [s2Member-PayPal-Button level="4" ra="49.95" ... /]
18
+ ~ see, this will work just fine.
19
+
20
+ [/_s2All]
21
+
22
+ [/s2All]
23
+
24
+ [s2All current_user_cannot="access_s2member_level4" current_user_cannot="access_s2member_level3" current_user_cannot="access_s2member_level2" current_user_can="access_s2member_level1"]
25
+ Content for Members who can ONLY access Level #1 on this Blog.
26
+ [/s2All]
27
+
28
+ [s2All current_user_is="s2member_level1"]
29
+ Content for Members who can ONLY access Level #1 on this Blog.
30
+ ~ Same thing, only this is MUCH simpler, less typing.
31
+ [/s2All]
includes/menu-pages/code-samples/version.php CHANGED
@@ -1,4 +1,8 @@
1
  <?php echo S2MEMBER_VERSION; ?>
2
  This may output something like: 3.0.x
3
  ( or whatever the current version number is )
4
- Use PHP's version_compare() function to test this.
 
 
 
 
1
  <?php echo S2MEMBER_VERSION; ?>
2
  This may output something like: 3.0.x
3
  ( or whatever the current version number is )
4
+ Use PHP's version_compare() function to test this.
5
+
6
+ ---- s2member Shortcode Equivalent ----
7
+
8
+ [s2Get constant="S2MEMBER_VERSION" /]
includes/menu-pages/options.inc.php CHANGED
@@ -1268,7 +1268,10 @@ if (apply_filters ("ws_plugin__s2member_during_options_page_during_left_sections
1268
  /**/
1269
  echo '<div class="ws-menu-page-section ws-plugin--s2member-ip-restrictions-section">' . "\n";
1270
  echo '<h3>Unique IP Access Restrictions ( prevents username/link sharing )</h3>' . "\n";
1271
- echo '<p>As with any Membership system, it is possible for one Member to signup, and then share their Username with someone else; or even post it online for the whole world to see. This is known as Link Sharing ( aka: Username Sharing ). It is not likely that you\'ll be attacked in this way, but it\'s still a good idea to protect your system; just in case somebody tries this. s2Member\'s IP Restrictions, work for both Membership Level Access ( account logins ), and also for Specific Post/Page Access. In both cases, the rules are simple. A single Username, and/or Access Link is only valid for a certain number of unique IP addresses. Once that limit is reached, s2Member assumes there has been a security breach. At that time, s2Member will place a temporary ban ( preventing access ) to a Specific Post/Page, or to an account associated with a particular Username. This temporary ban, will ONLY affect the offending Link and/or Username associated with the security breach.</p>' . "\n";
 
 
 
1272
  do_action ("ws_plugin__s2member_during_options_page_during_left_sections_during_ip_restrictions", get_defined_vars ());
1273
  /**/
1274
  echo '<table class="form-table">' . "\n";
@@ -1286,18 +1289,21 @@ if (apply_filters ("ws_plugin__s2member_during_options_page_during_left_sections
1286
  /**/
1287
  echo '<td>' . "\n";
1288
  echo '<select name="ws_plugin__s2member_max_ip_restriction" id="ws-plugin--s2member-max-ip-restriction">' . "\n";
1289
- echo '<option value="2"' . (($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["max_ip_restriction"] == 2) ? ' selected="selected"' : '') . '>Allow up to 2 different IPs per Customer</option>' . "\n";
1290
- echo '<option value="3"' . (($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["max_ip_restriction"] == 3) ? ' selected="selected"' : '') . '>Allow up to 3 different IPs per Customer</option>' . "\n";
1291
- echo '<option value="4"' . (($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["max_ip_restriction"] == 4) ? ' selected="selected"' : '') . '>Allow up to 4 different IPs per Customer</option>' . "\n";
1292
- echo '<option value="5"' . (($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["max_ip_restriction"] == 5) ? ' selected="selected"' : '') . '>Allow up to 5 different IPs per Customer</option>' . "\n";
1293
- echo '<option value="10"' . (($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["max_ip_restriction"] == 10) ? ' selected="selected"' : '') . '>Allow up to 10 different IPs per Customer</option>' . "\n";
1294
- echo '<option value="20"' . (($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["max_ip_restriction"] == 20) ? ' selected="selected"' : '') . '>Allow up to 20 different IPs per Customer</option>' . "\n";
1295
- echo '<option value="30"' . (($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["max_ip_restriction"] == 30) ? ' selected="selected"' : '') . '>Allow up to 30 different IPs per Customer</option>' . "\n";
1296
- echo '<option value="40"' . (($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["max_ip_restriction"] == 40) ? ' selected="selected"' : '') . '>Allow up to 40 different IPs per Customer</option>' . "\n";
1297
- echo '<option value="50"' . (($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["max_ip_restriction"] == 50) ? ' selected="selected"' : '') . '>Allow up to 50 different IPs per Customer</option>' . "\n";
1298
- echo '<option value="75"' . (($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["max_ip_restriction"] == 75) ? ' selected="selected"' : '') . '>Allow up to 75 different IPs per Customer</option>' . "\n";
1299
- echo '<option value="100"' . (($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["max_ip_restriction"] == 100) ? ' selected="selected"' : '') . '>Allow up to 100 different IPs per Customer</option>' . "\n";
 
 
1300
  echo '</select><br />' . "\n";
 
1301
  echo '</td>' . "\n";
1302
  /**/
1303
  echo '</tr>' . "\n";
@@ -1317,15 +1323,21 @@ if (apply_filters ("ws_plugin__s2member_during_options_page_during_left_sections
1317
  echo '<option value="900"' . (($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["max_ip_restriction_time"] == 900) ? ' selected="selected"' : '') . '>If limit is exceeded ( punish for 15 mins )</option>' . "\n";
1318
  echo '<option value="1800"' . (($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["max_ip_restriction_time"] == 1800) ? ' selected="selected"' : '') . '>If limit is exceeded ( punish for 30 mins )</option>' . "\n";
1319
  echo '<option value="3600"' . (($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["max_ip_restriction_time"] == 3600) ? ' selected="selected"' : '') . '>If limit is exceeded ( punish for 1 hour )</option>' . "\n";
1320
- echo '<option value="7200"' . ((!$GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["max_ip_restriction_time"] == 7200) ? ' selected="selected"' : '') . '>If limit is exceeded ( punish for 2 hours )</option>' . "\n";
1321
- echo '<option value="14400"' . ((!$GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["max_ip_restriction_time"] == 14400) ? ' selected="selected"' : '') . '>If limit is exceeded ( punish for 4 hours )</option>' . "\n";
1322
- echo '<option value="21600"' . ((!$GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["max_ip_restriction_time"] == 21600) ? ' selected="selected"' : '') . '>If limit is exceeded ( punish for 6 hours )</option>' . "\n";
1323
- echo '<option value="28800"' . ((!$GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["max_ip_restriction_time"] == 28800) ? ' selected="selected"' : '') . '>If limit is exceeded ( punish for 8 hours )</option>' . "\n";
1324
- echo '<option value="43200"' . ((!$GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["max_ip_restriction_time"] == 43200) ? ' selected="selected"' : '') . '>If limit is exceeded ( punish for 12 hours )</option>' . "\n";
1325
- echo '<option value="86400"' . ((!$GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["max_ip_restriction_time"] == 86400) ? ' selected="selected"' : '') . '>If limit is exceeded ( punish for 24 hours )</option>' . "\n";
1326
- echo '<option value="172800"' . ((!$GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["max_ip_restriction_time"] == 172800) ? ' selected="selected"' : '') . '>If limit is exceeded ( punish for 2 days )</option>' . "\n";
1327
- echo '<option value="345600"' . ((!$GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["max_ip_restriction_time"] == 345600) ? ' selected="selected"' : '') . '>If limit is exceeded ( punish for 4 days )</option>' . "\n";
1328
- echo '<option value="604800"' . ((!$GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["max_ip_restriction_time"] == 604800) ? ' selected="selected"' : '') . '>If limit is exceeded ( punish for 1 week )</option>' . "\n";
 
 
 
 
 
 
1329
  echo '</select><br />' . "\n";
1330
  echo 'When/if you change this, it will take X amount of time to update; based on your previous configuration.' . "\n";
1331
  echo '</td>' . "\n";
1268
  /**/
1269
  echo '<div class="ws-menu-page-section ws-plugin--s2member-ip-restrictions-section">' . "\n";
1270
  echo '<h3>Unique IP Access Restrictions ( prevents username/link sharing )</h3>' . "\n";
1271
+ echo '<p>As with any Membership system, it is possible for one Member to signup, and then share their Username with someone else; or even post it online for the whole world to see. This is known as Link Sharing ( aka: Username Sharing ). It is NOT likely that you\'ll be attacked in this way, but it\'s still a good idea to protect your system; just in case somebody tries this. s2Member\'s IP Restrictions work for Membership Level Access ( account logins ), Specific Post/Page Access, Registration Links, and other secure Entry Points.</p>' . "\n";
1272
+ echo '<p>In all cases, the rules are simple. A single Username, Access Link, and/or Entry Point ... is only valid for a certain number of unique IP addresses. Once that limit is reached, s2Member assumes there has been a security breach. At that time, s2Member will place a temporary ban ( preventing access ) to a Specific Post/Page, or to an account associated with a particular Username. This temporary ban, will ONLY affect the offending Link and/or Username associated with the security breach. You can fine-tune this behavior, using the options below.</p>' . "\n";
1273
+ echo '<p>This form of IP monitoring, is known as an (Adaptive Concurrency Restriction). We refer to this as "Adaptive", because the concurrency timeouts are increased automatically, based on the number of attempts that MAY take place over time. The default period of 30 days works on 99.9% of all installations. This period is renewed automatically, every time a new attempt is made. This allows s2Member to become more secure; with each attempt from a new location ( commonly associated with link sharing ). In other words, s2Member adapts itself to bad behavior, so it can ALSO crack-down on hacking attempts that may occur over a longer period of time. And without being SO paranoid that a legitimate Customer would have a problem.</p>' . "\n";
1274
+ echo '<p><em>*Note* an empty IP address ( associated with someone browsing anonymously ), is also considered a unique IP address, so it cannot circumvent s2Member\'s security.</em></p>' . "\n";
1275
  do_action ("ws_plugin__s2member_during_options_page_during_left_sections_during_ip_restrictions", get_defined_vars ());
1276
  /**/
1277
  echo '<table class="form-table">' . "\n";
1289
  /**/
1290
  echo '<td>' . "\n";
1291
  echo '<select name="ws_plugin__s2member_max_ip_restriction" id="ws-plugin--s2member-max-ip-restriction">' . "\n";
1292
+ $ws_plugin__s2member_temp_s = apply_filters ("ws_plugin__s2member_ip_restrictions__concurrency_time_per_ip", "30 days");
1293
+ echo '<option value="1"' . (($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["max_ip_restriction"] == 1) ? ' selected="selected"' : '') . '>Allow up to 1 unique IP per Customer ( every ' . $ws_plugin__s2member_temp_s . ' )</option>' . "\n";
1294
+ echo '<option value="2"' . (($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["max_ip_restriction"] == 2) ? ' selected="selected"' : '') . '>Allow up to 2 different IPs per Customer ( every ' . $ws_plugin__s2member_temp_s . ' )</option>' . "\n";
1295
+ echo '<option value="3"' . (($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["max_ip_restriction"] == 3) ? ' selected="selected"' : '') . '>Allow up to 3 different IPs per Customer ( every ' . $ws_plugin__s2member_temp_s . ' )</option>' . "\n";
1296
+ echo '<option value="4"' . (($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["max_ip_restriction"] == 4) ? ' selected="selected"' : '') . '>Allow up to 4 different IPs per Customer ( every ' . $ws_plugin__s2member_temp_s . ' )</option>' . "\n";
1297
+ echo '<option value="5"' . (($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["max_ip_restriction"] == 5) ? ' selected="selected"' : '') . '>Allow up to 5 different IPs per Customer ( every ' . $ws_plugin__s2member_temp_s . ' )</option>' . "\n";
1298
+ echo '<option value="10"' . (($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["max_ip_restriction"] == 10) ? ' selected="selected"' : '') . '>Allow up to 10 different IPs per Customer ( every ' . $ws_plugin__s2member_temp_s . ' )</option>' . "\n";
1299
+ echo '<option value="20"' . (($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["max_ip_restriction"] == 20) ? ' selected="selected"' : '') . '>Allow up to 20 different IPs per Customer ( every ' . $ws_plugin__s2member_temp_s . ' )</option>' . "\n";
1300
+ echo '<option value="30"' . (($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["max_ip_restriction"] == 30) ? ' selected="selected"' : '') . '>Allow up to 30 different IPs per Customer ( every ' . $ws_plugin__s2member_temp_s . ' )</option>' . "\n";
1301
+ echo '<option value="40"' . (($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["max_ip_restriction"] == 40) ? ' selected="selected"' : '') . '>Allow up to 40 different IPs per Customer ( every ' . $ws_plugin__s2member_temp_s . ' )</option>' . "\n";
1302
+ echo '<option value="50"' . (($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["max_ip_restriction"] == 50) ? ' selected="selected"' : '') . '>Allow up to 50 different IPs per Customer ( every ' . $ws_plugin__s2member_temp_s . ' )</option>' . "\n";
1303
+ echo '<option value="75"' . (($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["max_ip_restriction"] == 75) ? ' selected="selected"' : '') . '>Allow up to 75 different IPs per Customer ( every ' . $ws_plugin__s2member_temp_s . ' )</option>' . "\n";
1304
+ echo '<option value="100"' . (($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["max_ip_restriction"] == 100) ? ' selected="selected"' : '') . '>Allow up to 100 different IPs per Customer ( every ' . $ws_plugin__s2member_temp_s . ' )</option>' . "\n";
1305
  echo '</select><br />' . "\n";
1306
+ echo 'The default period of "30 days" could be modified through this WordPress® Filter:<br /><code>ws_plugin__s2member_ip_restrictions__concurrency_time_per_ip</code>' . "\n";
1307
  echo '</td>' . "\n";
1308
  /**/
1309
  echo '</tr>' . "\n";
1323
  echo '<option value="900"' . (($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["max_ip_restriction_time"] == 900) ? ' selected="selected"' : '') . '>If limit is exceeded ( punish for 15 mins )</option>' . "\n";
1324
  echo '<option value="1800"' . (($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["max_ip_restriction_time"] == 1800) ? ' selected="selected"' : '') . '>If limit is exceeded ( punish for 30 mins )</option>' . "\n";
1325
  echo '<option value="3600"' . (($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["max_ip_restriction_time"] == 3600) ? ' selected="selected"' : '') . '>If limit is exceeded ( punish for 1 hour )</option>' . "\n";
1326
+ echo '<option value="7200"' . (($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["max_ip_restriction_time"] == 7200) ? ' selected="selected"' : '') . '>If limit is exceeded ( punish for 2 hours )</option>' . "\n";
1327
+ echo '<option value="14400"' . (($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["max_ip_restriction_time"] == 14400) ? ' selected="selected"' : '') . '>If limit is exceeded ( punish for 4 hours )</option>' . "\n";
1328
+ echo '<option value="21600"' . (($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["max_ip_restriction_time"] == 21600) ? ' selected="selected"' : '') . '>If limit is exceeded ( punish for 6 hours )</option>' . "\n";
1329
+ echo '<option value="28800"' . (($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["max_ip_restriction_time"] == 28800) ? ' selected="selected"' : '') . '>If limit is exceeded ( punish for 8 hours )</option>' . "\n";
1330
+ echo '<option value="43200"' . (($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["max_ip_restriction_time"] == 43200) ? ' selected="selected"' : '') . '>If limit is exceeded ( punish for 12 hours )</option>' . "\n";
1331
+ echo '<option value="86400"' . (($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["max_ip_restriction_time"] == 86400) ? ' selected="selected"' : '') . '>If limit is exceeded ( punish for 24 hours )</option>' . "\n";
1332
+ echo '<option value="172800"' . (($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["max_ip_restriction_time"] == 172800) ? ' selected="selected"' : '') . '>If limit is exceeded ( punish for 2 days )</option>' . "\n";
1333
+ echo '<option value="345600"' . (($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["max_ip_restriction_time"] == 345600) ? ' selected="selected"' : '') . '>If limit is exceeded ( punish for 4 days )</option>' . "\n";
1334
+ echo '<option value="604800"' . (($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["max_ip_restriction_time"] == 604800) ? ' selected="selected"' : '') . '>If limit is exceeded ( punish for 1 week )</option>' . "\n";
1335
+ echo '<option value="1209600"' . (($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["max_ip_restriction_time"] == 1209600) ? ' selected="selected"' : '') . '>If limit is exceeded ( punish for 2 weeks )</option>' . "\n";
1336
+ echo '<option value="2629743"' . (($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["max_ip_restriction_time"] == 2629743) ? ' selected="selected"' : '') . '>If limit is exceeded ( punish for 1 month )</option>' . "\n";
1337
+ echo '<option value="5259487"' . (($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["max_ip_restriction_time"] == 5259487) ? ' selected="selected"' : '') . '>If limit is exceeded ( punish for 2 months )</option>' . "\n";
1338
+ echo '<option value="7889231"' . (($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["max_ip_restriction_time"] == 7889231) ? ' selected="selected"' : '') . '>If limit is exceeded ( punish for 3 months )</option>' . "\n";
1339
+ echo '<option value="15778463"' . (($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["max_ip_restriction_time"] == 15778463) ? ' selected="selected"' : '') . '>If limit is exceeded ( punish for 6 months )</option>' . "\n";
1340
+ echo '<option value="31556926"' . (($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["max_ip_restriction_time"] == 31556926) ? ' selected="selected"' : '') . '>If limit is exceeded ( punish for 1 year )</option>' . "\n";
1341
  echo '</select><br />' . "\n";
1342
  echo 'When/if you change this, it will take X amount of time to update; based on your previous configuration.' . "\n";
1343
  echo '</td>' . "\n";
includes/menu-pages/paypal-ops.inc.php CHANGED
@@ -12,7 +12,7 @@ If not, see: <http://www.gnu.org/licenses/>.
12
  Direct access denial.
13
  */
14
  if (realpath (__FILE__) === realpath ($_SERVER["SCRIPT_FILENAME"]))
15
- exit ("Do not access this file directly.");
16
  /*
17
  PayPal® Options page.
18
  */
@@ -430,6 +430,8 @@ if (apply_filters ("ws_plugin__s2member_during_paypal_ops_page_during_left_secti
430
  echo '<div class="ws-menu-page-section ws-plugin--s2member-eot-behavior-section">' . "\n";
431
  echo '<h3>PayPal® EOT Behavior ( required, please choose )</h3>' . "\n";
432
  echo '<p>EOT = End Of Term. By default, s2Member will demote a paid Member to a Free Subscriber whenever their Subscription term has ended ( i.e. expired ), been cancelled, refunded, charged back to you, etc. s2Member demotes them to a Free Subscriber, so they will no longer have Member Level Access to your site. However, in some cases, you may prefer to have Customer accounts deleted completely, instead of just being demoted. This is where you choose which method works best for your site. If you don\'t want s2Member to take ANY action at all, you can disable s2Member\'s EOT System temporarily, or even completely.</p>' . "\n";
 
 
433
  do_action ("ws_plugin__s2member_during_paypal_ops_page_during_left_sections_during_eot_behavior", get_defined_vars ());
434
  /**/
435
  echo '<p id="ws-plugin--s2member-auto-eot-system-enabled-via-cron"' . (($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["auto_eot_system_enabled"] == 2 && (!function_exists ("wp_cron") || !wp_get_schedule ("ws_plugin__s2member_auto_eot_system__schedule"))) ? '' : ' style="display:none;"') . '>If you\'d like to run s2Member\'s Auto-EOT System through a more traditional Cron Job; instead of through <code>WP-Cron</code>, you will need to configure a Cron Job through your server control panel; provided by your hosting company. Set the Cron Job to run <code>once about every 10 minutes to an hour</code>. You\'ll want to configure an HTTP Cron Job that loads this URL:<br /><code>' . esc_html (add_query_arg ("s2member_auto_eot_system_via_cron", "1", get_bloginfo ("wpurl") . "/")) . '</code></p>' . "\n";
@@ -449,7 +451,7 @@ if (apply_filters ("ws_plugin__s2member_during_paypal_ops_page_during_left_secti
449
  /**/
450
  echo '<td>' . "\n";
451
  echo '<select name="ws_plugin__s2member_auto_eot_system_enabled" id="ws-plugin--s2member-auto-eot-system-enabled">' . "\n";
452
- /* Very advanced conditionals here. If the Auto-EOT System is NOT running, or NOT fully configured, this will indicate that no option is set - as sort of a built-in warning in the UI panel. */
453
  echo (($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["auto_eot_system_enabled"] == 1 && (!function_exists ("wp_cron") || !wp_get_schedule ("ws_plugin__s2member_auto_eot_system__schedule"))) || ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["auto_eot_system_enabled"] == 2 && (function_exists ("wp_cron") && wp_get_schedule ("ws_plugin__s2member_auto_eot_system__schedule"))) || (!$GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["auto_eot_system_enabled"] && (function_exists ("wp_cron") && wp_get_schedule ("ws_plugin__s2member_auto_eot_system__schedule")))) ? '<option value=""></option>' . "\n" : '';
454
  echo '<option value="1"' . (($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["auto_eot_system_enabled"] == 1 && function_exists ("wp_cron") && wp_get_schedule ("ws_plugin__s2member_auto_eot_system__schedule")) ? ' selected="selected"' : '') . '>Yes ( enable the Auto-EOT System through WP-Cron )</option>' . "\n";
455
  echo (!is_multisite () || !ws_plugin__s2member_is_multisite_farm () || is_main_site ()) ? '<option value="2"' . (($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["auto_eot_system_enabled"] == 2 && (!function_exists ("wp_cron") || !wp_get_schedule ("ws_plugin__s2member_auto_eot_system__schedule"))) ? ' selected="selected"' : '') . '>Yes ( but, I\'ll run it with my own Cron Job )</option>' . "\n" : '';
@@ -478,6 +480,28 @@ if (apply_filters ("ws_plugin__s2member_during_paypal_ops_page_during_left_secti
478
  echo '</td>' . "\n";
479
  /**/
480
  echo '</tr>' . "\n";
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
481
  echo '</tbody>' . "\n";
482
  echo '</table>' . "\n";
483
  echo '</div>' . "\n";
12
  Direct access denial.
13
  */
14
  if (realpath (__FILE__) === realpath ($_SERVER["SCRIPT_FILENAME"]))
15
+ exit("Do not access this file directly.");
16
  /*
17
  PayPal® Options page.
18
  */
430
  echo '<div class="ws-menu-page-section ws-plugin--s2member-eot-behavior-section">' . "\n";
431
  echo '<h3>PayPal® EOT Behavior ( required, please choose )</h3>' . "\n";
432
  echo '<p>EOT = End Of Term. By default, s2Member will demote a paid Member to a Free Subscriber whenever their Subscription term has ended ( i.e. expired ), been cancelled, refunded, charged back to you, etc. s2Member demotes them to a Free Subscriber, so they will no longer have Member Level Access to your site. However, in some cases, you may prefer to have Customer accounts deleted completely, instead of just being demoted. This is where you choose which method works best for your site. If you don\'t want s2Member to take ANY action at all, you can disable s2Member\'s EOT System temporarily, or even completely.</p>' . "\n";
433
+ echo '<p>The PayPal® IPN service will notify s2Member whenever a Member\'s payments have been failing, and/or whenever a Member\'s Subscription has expired for any reason. Even refunds &amp; chargeback reversals are supported through the IPN service. If you issue a refund to an unhappy Customer through PayPal®, s2Member will be notified, and the account for that Customer will either be demoted to a Free Subscriber, or deleted automatically ( based on your configuration ). The communication from PayPal® -> s2Member is seamless.</p>' . "\n";
434
+ echo '<p><em><strong>*Some Hairy Details*</strong> There might be times whenever you notice that a Members\'s Subscription has been cancelled through PayPal®... but, s2Member continues allowing the User access to your site as a paid Member. Please don\'t be confused by this... in 99.9% of these cases, the reason for this is legitimate. s2Member will only remove the User\'s membership privileges when PayPal® sends a <code>subscr_eot</code> notification via the IPN service, a refund occurs, a chargeback occurs, or when a cancellation occurs - which would later result in a delayed Auto-EOT by s2Member. s2Member will not process an EOT until the User has completely used up the time they paid for. In other words, if a User signs up for a monthly Subscription on Jan 1st, and then cancels their Subscription on Jan 15th; technically, they should still be allowed to access the site for another 15 days, and then on Feb 1st, the time they paid for has completely elapsed. At that time, s2Member will remove their membership privileges; by either demoting them to a Free Subscriber, or deleting their account from the system ( based on your configuration ). s2Member also calculates one extra day ( 24 hours ) into its equation, just to make sure access is not removed sooner than a Customer might expect.</em></p>' . "\n";
435
  do_action ("ws_plugin__s2member_during_paypal_ops_page_during_left_sections_during_eot_behavior", get_defined_vars ());
436
  /**/
437
  echo '<p id="ws-plugin--s2member-auto-eot-system-enabled-via-cron"' . (($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["auto_eot_system_enabled"] == 2 && (!function_exists ("wp_cron") || !wp_get_schedule ("ws_plugin__s2member_auto_eot_system__schedule"))) ? '' : ' style="display:none;"') . '>If you\'d like to run s2Member\'s Auto-EOT System through a more traditional Cron Job; instead of through <code>WP-Cron</code>, you will need to configure a Cron Job through your server control panel; provided by your hosting company. Set the Cron Job to run <code>once about every 10 minutes to an hour</code>. You\'ll want to configure an HTTP Cron Job that loads this URL:<br /><code>' . esc_html (add_query_arg ("s2member_auto_eot_system_via_cron", "1", get_bloginfo ("wpurl") . "/")) . '</code></p>' . "\n";
451
  /**/
452
  echo '<td>' . "\n";
453
  echo '<select name="ws_plugin__s2member_auto_eot_system_enabled" id="ws-plugin--s2member-auto-eot-system-enabled">' . "\n";
454
+ /* Very advanced conditionals here. If the Auto-EOT System is NOT running, or NOT fully configured, this will indicate that no option is set - as sort of a built-in acknowledgment/warning in the UI panel. */
455
  echo (($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["auto_eot_system_enabled"] == 1 && (!function_exists ("wp_cron") || !wp_get_schedule ("ws_plugin__s2member_auto_eot_system__schedule"))) || ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["auto_eot_system_enabled"] == 2 && (function_exists ("wp_cron") && wp_get_schedule ("ws_plugin__s2member_auto_eot_system__schedule"))) || (!$GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["auto_eot_system_enabled"] && (function_exists ("wp_cron") && wp_get_schedule ("ws_plugin__s2member_auto_eot_system__schedule")))) ? '<option value=""></option>' . "\n" : '';
456
  echo '<option value="1"' . (($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["auto_eot_system_enabled"] == 1 && function_exists ("wp_cron") && wp_get_schedule ("ws_plugin__s2member_auto_eot_system__schedule")) ? ' selected="selected"' : '') . '>Yes ( enable the Auto-EOT System through WP-Cron )</option>' . "\n";
457
  echo (!is_multisite () || !ws_plugin__s2member_is_multisite_farm () || is_main_site ()) ? '<option value="2"' . (($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["auto_eot_system_enabled"] == 2 && (!function_exists ("wp_cron") || !wp_get_schedule ("ws_plugin__s2member_auto_eot_system__schedule"))) ? ' selected="selected"' : '') . '>Yes ( but, I\'ll run it with my own Cron Job )</option>' . "\n" : '';
480
  echo '</td>' . "\n";
481
  /**/
482
  echo '</tr>' . "\n";
483
+ echo '<tr>' . "\n";
484
+ /**/
485
+ echo '<th>' . "\n";
486
+ echo '<label for="ws-plugin--s2member-triggers-immediate-eot">' . "\n";
487
+ echo 'Refunds/Reversals ( trigger immediate EOT )?' . "\n";
488
+ echo '</label>' . "\n";
489
+ echo '</th>' . "\n";
490
+ /**/
491
+ echo '</tr>' . "\n";
492
+ echo '<tr>' . "\n";
493
+ /**/
494
+ echo '<td>' . "\n";
495
+ echo '<select name="ws_plugin__s2member_triggers_immediate_eot" id="ws-plugin--s2member-triggers-immediate-eot">' . "\n";
496
+ echo '<option value="none"' . (($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["triggers_immediate_eot"] === "none") ? ' selected="selected"' : '') . '>Neither ( I\'ll review these two events manually )</option>' . "\n";
497
+ echo '<option value="refunds"' . (($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["triggers_immediate_eot"] === "refunds") ? ' selected="selected"' : '') . '>Refunds ( refunds ALWAYS trigger an immediate EOT action )</option>' . "\n";
498
+ echo '<option value="reversals"' . (($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["triggers_immediate_eot"] === "reversals") ? ' selected="selected"' : '') . '>Reversals ( chargebacks ALWAYS trigger an immediate EOT action )</option>' . "\n";
499
+ echo '<option value="refunds,reversals"' . (($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["triggers_immediate_eot"] === "refunds,reversals") ? ' selected="selected"' : '') . '>Refunds/Reversals ( ALWAYS trigger an immediate EOT action )</option>' . "\n";
500
+ echo '</select><br />' . "\n";
501
+ echo 'This setting will <a href="#" onclick="alert(\'A Refund/Reversal Notification will ALWAYS be processed internally by s2Member, even if no action is taken by s2Member. This way you\\\'ll have the full ability to listen for these two events on your own; if you prefer ( optional ). For more information, check your Dashboard under: `s2Member -> API Notifications -> Refunds/Reversals`.\'); return false;">NOT affect</a> s2Member\'s internal API Notifications for Refund/Reversal events.' . "\n";
502
+ echo '</td>' . "\n";
503
+ /**/
504
+ echo '</tr>' . "\n";
505
  echo '</tbody>' . "\n";
506
  echo '</table>' . "\n";
507
  echo '</div>' . "\n";
includes/menu-pages/scripting.inc.php CHANGED
@@ -38,7 +38,7 @@ if (apply_filters ("ws_plugin__s2member_during_scripting_page_during_left_sectio
38
  /**/
39
  echo '<div class="ws-menu-page-section ws-plugin--s2member-api-easy-way-section">' . "\n";
40
  echo '<h3>The Extremely Easy Way ( no scripting required )</h3>' . "\n";
41
- echo '<p>From your s2Member General Options Panel, you may restrict access to certain Posts, Pages, Tags, Categories, and/or URIs based on a Member\'s Level. The s2Member Options Panel makes it easy for you. All you do is type in the basics of what you want to restrict access to, and those sections of your site will be off limits to non-Members. That being said, there are times when you might need to have greater control over which portions of your site can be viewed by non-Members, or Members at different Levels. This is where API Scripting with Advanced Conditionals comes in.</p>' . "\n";
42
  do_action ("ws_plugin__s2member_during_scripting_page_during_left_sections_during_api_easy_way", get_defined_vars ());
43
  echo '</div>' . "\n";
44
  /**/
@@ -47,6 +47,65 @@ if (apply_filters ("ws_plugin__s2member_during_scripting_page_during_left_sectio
47
  do_action ("ws_plugin__s2member_during_scripting_page_during_left_sections_after_api_easy_way", get_defined_vars ());
48
  }
49
  /**/
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
50
  if (apply_filters ("ws_plugin__s2member_during_scripting_page_during_left_sections_display_api_advanced_way", true, get_defined_vars ()))
51
  {
52
  do_action ("ws_plugin__s2member_during_scripting_page_during_left_sections_before_api_advanced_way", get_defined_vars ());
@@ -55,22 +114,54 @@ if (apply_filters ("ws_plugin__s2member_during_scripting_page_during_left_sectio
55
  /**/
56
  echo '<div class="ws-menu-page-section ws-plugin--s2member-api-advanced-way-section">' . "\n";
57
  echo '<h3>The Advanced Way ( some PHP scripting required )</h3>' . "\n";
58
- echo '<p>In an effort to give you even more control over access restrictions, s2Member makes some PHP functions, and also some PHP Constants, available to you from within WordPress®. In this section, we\'ll demonstrate two functions: <strong><code>is_user_logged_in()</code></strong> &amp; <strong><code>current_user_can()</code></strong>. To make use of these functions, please follow our PHP code samples below. Using PHP, you can control access to certain portions of your content, and even build Advanced Conditionals within your content, based on a Members\'s Level. In order to use PHP scripting inside your Posts/Pages, you\'ll need to install this handy plugin ( <a href="http://wordpress.org/extend/plugins/exec-php/" target="_blank" rel="external">Exec-PHP</a> ).</p>' . "\n";
59
  do_action ("ws_plugin__s2member_during_scripting_page_during_left_sections_during_api_advanced_way", get_defined_vars ());
 
 
 
60
  echo '<p><strong>Example #1:</strong> Full access for anyone that is logged in.</strong></p>' . "\n";
61
  echo '<p>' . highlight_string (file_get_contents (dirname (__FILE__) . "/code-samples/is-user-logged-in.php"), true) . '</p>' . "\n";
 
 
 
62
  echo '<p><strong>Example #2:</strong> Full access for any Member with a Level >= 1.</strong></p>' . "\n";
63
  echo '<p>' . highlight_string (file_get_contents (dirname (__FILE__) . "/code-samples/current-user-can-full-access.php"), true) . '</p>' . "\n";
 
 
 
64
  echo '<p><strong>Example #3:</strong> Specific content for each different Member Level.</strong></p>' . "\n";
65
- echo '<p>' . highlight_string (file_get_contents (dirname (__FILE__) . "/code-samples/current-user-can-specific-content.php"), true) . '</p>' . "\n";
66
- echo '<p><strong>Example #4:</strong> Uses s2Member API Constants, instead of functions.</strong></p>' . "\n";
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
67
  echo '<p>' . highlight_string (file_get_contents (dirname (__FILE__) . "/code-samples/current-user-can-constants-1.php"), true) . '</p>' . "\n";
68
- echo '<p><strong>Example #5:</strong> Uses s2Member API Constants, instead of functions.</strong></p>' . "\n";
 
 
 
69
  echo '<p>' . highlight_string (file_get_contents (dirname (__FILE__) . "/code-samples/current-user-can-constants-2.php"), true) . '</p>' . "\n";
 
 
 
70
  echo '<p><strong>Membership Levels provide incremental access:</strong></p>' . "\n";
71
  echo '<p>* A Member with Level 4 access, will also be able to access Levels 0, 1, 2 &amp; 3.<br />* A Member with Level 3 access, will also be able to access Levels 0, 1 &amp; 2.<br />* A Member with Level 2 access, will also be able to access Levels 0 &amp; 1.<br />* A Member with Level 1 access, will also be able to access Level 0.<br />* A Subscriber with Level 0 access, will ONLY be able to access Level 0.</p>' . "\n";
72
- echo '<p><em>* WordPress® Subscribers are at Membership Level 0. If you\'re allowing Open Registration, Subscribers will be at Level 0 ( a Free Subscriber ).</em></p>' . "\n";
73
- echo '<p><em>* WordPress® Administrators, Editors, Authors, and Contributors have Level 4 access, with respect to s2Member. All of their other Roles/Capabilities are left untouched.</em></p>' . "\n";
74
  echo '</div>' . "\n";
75
  /**/
76
  echo '</div>' . "\n";
@@ -89,7 +180,7 @@ if (apply_filters ("ws_plugin__s2member_during_scripting_page_during_left_sectio
89
  echo '<p>Using the PayPal® Button Generator for s2Member, you can add Custom Capabilities in comma delimited format. s2Member builds upon existing functionality offered by WordPress® Roles/Capabilities. s2Member supports Free Subscribers ( at Level #0 ), and up to four Primary Roles ( i.e. s2Member Levels 1-4 ). Each s2Member Level provides <code>current_user_can("access_s2member_level0"), 1, 2, 3, 4</code>. These are the default Capabilities that come with each Membership Level. Now... If you\'d like to package together some variations of each Membership Level that you\'re selling, you can! All you do is add some Custom Capabilities whenever you create your PayPal® Button Code ( <em>there is a field in the Button Generator where you can enter Custom Capabilities</em> ). You can sell membership packages that come with Custom Capabilities, and even with custom prices.</p>' . "\n";
90
  echo '<p>Custom Capabilities are an extension to a feature that already exists in WordPress®. The <code>current_user_can()</code> function, can be used to test for these additional Capabilities that you allow. Whenever a Member completes the checkout process, after having purchased a Membership from you ( one that included Custom Capabilities ), s2Member will add those Custom Capabilities to the account for that specific Member.</p>' . "\n";
91
  echo '<p>Custom Capabilities are always prepended with <code>access_s2member_ccap_</code>. You fill in the last part, with ONLY lowercase alpha-numerics and/or underscores. For example, let\'s say you want to sell Membership Level #1, as is. But, you also want to sell a slight variation of Membership Level #1, that includes the ability to access the Music &amp; Video sections of your site. So, instead of selling this additional access under a whole new Membership Level, you could just sell a modified version of Membership Level #1. Add the the Custom Capabilities: <code>music,videos</code>. Once a Member has these Capabilities, you can test for these Capabilities using <code>current_user_can("access_s2member_ccap_music")</code> and <code>current_user_can("access_s2member_ccap_videos")</code>.</p>' . "\n";
92
- echo '<p>The important thing to realize, is that Custom Capabilities, are just that. They\'re custom. s2Member only deals with the default Capabilities that it uses. If you start using Custom Capabilities, you MUST use Advanced Conditionals ( <em>i.e. the <code>current_user_can()</code> function</em> ) to test for them. Either in your theme files, or in Posts/Pages using the <a href="http://wordpress.org/extend/plugins/exec-php/" target="_blank" rel="external">Exec-PHP</a> plugin.</p>' . "\n";
93
  echo '<p><em class="ws-menu-page-hilite"><strong>*Tip*</strong> Starting with s2Member v3.2+, you can now tell s2Member to require Custom Capabilities on a per Post/Page basis. So now, s2Member ( if you prefer ) can handle Custom Capabilities for you! Whenever you edit a Post/Page, you can tell s2Member to require certain Custom Capabilities that you type in, using comma delimited format. In other words, you will need to type in some of the trigger words that you used whenever you created your PayPal® Pro Forms and/or PayPal® Buttons. This way your Members will have the proper Capabilities to view different kinds of content that you offer.</em></p>' . "\n";
94
  do_action ("ws_plugin__s2member_during_scripting_page_during_left_sections_during_custom_capabilities", get_defined_vars ());
95
  /**/
@@ -236,8 +327,7 @@ if (apply_filters ("ws_plugin__s2member_during_scripting_page_during_left_sectio
236
  echo '<p>' . highlight_string (file_get_contents (dirname (__FILE__) . "/code-samples/current-user-access-level.php"), true) . '</p>' . "\n";
237
  echo '<p><strong>Membership Levels provide incremental access:</strong></p>' . "\n";
238
  echo '<p>* A Member with Level 4 access, will also be able to access Levels 0, 1, 2 &amp; 3.<br />* A Member with Level 3 access, will also be able to access Levels 0, 1 &amp; 2.<br />* A Member with Level 2 access, will also be able to access Levels 0 &amp; 1.<br />* A Member with Level 1 access, will also be able to access Level 0.<br />* A Subscriber with Level 0 access, will ONLY be able to access Level 0.</p>' . "\n";
239
- echo '<p><em>* WordPress® Subscribers are at Membership Level 0. If you\'re allowing Open Registration, Subscribers will be at Level 0 ( a Free Subscriber ).</em></p>' . "\n";
240
- echo '<p><em>* WordPress® Administrators, Editors, Authors, and Contributors have Level 4 access, with respect to s2Member. All of their other Roles/Capabilities are left untouched.</em></p>' . "\n";
241
  /**/
242
  echo '<div class="ws-menu-page-hr"></div>' . "\n";
243
  /**/
38
  /**/
39
  echo '<div class="ws-menu-page-section ws-plugin--s2member-api-easy-way-section">' . "\n";
40
  echo '<h3>The Extremely Easy Way ( no scripting required )</h3>' . "\n";
41
+ echo '<p>From your s2Member General Options Panel, you may restrict access to certain Posts, Pages, Tags, Categories, and/or URIs based on a Member\'s Level. The s2Member Options Panel makes it easy for you. All you do is type in the basics of what you want to restrict access to, and those sections of your site will be off limits to non-Members. That being said, there are times when you might need to have greater control over which portions of your site can be viewed by non-Members, or Members at different Levels; with different Capabilities. This is where API Scripting with Conditionals comes in.</p>' . "\n";
42
  do_action ("ws_plugin__s2member_during_scripting_page_during_left_sections_during_api_easy_way", get_defined_vars ());
43
  echo '</div>' . "\n";
44
  /**/
47
  do_action ("ws_plugin__s2member_during_scripting_page_during_left_sections_after_api_easy_way", get_defined_vars ());
48
  }
49
  /**/
50
+ if (apply_filters ("ws_plugin__s2member_during_scripting_page_during_left_sections_display_api_simple_way", true, get_defined_vars ()))
51
+ {
52
+ do_action ("ws_plugin__s2member_during_scripting_page_during_left_sections_before_api_simple_way", get_defined_vars ());
53
+ /**/
54
+ echo '<div class="ws-menu-page-group" title="Using Simple Conditionals">' . "\n";
55
+ /**/
56
+ echo '<div class="ws-menu-page-section ws-plugin--s2member-api-simple-way-section">' . "\n";
57
+ echo '<h3>The Simple Way ( no scripting required, just Shortcodes )</h3>' . "\n";
58
+ echo '<p>In an effort to give you even more control over access restrictions, s2Member makes Simple Conditionals available to you from within WordPress®, using Shortcodes that are fully compatible with both the Visual Editor, and also the HTML Tab in WordPress®. In this section, we\'ll demonstrate several functions that are possible using Shortcodes: <strong><code>is_user_logged_in="yes|no"</code></strong>, <strong><code>is_user_not_logged_in="yes|no"</code></strong>, <strong><code>current_user_is="role"</code></strong>, <strong><code>current_user_is_not="role"</code></strong>, <strong><code>current_user_can="capability"</code></strong>, <strong><code>current_user_cannot="capability"</code></strong>, <strong><code>current_user_is_for_blog="blog_id,role"</code></strong>, <strong><code>current_user_is_not_for_blog="blog_id,role"</code></strong>, <strong><code>current_user_can_for_blog="blog_id,capability"</code></strong>, &amp; <strong><code>current_user_cannot_for_blog="blog_id,capability"</code></strong>. To make use of these functions, please follow our code samples below. Using Shortcodes, it\'s easy to build Simple Conditionals within your content; based on a Members\'s Level, or even based on Custom Capabilities. s2Member\'s Shortcodes can be used inside a Post/Page, and also inside Text Widgets.</p>' . "\n";
59
+ echo '<p><em>There are <strong>three different Shortcodes</strong> that work with Simple Conditionals.<br /><strong>1. <code>s2All</code></strong> ( true, if all conditions are met ).<br /><strong>2. <code>s2Any</code></strong> ( true, if any condition is met ).<br /><strong>3. <code>s2Get</code></strong> ( to get an API Constant value ).</em></p>' . "\n";
60
+ do_action ("ws_plugin__s2member_during_scripting_page_during_left_sections_during_api_simple_way", get_defined_vars ());
61
+ /**/
62
+ echo '<div class="ws-menu-page-hr"></div>' . "\n";
63
+ /**/
64
+ echo '<p><strong>Example #1:</strong> Full access for anyone that is logged in.</strong></p>' . "\n";
65
+ echo '<p>' . highlight_string (file_get_contents (dirname (__FILE__) . "/code-samples/sc-is-user-logged-in.php"), true) . '</p>' . "\n";
66
+ /**/
67
+ echo '<div class="ws-menu-page-hr"></div>' . "\n";
68
+ /**/
69
+ echo '<p><strong>Example #2:</strong> Full access for any Member with a Level >= 1.</strong></p>' . "\n";
70
+ echo '<p>' . highlight_string (file_get_contents (dirname (__FILE__) . "/code-samples/sc-current-user-can-full-access.php"), true) . '</p>' . "\n";
71
+ /**/
72
+ echo '<div class="ws-menu-page-hr"></div>' . "\n";
73
+ /**/
74
+ echo '<p><strong>Example #3:</strong> Specific content for each different Member Level.</strong></p>' . "\n";
75
+ echo '<p>' . highlight_string (file_get_contents (dirname (__FILE__) . "/code-samples/sc-current-user-is-specific-content.php"), true) . '</p>' . "\n";
76
+ /**/
77
+ echo '<div class="ws-menu-page-hr"></div>' . "\n";
78
+ /**/
79
+ echo '<p><strong>Example #4:</strong> Using s2Member API Conditionals, supplementing WordPress® core functions.</strong></p>' . "\n";
80
+ echo '<p>' . highlight_string (file_get_contents (dirname (__FILE__) . "/code-samples/sc-s2-conditional-supplements-1.php"), true) . '</p>' . "\n";
81
+ /**/
82
+ echo '<div class="ws-menu-page-hr"></div>' . "\n";
83
+ /**/
84
+ echo '<p><strong>Example #5:</strong> Using multiple Conditionals together, and even nesting other Shortcodes.</strong></p>' . "\n";
85
+ echo '<p>' . highlight_string (file_get_contents (dirname (__FILE__) . "/code-samples/sc-s2-conditional-supplements-2.php"), true) . '</p>' . "\n";
86
+ /**/
87
+ echo '<div class="ws-menu-page-hr"></div>' . "\n";
88
+ /**/
89
+ echo '<p><strong>Example #6:</strong> Using multiple Conditionals together, and even nesting Conditionals.</strong></p>' . "\n";
90
+ echo '<p>' . highlight_string (file_get_contents (dirname (__FILE__) . "/code-samples/sc-s2-conditional-supplements-3.php"), true) . '</p>' . "\n";
91
+ /**/
92
+ echo '<div class="ws-menu-page-hr"></div>' . "\n";
93
+ /**/
94
+ echo '<p><strong>Membership Levels provide incremental access:</strong></p>' . "\n";
95
+ echo '<p>* A Member with Level 4 access, will also be able to access Levels 0, 1, 2 &amp; 3.<br />* A Member with Level 3 access, will also be able to access Levels 0, 1 &amp; 2.<br />* A Member with Level 2 access, will also be able to access Levels 0 &amp; 1.<br />* A Member with Level 1 access, will also be able to access Level 0.<br />* A Subscriber with Level 0 access, will ONLY be able to access Level 0.</p>' . "\n";
96
+ echo '<p><em>* WordPress® Subscribers are at Membership Level 0. If you\'re allowing Open Registration, Subscribers will be at Level 0 ( a Free Subscriber ). WordPress® Administrators, Editors, Authors, and Contributors have Level 4 access, with respect to s2Member. All of their other Roles/Capabilities are left untouched.</em></p>' . "\n";
97
+ /**/
98
+ echo '<div class="ws-menu-page-hr"></div>' . "\n";
99
+ /**/
100
+ echo '<p><em>s2Member supports ALL <a href="http://codex.wordpress.org/Conditional_Tags" target="_blank" rel="external">Conditional Tags</a> in WordPress®. Including, but not limited to: <strong><code>is_multisite="yes|no"</code></strong>, <strong><code>is_main_site="yes|no"</code></strong>, <strong><code>is_super_admin="yes|no"</code></strong>, <strong><code>is_admin="yes|no"</code></strong>, <strong><code>is_404="yes|no"</code></strong>, <strong><code>is_home="yes|no"</code></strong>, <strong><code>is_front_page="yes|no"</code></strong>, <strong><code>is_comments_popup="yes|no"</code></strong>, <strong><code>is_singular="yes|no|ID|slug|array(slug,ID)"</code></strong>, <strong><code>is_single="yes|no|ID|slug|array(slug,ID)"</code></strong>, <strong><code>is_page="yes|no|ID|slug|array(slug,ID)"</code></strong>, <strong><code>is_page_template="yes|no|file.php"</code></strong>, <strong><code>is_attachment="yes|no"</code></strong>, <strong><code>is_feed="yes|no"</code></strong>, <strong><code>is_trackback="yes|no"</code></strong>, <strong><code>is_archive="yes|no"</code></strong>, <strong><code>is_search="yes|no"</code></strong>, <strong><code>is_category="yes|no|ID|slug|array(slug,ID)"</code></strong>, <strong><code>is_tax="taxonomy,term"</code></strong>, <strong><code>is_tag="yes|no|slug|array(slug,slug)"</code></strong>, <strong><code>has_tag="yes|no|slug|array(slug,slug)"</code></strong>, <strong><code>is_author="yes|no|ID|slug|array(slug,ID)"</code></strong>, <strong><code>is_date="yes|no"</code></strong>, <strong><code>is_day="yes|no"</code></strong>, <strong><code>is_month="yes|no"</code></strong>, <strong><code>is_time="yes|no"</code></strong>, <strong><code>is_year="yes|no"</code></strong>, <strong><code>is_sticky="yes|no|ID"</code></strong>, <strong><code>is_paged="yes|no"</code></strong>, <strong><code>is_preview="yes|no"</code></strong>, <strong><code>comments_open="yes|no"</code></strong>, <strong><code>pings_open="yes|no"</code></strong>, <strong><code>has_excerpt="yes|no|ID"</code></strong>, <strong><code>in_the_loop="yes|no"</code></strong>, <strong><code>is_active_sidebar="ID|number"</code></strong>.</em></p>' . "\n";
101
+ echo '<p><em>Passing arguments into a Shortcode attribute:<br /><br />1. yes|no ( ex: <code>is_page="yes"</code> )<br />1. ID ( ex: <code>is_page="24"</code> )<br />3. slug ( ex: <code>is_page="my-cool-page"</code><br />4. array ( ex: <code>is_page="array(my-cool-page,24,about,contact-form)"</code><br /><br />*Tip: do NOT use spaces in attribute values.<br /> <strong class="ws-menu-page-error-hilite">BAD</strong> <code>is_page="My Membership Options Page"</code><br />- use slugs or IDs instead, no spaces.</em></p>' . "\n";
102
+ echo '</div>' . "\n";
103
+ /**/
104
+ echo '</div>' . "\n";
105
+ /**/
106
+ do_action ("ws_plugin__s2member_during_scripting_page_during_left_sections_after_api_simple_way", get_defined_vars ());
107
+ }
108
+ /**/
109
  if (apply_filters ("ws_plugin__s2member_during_scripting_page_during_left_sections_display_api_advanced_way", true, get_defined_vars ()))
110
  {
111
  do_action ("ws_plugin__s2member_during_scripting_page_during_left_sections_before_api_advanced_way", get_defined_vars ());
114
  /**/
115
  echo '<div class="ws-menu-page-section ws-plugin--s2member-api-advanced-way-section">' . "\n";
116
  echo '<h3>The Advanced Way ( some PHP scripting required )</h3>' . "\n";
117
+ echo '<p>In an effort to give you even more control over access restrictions, s2Member makes some PHP functions, and also some PHP Constants, available to you from within WordPress®. In this section, we\'ll demonstrate several functions: <strong><code>is_user_logged_in()</code></strong>, <strong><code>is_user_not_logged_in()</code></strong>, <strong><code>current_user_is("role")</code></strong>, <strong><code>current_user_is_not("role")</code></strong>, <strong><code>current_user_can("capability")</code></strong>, <strong><code>current_user_cannot("capability")</code></strong>, <strong><code>current_user_is_for_blog($blog_id,"role")</code></strong>, <strong><code>current_user_is_not_for_blog($blog_id,"role")</code></strong>, <strong><code>current_user_can_for_blog($blog_id,"capability")</code></strong>, &amp; <strong><code>current_user_cannot_for_blog($blog_id,"capability")</code></strong>. To make use of these functions, please follow our PHP code samples below. Using PHP, is a very powerful way to build Advanced Conditionals within your content; based on a Members\'s Level, Custom Capabilities, and/or other factors. In order to use PHP scripting inside your Posts/Pages, you\'ll need to install this handy plugin ( <a href="http://wordpress.org/extend/plugins/exec-php/" target="_blank" rel="external">Exec-PHP</a> ).</p>' . "\n";
118
  do_action ("ws_plugin__s2member_during_scripting_page_during_left_sections_during_api_advanced_way", get_defined_vars ());
119
+ /**/
120
+ echo '<div class="ws-menu-page-hr"></div>' . "\n";
121
+ /**/
122
  echo '<p><strong>Example #1:</strong> Full access for anyone that is logged in.</strong></p>' . "\n";
123
  echo '<p>' . highlight_string (file_get_contents (dirname (__FILE__) . "/code-samples/is-user-logged-in.php"), true) . '</p>' . "\n";
124
+ /**/
125
+ echo '<div class="ws-menu-page-hr"></div>' . "\n";
126
+ /**/
127
  echo '<p><strong>Example #2:</strong> Full access for any Member with a Level >= 1.</strong></p>' . "\n";
128
  echo '<p>' . highlight_string (file_get_contents (dirname (__FILE__) . "/code-samples/current-user-can-full-access.php"), true) . '</p>' . "\n";
129
+ /**/
130
+ echo '<div class="ws-menu-page-hr"></div>' . "\n";
131
+ /**/
132
  echo '<p><strong>Example #3:</strong> Specific content for each different Member Level.</strong></p>' . "\n";
133
+ echo '<p>' . highlight_string (file_get_contents (dirname (__FILE__) . "/code-samples/current-user-is-specific-content.php"), true) . '</p>' . "\n";
134
+ /**/
135
+ echo '<div class="ws-menu-page-hr"></div>' . "\n";
136
+ /**/
137
+ echo '<p><strong>Example #4:</strong> Using s2Member API Conditionals, supplementing WordPress® core functions.</strong></p>' . "\n";
138
+ echo '<p>' . highlight_string (file_get_contents (dirname (__FILE__) . "/code-samples/s2-conditional-supplements-1.php"), true) . '</p>' . "\n";
139
+ /**/
140
+ echo '<div class="ws-menu-page-hr"></div>' . "\n";
141
+ /**/
142
+ echo '<p><strong>Example #5:</strong> Using s2Member API Conditionals, supplementing WordPress® core functions.</strong></p>' . "\n";
143
+ echo '<p>' . highlight_string (file_get_contents (dirname (__FILE__) . "/code-samples/s2-conditional-supplements-2.php"), true) . '</p>' . "\n";
144
+ /**/
145
+ echo '<div class="ws-menu-page-hr"></div>' . "\n";
146
+ /**/
147
+ echo '<p><strong>Example #6:</strong> Using multiple Conditionals together, and even nesting Conditionals.</strong></p>' . "\n";
148
+ echo '<p>' . highlight_string (file_get_contents (dirname (__FILE__) . "/code-samples/s2-conditional-supplements-3.php"), true) . '</p>' . "\n";
149
+ /**/
150
+ echo '<div class="ws-menu-page-hr"></div>' . "\n";
151
+ /**/
152
+ echo '<p><strong>Example #7:</strong> Using s2Member API Constants, instead of conditional functions.</strong></p>' . "\n";
153
  echo '<p>' . highlight_string (file_get_contents (dirname (__FILE__) . "/code-samples/current-user-can-constants-1.php"), true) . '</p>' . "\n";
154
+ /**/
155
+ echo '<div class="ws-menu-page-hr"></div>' . "\n";
156
+ /**/
157
+ echo '<p><strong>Example #8:</strong> Using s2Member API Constants, instead of conditional functions.</strong></p>' . "\n";
158
  echo '<p>' . highlight_string (file_get_contents (dirname (__FILE__) . "/code-samples/current-user-can-constants-2.php"), true) . '</p>' . "\n";
159
+ /**/
160
+ echo '<div class="ws-menu-page-hr"></div>' . "\n";
161
+ /**/
162
  echo '<p><strong>Membership Levels provide incremental access:</strong></p>' . "\n";
163
  echo '<p>* A Member with Level 4 access, will also be able to access Levels 0, 1, 2 &amp; 3.<br />* A Member with Level 3 access, will also be able to access Levels 0, 1 &amp; 2.<br />* A Member with Level 2 access, will also be able to access Levels 0 &amp; 1.<br />* A Member with Level 1 access, will also be able to access Level 0.<br />* A Subscriber with Level 0 access, will ONLY be able to access Level 0.</p>' . "\n";
164
+ echo '<p><em>* WordPress® Subscribers are at Membership Level 0. If you\'re allowing Open Registration, Subscribers will be at Level 0 ( a Free Subscriber ). WordPress® Administrators, Editors, Authors, and Contributors have Level 4 access, with respect to s2Member. All of their other Roles/Capabilities are left untouched.</em></p>' . "\n";
 
165
  echo '</div>' . "\n";
166
  /**/
167
  echo '</div>' . "\n";
180
  echo '<p>Using the PayPal® Button Generator for s2Member, you can add Custom Capabilities in comma delimited format. s2Member builds upon existing functionality offered by WordPress® Roles/Capabilities. s2Member supports Free Subscribers ( at Level #0 ), and up to four Primary Roles ( i.e. s2Member Levels 1-4 ). Each s2Member Level provides <code>current_user_can("access_s2member_level0"), 1, 2, 3, 4</code>. These are the default Capabilities that come with each Membership Level. Now... If you\'d like to package together some variations of each Membership Level that you\'re selling, you can! All you do is add some Custom Capabilities whenever you create your PayPal® Button Code ( <em>there is a field in the Button Generator where you can enter Custom Capabilities</em> ). You can sell membership packages that come with Custom Capabilities, and even with custom prices.</p>' . "\n";
181
  echo '<p>Custom Capabilities are an extension to a feature that already exists in WordPress®. The <code>current_user_can()</code> function, can be used to test for these additional Capabilities that you allow. Whenever a Member completes the checkout process, after having purchased a Membership from you ( one that included Custom Capabilities ), s2Member will add those Custom Capabilities to the account for that specific Member.</p>' . "\n";
182
  echo '<p>Custom Capabilities are always prepended with <code>access_s2member_ccap_</code>. You fill in the last part, with ONLY lowercase alpha-numerics and/or underscores. For example, let\'s say you want to sell Membership Level #1, as is. But, you also want to sell a slight variation of Membership Level #1, that includes the ability to access the Music &amp; Video sections of your site. So, instead of selling this additional access under a whole new Membership Level, you could just sell a modified version of Membership Level #1. Add the the Custom Capabilities: <code>music,videos</code>. Once a Member has these Capabilities, you can test for these Capabilities using <code>current_user_can("access_s2member_ccap_music")</code> and <code>current_user_can("access_s2member_ccap_videos")</code>.</p>' . "\n";
183
+ echo '<p>The important thing to realize, is that Custom Capabilities, are just that. They\'re custom. s2Member only deals with the default Capabilities that it uses. If you start using Custom Capabilities, you MUST use Simple or Advanced Conditionals ( <em>i.e. <code>current_user_can</code> logic</em> ) to test for them. Either in your theme files with PHP, or in Posts/Pages using Simple Conditionals ( powered by Shortcodes ).</p>' . "\n";
184
  echo '<p><em class="ws-menu-page-hilite"><strong>*Tip*</strong> Starting with s2Member v3.2+, you can now tell s2Member to require Custom Capabilities on a per Post/Page basis. So now, s2Member ( if you prefer ) can handle Custom Capabilities for you! Whenever you edit a Post/Page, you can tell s2Member to require certain Custom Capabilities that you type in, using comma delimited format. In other words, you will need to type in some of the trigger words that you used whenever you created your PayPal® Pro Forms and/or PayPal® Buttons. This way your Members will have the proper Capabilities to view different kinds of content that you offer.</em></p>' . "\n";
185
  do_action ("ws_plugin__s2member_during_scripting_page_during_left_sections_during_custom_capabilities", get_defined_vars ());
186
  /**/
327
  echo '<p>' . highlight_string (file_get_contents (dirname (__FILE__) . "/code-samples/current-user-access-level.php"), true) . '</p>' . "\n";
328
  echo '<p><strong>Membership Levels provide incremental access:</strong></p>' . "\n";
329
  echo '<p>* A Member with Level 4 access, will also be able to access Levels 0, 1, 2 &amp; 3.<br />* A Member with Level 3 access, will also be able to access Levels 0, 1 &amp; 2.<br />* A Member with Level 2 access, will also be able to access Levels 0 &amp; 1.<br />* A Member with Level 1 access, will also be able to access Level 0.<br />* A Subscriber with Level 0 access, will ONLY be able to access Level 0.</p>' . "\n";
330
+ echo '<p><em>* WordPress® Subscribers are at Membership Level 0. If you\'re allowing Open Registration, Subscribers will be at Level 0 ( a Free Subscriber ). WordPress® Administrators, Editors, Authors, and Contributors have Level 4 access, with respect to s2Member. All of their other Roles/Capabilities are left untouched.</em></p>' . "\n";
 
331
  /**/
332
  echo '<div class="ws-menu-page-hr"></div>' . "\n";
333
  /**/
includes/menu-pages/start.inc.php CHANGED
@@ -113,7 +113,7 @@ if (apply_filters ("ws_plugin__s2member_during_start_page_during_left_sections_d
113
  echo '<div class="ws-menu-page-section ws-plugin--s2member-general-options-section">' . "\n";
114
  echo '<h3>Your s2Member -> General Options ( basic configuration )</h3>' . "\n";
115
  echo '<p>Once you have a Login Welcome Page, and a Membership Options Page. Go to: <code>s2Member -> General Options</code>.</p>' . "\n";
116
- echo '<p>From your s2Member General Options Panel, you may restrict access to certain Posts, Pages, Tags, Categories, and/or URIs based on a Member\'s Level. The s2Member Options Panel makes it easy for you. All you do is type in the basics of what you want to restrict access to, and those sections of your site will be off limits to non-Members.' . ((!is_multisite () || !ws_plugin__s2member_is_multisite_farm () || is_main_site ()) ? ' That being said, there are times when you might need to have greater control over which portions of your site can be viewed by non-Members, or Members at different Levels. This is where API Scripting with Advanced Conditionals comes in. <em>For more information, see: <code>s2Member -> API Scripting</code></em>.' : '') . '</p>' . "\n";
117
  do_action ("ws_plugin__s2member_during_start_page_during_left_sections_during_general_options", get_defined_vars ());
118
  echo '</div>' . "\n";
119
  /**/
113
  echo '<div class="ws-menu-page-section ws-plugin--s2member-general-options-section">' . "\n";
114
  echo '<h3>Your s2Member -> General Options ( basic configuration )</h3>' . "\n";
115
  echo '<p>Once you have a Login Welcome Page, and a Membership Options Page. Go to: <code>s2Member -> General Options</code>.</p>' . "\n";
116
+ echo '<p>From your s2Member General Options Panel, you may restrict access to certain Posts, Pages, Tags, Categories, and/or URIs based on a Member\'s Level. The s2Member Options Panel makes it easy for you. All you do is type in the basics of what you want to restrict access to, and those sections of your site will be off limits to non-Members.' . ((!is_multisite () || !ws_plugin__s2member_is_multisite_farm () || is_main_site ()) ? ' That being said, there are times when you might need to have greater control over which portions of your site can be viewed by non-Members, or Members at different Levels. This is where API Scripting with Conditionals comes in. <em>For more information, see: <code>s2Member -> API Scripting</code></em>.' : '') . '</p>' . "\n";
117
  do_action ("ws_plugin__s2member_during_start_page_during_left_sections_during_general_options", get_defined_vars ());
118
  echo '</div>' . "\n";
119
  /**/
includes/profile.inc.php CHANGED
@@ -25,11 +25,17 @@ echo '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www
25
  /**/
26
  echo '<html xmlns="http://www.w3.org/1999/xhtml">' . "\n";
27
  echo '<head>' . "\n";
 
28
  echo '<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />' . "\n";
29
  echo '<script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/jquery/1.4.1/jquery.min.js"></script>' . "\n";
30
  echo '<script type="text/javascript" src="' . get_bloginfo ("wpurl") . '/?ws_plugin__s2member_js_w_globals=1&amp;no-cache=' . urlencode (md5 (mt_rand ())) . '"></script>' . "\n";
31
  /**/
32
  echo '<title>My Profile</title>' . "\n";
 
 
 
 
 
33
  echo '</head>' . "\n";
34
  /**/
35
  echo '<body style="background:#FFFFFF; color:#333333; font-family:\'Verdana\', sans-serif; font-size:13px;">' . "\n";
@@ -38,16 +44,22 @@ echo '<form method="post" name="ws_plugin__s2member_profile" id="ws-plugin--s2me
38
  /**/
39
  echo '<input type="hidden" name="ws_plugin__s2member_profile_save" id="ws-plugin--s2member-profile-save" value="' . esc_attr (wp_create_nonce ("ws-plugin--s2member-profile-save")) . '" />' . "\n";
40
  /**/
 
41
  do_action ("ws_plugin__s2member_during_profile_before_table", get_defined_vars ());
 
42
  /**/
43
  echo '<table cellpadding="5" cellspacing="5" style="width:100%; border:0;">' . "\n";
44
  echo '<tbody>' . "\n";
45
  /**/
 
46
  do_action ("ws_plugin__s2member_during_profile_before_fields", get_defined_vars ());
 
47
  /**/
48
  if (apply_filters ("ws_plugin__s2member_during_profile_during_fields_display_username", true, get_defined_vars ()))
49
  {
 
50
  do_action ("ws_plugin__s2member_during_profile_during_fields_before_username", get_defined_vars ());
 
51
  /**/
52
  echo '<tr>' . "\n";
53
  echo '<td>' . "\n";
@@ -58,12 +70,16 @@ if (apply_filters ("ws_plugin__s2member_during_profile_during_fields_display_use
58
  echo '</td>' . "\n";
59
  echo '</tr>' . "\n";
60
  /**/
 
61
  do_action ("ws_plugin__s2member_during_profile_during_fields_after_username", get_defined_vars ());
 
62
  }
63
  /**/
64
  if (apply_filters ("ws_plugin__s2member_during_profile_during_fields_display_email", true, get_defined_vars ()))
65
  {
 
66
  do_action ("ws_plugin__s2member_during_profile_during_fields_before_email", get_defined_vars ());
 
67
  /**/
68
  echo '<tr>' . "\n";
69
  echo '<td>' . "\n";
@@ -74,12 +90,16 @@ if (apply_filters ("ws_plugin__s2member_during_profile_during_fields_display_ema
74
  echo '</td>' . "\n";
75
  echo '</tr>' . "\n";
76
  /**/
 
77
  do_action ("ws_plugin__s2member_during_profile_during_fields_after_email", get_defined_vars ());
 
78
  }
79
  /**/
80
  if (apply_filters ("ws_plugin__s2member_during_profile_during_fields_display_first_name", true, get_defined_vars ()))
81
  {
 
82
  do_action ("ws_plugin__s2member_during_profile_during_fields_before_first_name", get_defined_vars ());
 
83
  /**/
84
  echo '<tr>' . "\n";
85
  echo '<td>' . "\n";
@@ -90,12 +110,16 @@ if (apply_filters ("ws_plugin__s2member_during_profile_during_fields_display_fir
90
  echo '</td>' . "\n";
91
  echo '</tr>' . "\n";
92
  /**/
 
93
  do_action ("ws_plugin__s2member_during_profile_during_fields_after_first_name", get_defined_vars ());
 
94
  }
95
  /**/
96
  if (apply_filters ("ws_plugin__s2member_during_profile_during_fields_display_last_name", true, get_defined_vars ()))
97
  {
 
98
  do_action ("ws_plugin__s2member_during_profile_during_fields_before_last_name", get_defined_vars ());
 
99
  /**/
100
  echo '<tr>' . "\n";
101
  echo '<td>' . "\n";
@@ -106,12 +130,16 @@ if (apply_filters ("ws_plugin__s2member_during_profile_during_fields_display_las
106
  echo '</td>' . "\n";
107
  echo '</tr>' . "\n";
108
  /**/
 
109
  do_action ("ws_plugin__s2member_during_profile_during_fields_after_last_name", get_defined_vars ());
 
110
  }
111
  /**/
112
  if (apply_filters ("ws_plugin__s2member_during_profile_during_fields_display_display_name", true, get_defined_vars ()))
113
  {
 
114
  do_action ("ws_plugin__s2member_during_profile_during_fields_before_display_name", get_defined_vars ());
 
115
  /**/
116
  echo '<tr>' . "\n";
117
  echo '<td>' . "\n";
@@ -122,14 +150,18 @@ if (apply_filters ("ws_plugin__s2member_during_profile_during_fields_display_dis
122
  echo '</td>' . "\n";
123
  echo '</tr>' . "\n";
124
  /**/
 
125
  do_action ("ws_plugin__s2member_during_profile_during_fields_after_last_name", get_defined_vars ());
 
126
  }
127
  /**/
128
  if (apply_filters ("ws_plugin__s2member_during_profile_during_fields_display_custom_fields", true, get_defined_vars ()))
129
  {
130
  $fields = get_user_option ("s2member_custom_fields", $current_user->ID);
131
  /**/
 
132
  do_action ("ws_plugin__s2member_during_profile_during_fields_before_custom_fields", get_defined_vars ());
 
133
  /**/
134
  foreach (preg_split ("/[\r\n\t;,]+/", $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["custom_reg_fields"]) as $field)
135
  {
@@ -141,11 +173,14 @@ if (apply_filters ("ws_plugin__s2member_during_profile_during_fields_display_cus
141
  /**/
142
  if ($field = trim ($field, "^* \t\n\r\0\x0B")) /* Don't process empty fields. */
143
  {
 
144
  do_action ("ws_plugin__s2member_during_profile_during_fields_during_custom_fields_before", get_defined_vars ());
 
145
  /**/
146
  $field_var = preg_replace ("/[^a-z0-9]/i", "_", strtolower ($field));
147
  $field_id_class = preg_replace ("/_/", "-", $field_var);
148
  /**/
 
149
  if (apply_filters ("ws_plugin__s2member_during_profile_during_fields_during_custom_fields_display", true, get_defined_vars ()))
150
  {
151
  echo '<tr>' . "\n";
@@ -157,17 +192,24 @@ if (apply_filters ("ws_plugin__s2member_during_profile_during_fields_display_cus
157
  echo '</td>' . "\n";
158
  echo '</tr>' . "\n";
159
  }
 
160
  /**/
 
161
  do_action ("ws_plugin__s2member_during_profile_during_fields_during_custom_fields_after", get_defined_vars ());
 
162
  }
163
  }
164
  /**/
 
165
  do_action ("ws_plugin__s2member_during_profile_during_fields_after_custom_fields", get_defined_vars ());
 
166
  }
167
  /**/
168
  if (apply_filters ("ws_plugin__s2member_during_profile_during_fields_display_password", true, get_defined_vars ()))
169
  {
 
170
  do_action ("ws_plugin__s2member_during_profile_during_fields_before_password", get_defined_vars ());
 
171
  /**/
172
  echo '<tr>' . "\n";
173
  echo '<td>' . "\n";
@@ -184,10 +226,14 @@ if (apply_filters ("ws_plugin__s2member_during_profile_during_fields_display_pas
184
  echo '</td>' . "\n";
185
  echo '</tr>' . "\n";
186
  /**/
 
187
  do_action ("ws_plugin__s2member_during_profile_during_fields_after_password", get_defined_vars ());
 
188
  }
189
  /**/
 
190
  do_action ("ws_plugin__s2member_during_profile_after_fields", get_defined_vars ());
 
191
  /**/
192
  echo '<tr>' . "\n";
193
  echo '<td>' . "\n";
@@ -198,7 +244,9 @@ echo '</tr>' . "\n";
198
  echo '</tbody>' . "\n";
199
  echo '</table>' . "\n";
200
  /**/
 
201
  do_action ("ws_plugin__s2member_during_profile_after_table", get_defined_vars ());
 
202
  /**/
203
  echo '</form>' . "\n";
204
  /**/
25
  /**/
26
  echo '<html xmlns="http://www.w3.org/1999/xhtml">' . "\n";
27
  echo '<head>' . "\n";
28
+ /**/
29
  echo '<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />' . "\n";
30
  echo '<script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/jquery/1.4.1/jquery.min.js"></script>' . "\n";
31
  echo '<script type="text/javascript" src="' . get_bloginfo ("wpurl") . '/?ws_plugin__s2member_js_w_globals=1&amp;no-cache=' . urlencode (md5 (mt_rand ())) . '"></script>' . "\n";
32
  /**/
33
  echo '<title>My Profile</title>' . "\n";
34
+ /**/
35
+ eval('foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;');
36
+ do_action ("ws_plugin__s2member_during_profile_head", get_defined_vars ());
37
+ unset ($__refs, $__v); /* Unset defined __refs, __v. */
38
+ /**/
39
  echo '</head>' . "\n";
40
  /**/
41
  echo '<body style="background:#FFFFFF; color:#333333; font-family:\'Verdana\', sans-serif; font-size:13px;">' . "\n";
44
  /**/
45
  echo '<input type="hidden" name="ws_plugin__s2member_profile_save" id="ws-plugin--s2member-profile-save" value="' . esc_attr (wp_create_nonce ("ws-plugin--s2member-profile-save")) . '" />' . "\n";
46
  /**/
47
+ eval('foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;');
48
  do_action ("ws_plugin__s2member_during_profile_before_table", get_defined_vars ());
49
+ unset ($__refs, $__v); /* Unset defined __refs, __v. */
50
  /**/
51
  echo '<table cellpadding="5" cellspacing="5" style="width:100%; border:0;">' . "\n";
52
  echo '<tbody>' . "\n";
53
  /**/
54
+ eval('foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;');
55
  do_action ("ws_plugin__s2member_during_profile_before_fields", get_defined_vars ());
56
+ unset ($__refs, $__v); /* Unset defined __refs, __v. */
57
  /**/
58
  if (apply_filters ("ws_plugin__s2member_during_profile_during_fields_display_username", true, get_defined_vars ()))
59
  {
60
+ eval('foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;');
61
  do_action ("ws_plugin__s2member_during_profile_during_fields_before_username", get_defined_vars ());
62
+ unset ($__refs, $__v); /* Unset defined __refs, __v. */
63
  /**/
64
  echo '<tr>' . "\n";
65
  echo '<td>' . "\n";
70
  echo '</td>' . "\n";
71
  echo '</tr>' . "\n";
72
  /**/
73
+ eval('foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;');
74
  do_action ("ws_plugin__s2member_during_profile_during_fields_after_username", get_defined_vars ());
75
+ unset ($__refs, $__v); /* Unset defined __refs, __v. */
76
  }
77
  /**/
78
  if (apply_filters ("ws_plugin__s2member_during_profile_during_fields_display_email", true, get_defined_vars ()))
79
  {
80
+ eval('foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;');
81
  do_action ("ws_plugin__s2member_during_profile_during_fields_before_email", get_defined_vars ());
82
+ unset ($__refs, $__v); /* Unset defined __refs, __v. */
83
  /**/
84
  echo '<tr>' . "\n";
85
  echo '<td>' . "\n";
90
  echo '</td>' . "\n";
91
  echo '</tr>' . "\n";
92
  /**/
93
+ eval('foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;');
94
  do_action ("ws_plugin__s2member_during_profile_during_fields_after_email", get_defined_vars ());
95
+ unset ($__refs, $__v); /* Unset defined __refs, __v. */
96
  }
97
  /**/
98
  if (apply_filters ("ws_plugin__s2member_during_profile_during_fields_display_first_name", true, get_defined_vars ()))
99
  {
100
+ eval('foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;');
101
  do_action ("ws_plugin__s2member_during_profile_during_fields_before_first_name", get_defined_vars ());
102
+ unset ($__refs, $__v); /* Unset defined __refs, __v. */
103
  /**/
104
  echo '<tr>' . "\n";
105
  echo '<td>' . "\n";
110
  echo '</td>' . "\n";
111
  echo '</tr>' . "\n";
112
  /**/
113
+ eval('foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;');
114
  do_action ("ws_plugin__s2member_during_profile_during_fields_after_first_name", get_defined_vars ());
115
+ unset ($__refs, $__v); /* Unset defined __refs, __v. */
116
  }
117
  /**/
118
  if (apply_filters ("ws_plugin__s2member_during_profile_during_fields_display_last_name", true, get_defined_vars ()))
119
  {
120
+ eval('foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;');
121
  do_action ("ws_plugin__s2member_during_profile_during_fields_before_last_name", get_defined_vars ());
122
+ unset ($__refs, $__v); /* Unset defined __refs, __v. */
123
  /**/
124
  echo '<tr>' . "\n";
125
  echo '<td>' . "\n";
130
  echo '</td>' . "\n";
131
  echo '</tr>' . "\n";
132
  /**/
133
+ eval('foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;');
134
  do_action ("ws_plugin__s2member_during_profile_during_fields_after_last_name", get_defined_vars ());
135
+ unset ($__refs, $__v); /* Unset defined __refs, __v. */
136
  }
137
  /**/
138
  if (apply_filters ("ws_plugin__s2member_during_profile_during_fields_display_display_name", true, get_defined_vars ()))
139
  {
140
+ eval('foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;');
141
  do_action ("ws_plugin__s2member_during_profile_during_fields_before_display_name", get_defined_vars ());
142
+ unset ($__refs, $__v); /* Unset defined __refs, __v. */
143
  /**/
144
  echo '<tr>' . "\n";
145
  echo '<td>' . "\n";
150
  echo '</td>' . "\n";
151
  echo '</tr>' . "\n";
152
  /**/
153
+ eval('foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;');
154
  do_action ("ws_plugin__s2member_during_profile_during_fields_after_last_name", get_defined_vars ());
155
+ unset ($__refs, $__v); /* Unset defined __refs, __v. */
156
  }
157
  /**/
158
  if (apply_filters ("ws_plugin__s2member_during_profile_during_fields_display_custom_fields", true, get_defined_vars ()))
159
  {
160
  $fields = get_user_option ("s2member_custom_fields", $current_user->ID);
161
  /**/
162
+ eval('foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;');
163
  do_action ("ws_plugin__s2member_during_profile_during_fields_before_custom_fields", get_defined_vars ());
164
+ unset ($__refs, $__v); /* Unset defined __refs, __v. */
165
  /**/
166
  foreach (preg_split ("/[\r\n\t;,]+/", $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["custom_reg_fields"]) as $field)
167
  {
173
  /**/
174
  if ($field = trim ($field, "^* \t\n\r\0\x0B")) /* Don't process empty fields. */
175
  {
176
+ eval('foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;');
177
  do_action ("ws_plugin__s2member_during_profile_during_fields_during_custom_fields_before", get_defined_vars ());
178
+ unset ($__refs, $__v); /* Unset defined __refs, __v. */
179
  /**/
180
  $field_var = preg_replace ("/[^a-z0-9]/i", "_", strtolower ($field));
181
  $field_id_class = preg_replace ("/_/", "-", $field_var);
182
  /**/
183
+ eval('foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;');
184
  if (apply_filters ("ws_plugin__s2member_during_profile_during_fields_during_custom_fields_display", true, get_defined_vars ()))
185
  {
186
  echo '<tr>' . "\n";
192
  echo '</td>' . "\n";
193
  echo '</tr>' . "\n";
194
  }
195
+ unset ($__refs, $__v); /* Unset defined __refs, __v. */
196
  /**/
197
+ eval('foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;');
198
  do_action ("ws_plugin__s2member_during_profile_during_fields_during_custom_fields_after", get_defined_vars ());
199
+ unset ($__refs, $__v); /* Unset defined __refs, __v. */
200
  }
201
  }
202
  /**/
203
+ eval('foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;');
204
  do_action ("ws_plugin__s2member_during_profile_during_fields_after_custom_fields", get_defined_vars ());
205
+ unset ($__refs, $__v); /* Unset defined __refs, __v. */
206
  }
207
  /**/
208
  if (apply_filters ("ws_plugin__s2member_during_profile_during_fields_display_password", true, get_defined_vars ()))
209
  {
210
+ eval('foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;');
211
  do_action ("ws_plugin__s2member_during_profile_during_fields_before_password", get_defined_vars ());
212
+ unset ($__refs, $__v); /* Unset defined __refs, __v. */
213
  /**/
214
  echo '<tr>' . "\n";
215
  echo '<td>' . "\n";
226
  echo '</td>' . "\n";
227
  echo '</tr>' . "\n";
228
  /**/
229
+ eval('foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;');
230
  do_action ("ws_plugin__s2member_during_profile_during_fields_after_password", get_defined_vars ());
231
+ unset ($__refs, $__v); /* Unset defined __refs, __v. */
232
  }
233
  /**/
234
+ eval('foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;');
235
  do_action ("ws_plugin__s2member_during_profile_after_fields", get_defined_vars ());
236
+ unset ($__refs, $__v); /* Unset defined __refs, __v. */
237
  /**/
238
  echo '<tr>' . "\n";
239
  echo '<td>' . "\n";
244
  echo '</tbody>' . "\n";
245
  echo '</table>' . "\n";
246
  /**/
247
+ eval('foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;');
248
  do_action ("ws_plugin__s2member_during_profile_after_table", get_defined_vars ());
249
+ unset ($__refs, $__v); /* Unset defined __refs, __v. */
250
  /**/
251
  echo '</form>' . "\n";
252
  /**/
includes/syscon.inc.php CHANGED
@@ -16,7 +16,7 @@ WARNING: This is a system configuration file, please DO NOT EDIT this file direc
16
  Direct access denial.
17
  */
18
  if (realpath (__FILE__) === realpath ($_SERVER["SCRIPT_FILENAME"]))
19
- exit ("Do not access this file directly.");
20
  /*
21
  Determine the full url to the directory this plugin resides in.
22
  */
@@ -190,6 +190,7 @@ function ws_plugin__s2member_configure_options_and_their_defaults ($options = FA
190
  /**/
191
  "specific_ids" => "", /* Comma-delimited list of Specific Post/Page IDs. */
192
  /**/
 
193
  "membership_eot_behavior" => "demote", /* Demote or delete Members? */
194
  "auto_eot_system_enabled" => "1")); /* 0|1|2. 1 = WP-Cron, 2 = Cron tab. */
195
  /*
@@ -214,7 +215,7 @@ function ws_plugin__s2member_configure_options_and_their_defaults ($options = FA
214
  $value[$k] = trim (stripslashes ($v));
215
  /**/
216
  if (!isset ($default_options[$key]) && !preg_match ("/^pro_/", $key))
217
- unset ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"][$key]);
218
  /**/
219
  else if ($key === "options_version" && (!is_string ($value) || !is_numeric ($value)))
220
  $value = $default_options[$key];
@@ -225,10 +226,10 @@ function ws_plugin__s2member_configure_options_and_their_defaults ($options = FA
225
  else if ($key === "sec_encryption_key_history" && (!is_array ($value) || empty ($value)))
226
  $value = $default_options[$key];
227
  /**/
228
- else if ($key === "max_ip_restriction" && (!is_string ($value) || !is_numeric ($value) || $value < 2 || $value > 100))
229
  $value = $default_options[$key];
230
  /**/
231
- else if ($key === "max_ip_restriction_time" && (!is_string ($value) || !is_numeric ($value) || $value < 900 || $value > 604800))
232
  $value = $default_options[$key];
233
  /**/
234
  else if ($key === "run_deactivation_routines" && (!is_string ($value) || !is_numeric ($value)))
@@ -396,6 +397,9 @@ function ws_plugin__s2member_configure_options_and_their_defaults ($options = FA
396
  else if ($key === "specific_ids" && (!is_string ($value) || !($value = trim (preg_replace ("/[^0-9,]/", "", $value), ","))))
397
  $value = $default_options[$key];
398
  /**/
 
 
 
399
  else if ($key === "membership_eot_behavior" && (!is_string ($value) || !preg_match ("/^(demote|delete)$/", $value)))
400
  $value = $default_options[$key];
401
  /**/
@@ -414,5 +418,5 @@ function ws_plugin__s2member_configure_options_and_their_defaults ($options = FA
414
  return apply_filters_ref_array ("ws_plugin__s2member_options", array (&$GLOBALS["WS_PLUGIN__"]["s2member"]["o"]));
415
  }
416
  /**/
417
- call_user_func ("ws_plugin__s2member_configure_options_and_their_defaults");
418
  ?>
16
  Direct access denial.
17
  */
18
  if (realpath (__FILE__) === realpath ($_SERVER["SCRIPT_FILENAME"]))
19
+ exit("Do not access this file directly.");
20
  /*
21
  Determine the full url to the directory this plugin resides in.
22
  */
190
  /**/
191
  "specific_ids" => "", /* Comma-delimited list of Specific Post/Page IDs. */
192
  /**/
193
+ "triggers_immediate_eot" => "refunds,reversals", /* Immediate EOT? */
194
  "membership_eot_behavior" => "demote", /* Demote or delete Members? */
195
  "auto_eot_system_enabled" => "1")); /* 0|1|2. 1 = WP-Cron, 2 = Cron tab. */
196
  /*
215
  $value[$k] = trim (stripslashes ($v));
216
  /**/
217
  if (!isset ($default_options[$key]) && !preg_match ("/^pro_/", $key))
218
+ unset($GLOBALS["WS_PLUGIN__"]["s2member"]["o"][$key]);
219
  /**/
220
  else if ($key === "options_version" && (!is_string ($value) || !is_numeric ($value)))
221
  $value = $default_options[$key];
226
  else if ($key === "sec_encryption_key_history" && (!is_array ($value) || empty ($value)))
227
  $value = $default_options[$key];
228
  /**/
229
+ else if ($key === "max_ip_restriction" && (!is_string ($value) || !is_numeric ($value) || $value < 1 || $value > 100))
230
  $value = $default_options[$key];
231
  /**/
232
+ else if ($key === "max_ip_restriction_time" && (!is_string ($value) || !is_numeric ($value) || $value < 900 || $value > 31556926))
233
  $value = $default_options[$key];
234
  /**/
235
  else if ($key === "run_deactivation_routines" && (!is_string ($value) || !is_numeric ($value)))
397
  else if ($key === "specific_ids" && (!is_string ($value) || !($value = trim (preg_replace ("/[^0-9,]/", "", $value), ","))))
398
  $value = $default_options[$key];
399
  /**/
400
+ else if ($key === "triggers_immediate_eot" && (!is_string ($value) || !preg_match ("/^(none|refunds|reversals|refunds,reversals)$/", $value)))
401
+ $value = $default_options[$key];
402
+ /**/
403
  else if ($key === "membership_eot_behavior" && (!is_string ($value) || !preg_match ("/^(demote|delete)$/", $value)))
404
  $value = $default_options[$key];
405
  /**/
418
  return apply_filters_ref_array ("ws_plugin__s2member_options", array (&$GLOBALS["WS_PLUGIN__"]["s2member"]["o"]));
419
  }
420
  /**/
421
+ call_user_func("ws_plugin__s2member_configure_options_and_their_defaults");
422
  ?>
readme.txt CHANGED
@@ -1,7 +1,7 @@
1
  === s2Member ( Membership w/ PayPal® Integration ) ~ now Multisite compatible! ===
2
 
3
- Version: 3.2
4
- Stable tag: 3.2
5
  Framework: WS-P-3.0
6
 
7
  SSL Compatible: yes
@@ -74,7 +74,7 @@ s2Member supports Free Subscribers ( at Level #0 ), and up to four Primary Membe
74
 
75
  s2Member allows you to protect Pages, Posts, Tags, Categories, URIs, URI word fragments, URI Replacement Codes for BuddyPress, Specific Post/Page "Buy Now" Access, and even portions of content within Posts/Pages/themes/plugins. Everything is configurable through the s2Member Options Panel. This makes s2Member VERY easy to integrate into any WordPress®-powered site. With s2Member, you can also protect downloadable files, using special restrictions on how many downloads can occur within a certain amount of time; all based on Membership Level.
76
 
77
- Each Membership Level can have different restrictions, and you could even integrate Conditionals within your content based on Member Level. Advanced code samples are provided under `s2Member -> API Scripting -> Advanced Conditionals`. s2Member has been fully integrated with the Roles &amp; Capabilities that are already built into WordPress®. No new tables :-) It is designed to be completely seamless, without code bloat. We've carefully structured the entire framework, in order to maximize s2Member's ability to operate with other plugins installed.
78
 
79
  You can also sell Specific Post/Page Access ( membership not required ), using "Buy Now" buttons. You can even package multiple Posts/Pages together into one "Buy Now" transaction. Further details are provided under `s2Member -> PayPal® Buttons -> Special Posts/Pages`.
80
 
@@ -117,7 +117,7 @@ Yes, s2Member supports automation of account activation, welcome emails, confirm
117
  Yes, s2Member will work with PayPal® Auto-Return/PDT (Payment Data Transfer) `On`, and also with Auto-Return/PDT `Off`. If you enable Auto-Return, you MUST also enable PDT and supply s2Member with your Identity Token. If one is enabled, the other must also be enabled; and vice-versa. There is a place to enter your PayPal® Identity Token for PDT under `s2Member -> PayPal® Options`.
118
 
119
  = How does s2Member protect content from public access? =
120
- s2Member allows you to protect Pages, Posts, Tags, Categories, URIs, URI word fragments, URI Replacement Codes for BuddyPress, Specific Post/Page Access ( Buy Now! ), and even portions of content within Posts/Pages/themes/plugins using Advanced Conditionals. Everything is configurable through the s2Member Options Panel. This makes s2Member VERY easy to integrate into any WordPress®-powered site. With s2Member, you can also protect downloadable files, using special restrictions on how many downloads can occur within a certain amount of time. Each Membership Level can have different restrictions ( even Custom Capability Packages ). You can also integrate Conditionals within your content based on Member Level or Capabilities. Advanced code samples are provided under `s2Member -> API Scripting -> Advanced Conditionals`.
121
 
122
  = Does s2Member provide an API that I can connect to? =
123
  Yes, s2Member provides many *Advanced Scripting* techniques that are fully documented within its Option Panels. Code samples are provided for everything. There are several API functions that you can use, along with s2Member API Constants. This allows you to access many parts of its functionality, as well as specific Member information. Theme designers are welcome to integrate their themes/plugins with s2Member using the code samples that we provide under `s2Member -> API Scripting`. s2Member even provides API Notifications, which are an added layer of functionality. These are not to be confused with the IPN service. s2Member API Notifications make it easier to integrate back-office routines, affiliate programs, list servers, or any other 3rd-party application that should react to certain events.
@@ -170,6 +170,17 @@ Not yet. This is coming soon though. It will be included in a future release of
170
 
171
  == Changelog ==
172
 
 
 
 
 
 
 
 
 
 
 
 
173
  = 3.2 =
174
  * New Feature. s2Member now provides a small panel ( aka: `meta box` ) inside your Post/Page editing stations. This new panel makes it possible for you to restrict access to a Post/Page, or even a Custom Post Type ( on-the-fly ) without having to go back to your General Options panel all the time. Starting with s2Member v3.2+, you can also tell s2Member to require Custom Capabilities on a per Post/Page basis. So now, s2Member ( if you prefer ) can handle Custom Capabilities for you! Whenever you edit a Post/Page, you can tell s2Member to require certain Custom Capabilities that you type in, using comma delimited format. In other words, you will need to type in some of the trigger words that you used whenever you created your PayPal® Pro Forms and/or Standard PayPal® Buttons. This way your Members will have the proper Capabilities to view different kinds of content that you offer. All of this is optional.
175
  * Compatibility. s2Member, and also the s2Member Pro Module; have both been tested under WordPress® 3.0.1. Everything looks good - no conflicts.
1
  === s2Member ( Membership w/ PayPal® Integration ) ~ now Multisite compatible! ===
2
 
3
+ Version: 3.2.1
4
+ Stable tag: 3.2.1
5
  Framework: WS-P-3.0
6
 
7
  SSL Compatible: yes
74
 
75
  s2Member allows you to protect Pages, Posts, Tags, Categories, URIs, URI word fragments, URI Replacement Codes for BuddyPress, Specific Post/Page "Buy Now" Access, and even portions of content within Posts/Pages/themes/plugins. Everything is configurable through the s2Member Options Panel. This makes s2Member VERY easy to integrate into any WordPress®-powered site. With s2Member, you can also protect downloadable files, using special restrictions on how many downloads can occur within a certain amount of time; all based on Membership Level.
76
 
77
+ Each Membership Level can have different restrictions, and you could even integrate Conditionals within your content based on Member Level, or on Custom Capabilities. Both Simple ( Shortcode ) and Advanced ( PHP ) code samples are provided under `s2Member -> API Scripting`. s2Member has been fully integrated with Roles &amp; Capabilities that are already built into WordPress®. No new tables :-) It is designed to be completely seamless, without code bloat. We've carefully structured the entire framework, in order to maximize s2Member's ability to operate with other plugins installed.
78
 
79
  You can also sell Specific Post/Page Access ( membership not required ), using "Buy Now" buttons. You can even package multiple Posts/Pages together into one "Buy Now" transaction. Further details are provided under `s2Member -> PayPal® Buttons -> Special Posts/Pages`.
80
 
117
  Yes, s2Member will work with PayPal® Auto-Return/PDT (Payment Data Transfer) `On`, and also with Auto-Return/PDT `Off`. If you enable Auto-Return, you MUST also enable PDT and supply s2Member with your Identity Token. If one is enabled, the other must also be enabled; and vice-versa. There is a place to enter your PayPal® Identity Token for PDT under `s2Member -> PayPal® Options`.
118
 
119
  = How does s2Member protect content from public access? =
120
+ s2Member allows you to protect Pages, Posts, Tags, Categories, URIs, URI word fragments, URI Replacement Codes for BuddyPress, Specific Post/Page Access ( Buy Now! ), and even portions of content within Posts/Pages/themes/plugins using Simple ( Shortcode ) or Advanced ( PHP ) Conditionals. Everything is configurable through the s2Member Options Panel. This makes s2Member VERY easy to integrate into any WordPress®-powered site. With s2Member, you can also protect downloadable files, using special restrictions on how many downloads can occur within a certain amount of time. Each Membership Level can have different restrictions ( even Custom Capability Packages ). You can also integrate Conditionals within your content based on Capabilities. Both Simple and Advanced code samples are provided under `s2Member -> API Scripting`.
121
 
122
  = Does s2Member provide an API that I can connect to? =
123
  Yes, s2Member provides many *Advanced Scripting* techniques that are fully documented within its Option Panels. Code samples are provided for everything. There are several API functions that you can use, along with s2Member API Constants. This allows you to access many parts of its functionality, as well as specific Member information. Theme designers are welcome to integrate their themes/plugins with s2Member using the code samples that we provide under `s2Member -> API Scripting`. s2Member even provides API Notifications, which are an added layer of functionality. These are not to be confused with the IPN service. s2Member API Notifications make it easier to integrate back-office routines, affiliate programs, list servers, or any other 3rd-party application that should react to certain events.
170
 
171
  == Changelog ==
172
 
173
+ = 3.2.1 =
174
+ * Simple Conditionals. Staring with s2Member v3.2.1, "Simple Conditionals" are now available to you from within WordPress®, using Shortcodes that are fully compatible with both the Visual Editor, and also the HTML Tab in WordPress®. We've been through all of the documentation for s2Member, and updated ALL code samples to provide you with Shortcode equivalents. You can learn more about these new Shortcodes in your WP Dashboard, under: `s2Member -> API Scripting -> Simple Conditionals`. There are three new Shortcodes all together: `s2All`, `s2Any`, and `s2Get` - which allows you to pull all sorts of information from your WordPress® installation, without a single line of PHP code. All compatible with the Visual Editor. We also suggest a re-review of s2Member's API Constants, under: `s2Member -> API Scripting -> Constants`. This will NOT affect any existing Conditionals that you've written. Simple Conditionals are a NEW feature, and they'll have no affect on Advanced Conditionals; which have always been available for s2Member.
175
+ * Feature. s2Member now comes equipped with an advanced behavioral setting; specifically geared toward two special events ( Refunds/Reversals ). With s2Member v3.2.1+, you will find a new option which gives you more control over the way s2Member handles these two events. In your WP Dashboard, see: `s2Member -> PayPal® Options -> EOT Behavior`.
176
+ * Bug fix. s2Member's bbPress Bridge integration was using a hard-coded reference to `wp_capabilities`, instead of using an option call to determine the WordPress® table prefix that was needed for some installations. This was affecting installations of WordPress® that were using a non-standard `wp_` prefix. Corrected in s2Member v3.2.1. In addition, another bug was found, causing the error: `missing argument` in preg_replace. This has also been corrected with s2Member v3.2.1+.
177
+ * Bug fix. Invalid method `WP_User->hap_cap()`. This should have been `WP_User->has_cap()`. This was negatively affecting the new Custom Capabilities per-Post/Page introduced in the previous release of s2Member v3.2. This bug has been resolved with s2Member v3.2.1+.
178
+ * Hooks/Filters. Several new Hooks/Filters for Custom Fields. The upcoming release of s2Member v3.3 will include many new features for Custom Fields. In the mean time, these new Hooks/Filters integrated into `/includes/functions/register-access.inc.php` will make it easier for developers to maniuplate the display of Custom Fields. One such example is the Filter `ws_plugin__s2member_during_custom_registration_fields_during_custom_fields_display`.
179
+ * Forcing SSL w/ PayPal® Pro integration. The Custom Field `s2member_force_ssl=yes` is now more powerful. s2Member is now capable of forcing SSL ( i.e. `https://` ) on certain Posts/Pages, WITHOUT causing a site-wide conversion to https. In other words, s2Member can now buffer content without affecting href tags within that content, and/or in your navigation menus. Improvements to this routine make integrations of PayPal® Pro Forms easier than ever. Just add this Custom Field to any Post/Page that you want to force SSL on: `s2member_force_ssl=yes`. This is compatible with almost ANY WordPress® theme. Or, if your host requires a specific port number in the URL, use this instead: `s2member_force_ssl=443`. This Custom Field can be added in your Post/Page editing stations; inside WordPress®. ( * This is also compatible with the Quick Cache plugin for WordPress®, so that PayPal® Pro Forms can be cached initially for speed optimization. )
180
+ * IP Restrictions ( i.e. `s2Member -> General Options -> IP Restrictions` ), have been enhanced to provide better security against slower attacks that may span several weeks/months. s2Member's IP Restrictions are now capable of internal concurrency timeouts on a per-IP basis, as opposed to just a per entry-point basis. In addition, s2Member is now smarter about the way it enforces your configured Punishment Period. Some additional documentation on how IP Restrictions work, is now available in your s2Member General Options panel. There's nothing you need to change though; just review the updated details on this topic in your General Options panel for s2Member.
181
+ * Bug fix. The new Meta Box panel that was made available in the previous release of s2Member ( e.g. in your Post/Page editing stations ), was saving an empty array when there were no Custom Capabilities being specified/required. This is/was harmless; however, it WAS causing `s2member_ccaps_req` to appear in the Custom Fields drop-down menu for each Post/Page; even with no Custom Capabilities were required. This confusing behavior has been resolved with s2Member v3.2.1+.
182
+ * Bug fix. A new feature added in the previous release of s2Member, making it possible to Add A User through WordPress® ( including all s2Member fields initially, without a subsequent Edit ), was working with Multisite enabled, but broken WITHOUT Multisite enabled. This has been resolved with s2Member v3.2.1+. This feature is now working with or without Multisite Networking enabled.
183
+
184
  = 3.2 =
185
  * New Feature. s2Member now provides a small panel ( aka: `meta box` ) inside your Post/Page editing stations. This new panel makes it possible for you to restrict access to a Post/Page, or even a Custom Post Type ( on-the-fly ) without having to go back to your General Options panel all the time. Starting with s2Member v3.2+, you can also tell s2Member to require Custom Capabilities on a per Post/Page basis. So now, s2Member ( if you prefer ) can handle Custom Capabilities for you! Whenever you edit a Post/Page, you can tell s2Member to require certain Custom Capabilities that you type in, using comma delimited format. In other words, you will need to type in some of the trigger words that you used whenever you created your PayPal® Pro Forms and/or Standard PayPal® Buttons. This way your Members will have the proper Capabilities to view different kinds of content that you offer. All of this is optional.
186
  * Compatibility. s2Member, and also the s2Member Pro Module; have both been tested under WordPress® 3.0.1. Everything looks good - no conflicts.
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.2
13
- Stable tag: 3.2
14
  Framework: WS-P-3.0
15
 
16
  SSL Compatible: yes
@@ -48,10 +48,10 @@ if (realpath (__FILE__) === realpath ($_SERVER["SCRIPT_FILENAME"]))
48
  /*
49
  Define versions.
50
  */
51
- define ("WS_PLUGIN__S2MEMBER_VERSION", "3.2");
52
  define ("WS_PLUGIN__S2MEMBER_MIN_PHP_VERSION", "5.2");
53
  define ("WS_PLUGIN__S2MEMBER_MIN_WP_VERSION", "3.0");
54
- define ("WS_PLUGIN__S2MEMBER_MIN_PRO_VERSION", "1.2");
55
  /*
56
  Compatibility checks.
57
  */
9
  If not, see: <http://www.gnu.org/licenses/>.
10
  */
11
  /*
12
+ Version: 3.2.1
13
+ Stable tag: 3.2.1
14
  Framework: WS-P-3.0
15
 
16
  SSL Compatible: yes
48
  /*
49
  Define versions.
50
  */
51
+ define ("WS_PLUGIN__S2MEMBER_VERSION", "3.2.1");
52
  define ("WS_PLUGIN__S2MEMBER_MIN_PHP_VERSION", "5.2");
53
  define ("WS_PLUGIN__S2MEMBER_MIN_WP_VERSION", "3.0");
54
+ define ("WS_PLUGIN__S2MEMBER_MIN_PRO_VERSION", "1.2.1");
55
  /*
56
  Compatibility checks.
57
  */