Version Description
- Unique IP Restrictions. There is a new option under:
s2Member -> General Options -> IP Restrictionswhich allows a site owner to effectively disable IP Restrictions if they'd prefer. On some hosting platforms, the$_SERVER["REMOTE_ADDR"]variable ( i.e. a Users IP address ) is incorrectly set to the exact same thing for all visitors; which WILL prevent s2Member's IP Restrictions from working as intended. If you're on a hosting platform that has this bug, you may wish to disable IP Restrictions completely using s2Member v3.2.8+. Otherwise, under most circumstances we recommend that you leave IP Restrictions on.
Download this release
Release Info
| Developer | PriMoThemes |
| Plugin | |
| Version | 3.2.8 |
| Comparing to | |
| See all releases | |
Code changes from version 3.2.7 to 3.2.8
includes/functions/force-ssl.inc.php
CHANGED
|
@@ -95,7 +95,7 @@ if (!function_exists ("ws_plugin__s2member_check_force_ssl"))
|
|
| 95 |
return $c; /* Return string with conversions. */
|
| 96 |
}
|
| 97 |
/**/
|
| 98 |
-
ob_start ("_ws_plugin__s2member_force_ssl_buffer");
|
| 99 |
}
|
| 100 |
}
|
| 101 |
/**/
|
| 95 |
return $c; /* Return string with conversions. */
|
| 96 |
}
|
| 97 |
/**/
|
| 98 |
+
ob_start ("_ws_plugin__s2member_force_ssl_buffer");
|
| 99 |
}
|
| 100 |
}
|
| 101 |
/**/
|
includes/functions/ip-restrictions.inc.php
CHANGED
|
@@ -25,7 +25,7 @@ if (!function_exists ("ws_plugin__s2member_ip_restrictions_ok"))
|
|
| 25 |
do_action ("ws_plugin__s2member_before_ip_restrictions_ok", get_defined_vars ());
|
| 26 |
unset ($__refs, $__v); /* Unset defined __refs, __v. */
|
| 27 |
/**/
|
| 28 |
-
if ($
|
| 29 |
{
|
| 30 |
$prefix = "s2m_ipr_"; /* s2Member Transient prefix for all IP Restrictions. */
|
| 31 |
/**/
|
|
@@ -47,7 +47,7 @@ if (!function_exists ("ws_plugin__s2member_ip_restrictions_ok"))
|
|
| 47 |
/**/
|
| 48 |
if (get_transient ($transient_security_breach)) /* Has this restriction already been breached? */
|
| 49 |
{
|
| 50 |
-
ws_plugin__s2member_nocache_constants(true) . wp_clear_auth_cookie ();
|
| 51 |
/**/
|
| 52 |
do_action ("ws_plugin__s2member_during_ip_restrictions_ok_no", get_defined_vars ());
|
| 53 |
/**/
|
|
@@ -61,7 +61,7 @@ if (!function_exists ("ws_plugin__s2member_ip_restrictions_ok"))
|
|
| 61 |
}
|
| 62 |
else if (count ($entries) > $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["max_ip_restriction"])
|
| 63 |
{
|
| 64 |
-
ws_plugin__s2member_nocache_constants(true) . wp_clear_auth_cookie ();
|
| 65 |
/**/
|
| 66 |
set_transient ($transient_security_breach, 1, $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["max_ip_restriction_time"]);
|
| 67 |
/**/
|
| 25 |
do_action ("ws_plugin__s2member_before_ip_restrictions_ok", get_defined_vars ());
|
| 26 |
unset ($__refs, $__v); /* Unset defined __refs, __v. */
|
| 27 |
/**/
|
| 28 |
+
if ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["max_ip_restriction"] && $restriction)
|
| 29 |
{
|
| 30 |
$prefix = "s2m_ipr_"; /* s2Member Transient prefix for all IP Restrictions. */
|
| 31 |
/**/
|
| 47 |
/**/
|
| 48 |
if (get_transient ($transient_security_breach)) /* Has this restriction already been breached? */
|
| 49 |
{
|
| 50 |
+
ws_plugin__s2member_nocache_constants (true) . wp_clear_auth_cookie ();
|
| 51 |
/**/
|
| 52 |
do_action ("ws_plugin__s2member_during_ip_restrictions_ok_no", get_defined_vars ());
|
| 53 |
/**/
|
| 61 |
}
|
| 62 |
else if (count ($entries) > $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["max_ip_restriction"])
|
| 63 |
{
|
| 64 |
+
ws_plugin__s2member_nocache_constants (true) . wp_clear_auth_cookie ();
|
| 65 |
/**/
|
| 66 |
set_transient ($transient_security_breach, 1, $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["max_ip_restriction_time"]);
|
| 67 |
/**/
|
includes/functions/login-redirection.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 login redirections.
|
| 18 |
Attach to: add_action("wp_login");
|
|
@@ -21,7 +21,7 @@ if (!function_exists ("ws_plugin__s2member_login_redirect"))
|
|
| 21 |
{
|
| 22 |
function ws_plugin__s2member_login_redirect ($username = FALSE)
|
| 23 |
{
|
| 24 |
-
eval('foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;');
|
| 25 |
do_action ("ws_plugin__s2member_before_login_redirect", get_defined_vars ());
|
| 26 |
unset ($__refs, $__v); /* Unset defined __refs, __v. */
|
| 27 |
/**/
|
|
@@ -29,30 +29,30 @@ if (!function_exists ("ws_plugin__s2member_login_redirect"))
|
|
| 29 |
/* This additional check was added in case wp_signon() fires this event with empty $_POST credentials.
|
| 30 |
In this rare case, we can check to see if WordPress® is remembering a previously logged in User. */
|
| 31 |
/**/
|
| 32 |
-
if (!is_object ($user = new WP_User ($username)) || !($user_id = $user->ID) || !$user->has_cap ("edit_posts"))
|
| 33 |
{
|
| 34 |
-
eval('foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;');
|
| 35 |
do_action ("ws_plugin__s2member_during_login_redirect", get_defined_vars ());
|
| 36 |
unset ($__refs, $__v); /* Unset defined __refs, __v. */
|
| 37 |
/**/
|
| 38 |
if ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["custom_reg_password"] && function_exists ("ws_plugin__s2member_generate_password"))
|
| 39 |
{
|
| 40 |
-
delete_user_setting("default_password_nag"); /* setcookie() */
|
| 41 |
update_user_option ($user_id, "default_password_nag", false, true);
|
| 42 |
}
|
| 43 |
/**/
|
| 44 |
if (strtolower ($username) === "demo" || ws_plugin__s2member_ip_restrictions_ok ($_SERVER["REMOTE_ADDR"], strtolower ($username)))
|
| 45 |
{
|
| 46 |
if ($special_redirection_url = ws_plugin__s2member_login_redirection_url ($user))
|
| 47 |
-
wp_redirect($special_redirection_url);
|
| 48 |
/**/
|
| 49 |
-
else wp_redirect(get_page_link ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["login_welcome_page"]));
|
| 50 |
}
|
| 51 |
/**/
|
| 52 |
exit ();
|
| 53 |
}
|
| 54 |
/**/
|
| 55 |
-
eval('foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;');
|
| 56 |
do_action ("ws_plugin__s2member_after_login_redirect", get_defined_vars ());
|
| 57 |
unset ($__refs, $__v); /* Unset defined __refs, __v. */
|
| 58 |
/**/
|
|
@@ -66,7 +66,7 @@ if (!function_exists ("ws_plugin__s2member_login_redirection_url"))
|
|
| 66 |
{
|
| 67 |
function ws_plugin__s2member_login_redirection_url ($user = FALSE)
|
| 68 |
{
|
| 69 |
-
eval('foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;');
|
| 70 |
do_action ("ws_plugin__s2member_before_login_redirection_url", get_defined_vars ());
|
| 71 |
unset ($__refs, $__v); /* Unset defined __refs, __v. */
|
| 72 |
/**/
|
|
@@ -82,7 +82,7 @@ if (!function_exists ("ws_plugin__s2member_fill_login_redirect_rc_vars"))
|
|
| 82 |
{
|
| 83 |
function ws_plugin__s2member_fill_login_redirect_rc_vars ($url = FALSE, $user = FALSE)
|
| 84 |
{
|
| 85 |
-
eval('foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;');
|
| 86 |
do_action ("ws_plugin__s2member_before_fill_login_redirect_rc_vars", get_defined_vars ());
|
| 87 |
unset ($__refs, $__v); /* Unset defined __refs, __v. */
|
| 88 |
/**/
|
|
@@ -105,7 +105,7 @@ if (!function_exists ("ws_plugin__s2member_login_redirection_uri"))
|
|
| 105 |
{
|
| 106 |
function ws_plugin__s2member_login_redirection_uri ($user = FALSE)
|
| 107 |
{
|
| 108 |
-
eval('foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;');
|
| 109 |
do_action ("ws_plugin__s2member_before_login_redirection_uri", get_defined_vars ());
|
| 110 |
unset ($__refs, $__v); /* Unset defined __refs, __v. */
|
| 111 |
/**/
|
| 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 login redirections.
|
| 18 |
Attach to: add_action("wp_login");
|
| 21 |
{
|
| 22 |
function ws_plugin__s2member_login_redirect ($username = FALSE)
|
| 23 |
{
|
| 24 |
+
eval ('foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;');
|
| 25 |
do_action ("ws_plugin__s2member_before_login_redirect", get_defined_vars ());
|
| 26 |
unset ($__refs, $__v); /* Unset defined __refs, __v. */
|
| 27 |
/**/
|
| 29 |
/* This additional check was added in case wp_signon() fires this event with empty $_POST credentials.
|
| 30 |
In this rare case, we can check to see if WordPress® is remembering a previously logged in User. */
|
| 31 |
/**/
|
| 32 |
+
if (!is_object ($user = new WP_User ($username)) || ! ($user_id = $user->ID) || !$user->has_cap ("edit_posts"))
|
| 33 |
{
|
| 34 |
+
eval ('foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;');
|
| 35 |
do_action ("ws_plugin__s2member_during_login_redirect", get_defined_vars ());
|
| 36 |
unset ($__refs, $__v); /* Unset defined __refs, __v. */
|
| 37 |
/**/
|
| 38 |
if ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["custom_reg_password"] && function_exists ("ws_plugin__s2member_generate_password"))
|
| 39 |
{
|
| 40 |
+
delete_user_setting ("default_password_nag"); /* setcookie() */
|
| 41 |
update_user_option ($user_id, "default_password_nag", false, true);
|
| 42 |
}
|
| 43 |
/**/
|
| 44 |
if (strtolower ($username) === "demo" || ws_plugin__s2member_ip_restrictions_ok ($_SERVER["REMOTE_ADDR"], strtolower ($username)))
|
| 45 |
{
|
| 46 |
if ($special_redirection_url = ws_plugin__s2member_login_redirection_url ($user))
|
| 47 |
+
wp_redirect ($special_redirection_url);
|
| 48 |
/**/
|
| 49 |
+
else wp_redirect (get_page_link ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["login_welcome_page"]));
|
| 50 |
}
|
| 51 |
/**/
|
| 52 |
exit ();
|
| 53 |
}
|
| 54 |
/**/
|
| 55 |
+
eval ('foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;');
|
| 56 |
do_action ("ws_plugin__s2member_after_login_redirect", get_defined_vars ());
|
| 57 |
unset ($__refs, $__v); /* Unset defined __refs, __v. */
|
| 58 |
/**/
|
| 66 |
{
|
| 67 |
function ws_plugin__s2member_login_redirection_url ($user = FALSE)
|
| 68 |
{
|
| 69 |
+
eval ('foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;');
|
| 70 |
do_action ("ws_plugin__s2member_before_login_redirection_url", get_defined_vars ());
|
| 71 |
unset ($__refs, $__v); /* Unset defined __refs, __v. */
|
| 72 |
/**/
|
| 82 |
{
|
| 83 |
function ws_plugin__s2member_fill_login_redirect_rc_vars ($url = FALSE, $user = FALSE)
|
| 84 |
{
|
| 85 |
+
eval ('foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;');
|
| 86 |
do_action ("ws_plugin__s2member_before_fill_login_redirect_rc_vars", get_defined_vars ());
|
| 87 |
unset ($__refs, $__v); /* Unset defined __refs, __v. */
|
| 88 |
/**/
|
| 105 |
{
|
| 106 |
function ws_plugin__s2member_login_redirection_uri ($user = FALSE)
|
| 107 |
{
|
| 108 |
+
eval ('foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;');
|
| 109 |
do_action ("ws_plugin__s2member_before_login_redirection_uri", get_defined_vars ());
|
| 110 |
unset ($__refs, $__v); /* Unset defined __refs, __v. */
|
| 111 |
/**/
|
includes/menu-pages/options.inc.php
CHANGED
|
@@ -1411,6 +1411,7 @@ if (apply_filters ("ws_plugin__s2member_during_options_page_during_left_sections
|
|
| 1411 |
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";
|
| 1412 |
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";
|
| 1413 |
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";
|
|
|
|
| 1414 |
echo '</select><br />' . "\n";
|
| 1415 |
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";
|
| 1416 |
echo '</td>' . "\n";
|
| 1411 |
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";
|
| 1412 |
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";
|
| 1413 |
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";
|
| 1414 |
+
echo '<option value="0"' . ( ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["max_ip_restriction"] == 0) ? ' selected="selected"' : '') . '>Allow infinite IPs ( all IP restrictions are effectively disabled )</option>' . "\n";
|
| 1415 |
echo '</select><br />' . "\n";
|
| 1416 |
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";
|
| 1417 |
echo '</td>' . "\n";
|
includes/syscon.inc.php
CHANGED
|
@@ -271,7 +271,7 @@ if (!function_exists ("ws_plugin__s2member_configure_options_and_their_defaults"
|
|
| 271 |
else if ($key === "sec_encryption_key_history" && (!is_array ($value) || empty ($value)))
|
| 272 |
$value = $default_options[$key];
|
| 273 |
/**/
|
| 274 |
-
else if ($key === "max_ip_restriction" && (!is_string ($value) || !is_numeric ($value) || $value <
|
| 275 |
$value = $default_options[$key];
|
| 276 |
/**/
|
| 277 |
else if ($key === "max_ip_restriction_time" && (!is_string ($value) || !is_numeric ($value) || $value < 900 || $value > 31556926))
|
| 271 |
else if ($key === "sec_encryption_key_history" && (!is_array ($value) || empty ($value)))
|
| 272 |
$value = $default_options[$key];
|
| 273 |
/**/
|
| 274 |
+
else if ($key === "max_ip_restriction" && (!is_string ($value) || !is_numeric ($value) || $value < 0 || $value > 100))
|
| 275 |
$value = $default_options[$key];
|
| 276 |
/**/
|
| 277 |
else if ($key === "max_ip_restriction_time" && (!is_string ($value) || !is_numeric ($value) || $value < 900 || $value > 31556926))
|
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.1
|
| 6 |
|
| 7 |
SSL Compatible: yes
|
|
@@ -170,6 +170,9 @@ Not yet. This is coming soon though. It will be included in a future release of
|
|
| 170 |
|
| 171 |
== Changelog ==
|
| 172 |
|
|
|
|
|
|
|
|
|
|
| 173 |
= 3.2.7 =
|
| 174 |
* Custom Fields ( new features ). s2Member is now equipped with a VERY powerful set of features; designed to extend the functionality of Custom Fields. s2Member now supports Text Fields ( single/multi-line ), Checkboxes ( single/multi-option ), Radio Buttons ( single/multi-option ), and Dropdowns ( single/multi-option ). In addition, with s2Member it is now possible to configure Custom Fields differently for each Membership Level. Other tools: including Validation Formats and Visibility are also available. For full details, check your Dashboard under: `s2Member -> General Options -> Custom Fields`.
|
| 175 |
* Attn Developers ( before upgrading ). Hooks/Filters ( e.g. those related to Custom Fields ) have been modified in ways that may break custom scripts you've created to work with previous versions of s2Member. We suggest dropping all of your Hooks/Filters related to Custom Fields. Instead, use the NEW improved tools w/s2Member v3.2.7+. Please see: `s2Member -> General Options -> Custom Fields`.
|
| 1 |
=== s2Member ( Membership w/ PayPal® Integration ) ~ now Multisite compatible! ===
|
| 2 |
|
| 3 |
+
Version: 3.2.8
|
| 4 |
+
Stable tag: 3.2.8
|
| 5 |
Framework: WS-P-3.1
|
| 6 |
|
| 7 |
SSL Compatible: yes
|
| 170 |
|
| 171 |
== Changelog ==
|
| 172 |
|
| 173 |
+
= 3.2.8 =
|
| 174 |
+
* Unique IP Restrictions. There is a new option under: `s2Member -> General Options -> IP Restrictions` which allows a site owner to effectively disable IP Restrictions if they'd prefer. On some hosting platforms, the `$_SERVER["REMOTE_ADDR"]` variable ( i.e. a Users IP address ) is incorrectly set to the exact same thing for all visitors; which WILL prevent s2Member's IP Restrictions from working as intended. If you're on a hosting platform that has this bug, you may wish to disable IP Restrictions completely using s2Member v3.2.8+. Otherwise, under most circumstances we recommend that you leave IP Restrictions on.
|
| 175 |
+
|
| 176 |
= 3.2.7 =
|
| 177 |
* Custom Fields ( new features ). s2Member is now equipped with a VERY powerful set of features; designed to extend the functionality of Custom Fields. s2Member now supports Text Fields ( single/multi-line ), Checkboxes ( single/multi-option ), Radio Buttons ( single/multi-option ), and Dropdowns ( single/multi-option ). In addition, with s2Member it is now possible to configure Custom Fields differently for each Membership Level. Other tools: including Validation Formats and Visibility are also available. For full details, check your Dashboard under: `s2Member -> General Options -> Custom Fields`.
|
| 178 |
* Attn Developers ( before upgrading ). Hooks/Filters ( e.g. those related to Custom Fields ) have been modified in ways that may break custom scripts you've created to work with previous versions of s2Member. We suggest dropping all of your Hooks/Filters related to Custom Fields. Instead, use the NEW improved tools w/s2Member v3.2.7+. Please see: `s2Member -> General Options -> Custom Fields`.
|
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.1
|
| 15 |
|
| 16 |
SSL Compatible: yes
|
|
@@ -48,7 +48,7 @@ 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.7");
|
| 9 |
If not, see: <http://www.gnu.org/licenses/>.
|
| 10 |
*/
|
| 11 |
/*
|
| 12 |
+
Version: 3.2.8
|
| 13 |
+
Stable tag: 3.2.8
|
| 14 |
Framework: WS-P-3.1
|
| 15 |
|
| 16 |
SSL Compatible: yes
|
| 48 |
/*
|
| 49 |
Define versions.
|
| 50 |
*/
|
| 51 |
+
define ("WS_PLUGIN__S2MEMBER_VERSION", "3.2.8");
|
| 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.7");
|
