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

Version Description

No major changes. Just a few compatiblity improvements.

Download this release

Release Info

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

Code changes from version 3.0 to 3.0.1

includes/functions/auto-eots.inc.php CHANGED
@@ -14,7 +14,7 @@ Direct access denial.
14
  if (realpath (__FILE__) === realpath ($_SERVER["SCRIPT_FILENAME"]))
15
  exit;
16
  /*
17
- Function processed by WP_Cron. This handles Auto-EOTs.
18
  If you have a HUGE user-base, increase the max eots per process.
19
  To increase, use: add_filter("s2member_auto_eots_per_process");
20
  */
@@ -38,7 +38,7 @@ function ws_plugin__s2member_auto_eot_system ($per_process = 10)
38
  /**/
39
  $user = new WP_User ($user_id); /* Acquire user object. */
40
  /**/
41
- delete_usermeta ($user_id, "s2member_auto_eot_time"); /* Always remove this. */
42
  /* Removing this prevents re-runs on non WP Roles. Which are scanned for next. */
43
  /**/
44
  if (!ws_plugin__s2member_user_has_wp_role ($user)) /* Non WP Roles. */
@@ -73,8 +73,8 @@ function ws_plugin__s2member_auto_eot_system ($per_process = 10)
73
  if (($url = preg_replace ("/%%user_full_name%%/i", urlencode (trim ($user->first_name . " " . $user->last_name)), $url)))
74
  if (($url = preg_replace ("/%%user_email%%/i", urlencode ($user->user_email), $url)))
75
  /**/
76
- if (($url = trim ($url))) /* Make sure it is not empty. */
77
- ws_plugin__s2member_curlpsr ($url, "s2member=1");
78
  }
79
  /**/
80
  do_action ("s2member_during_auto_eot_system_during_demote");
@@ -98,7 +98,30 @@ function ws_plugin__s2member_auto_eot_system ($per_process = 10)
98
  return;
99
  }
100
  /*
101
- Extends the WP_Cron schedules to support 10 minute intervals.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
102
  Attach to: add_filter("cron_schedules");
103
  */
104
  function ws_plugin__s2member_extend_cron_schedules ($schedules = array ())
@@ -114,24 +137,39 @@ Adds a scheduled task for s2Member's Auto-EOT System.
114
  */
115
  function ws_plugin__s2member_add_auto_eot_system ()
116
  {
117
- if (!ws_plugin__s2member_remove_auto_eot_system ())
 
 
118
  {
119
- return false; /* Do not proceed if unable to remove first. */
120
  }
121
- else /* Otherwise, we can safely schedule the event and return true. */
122
  {
123
  wp_schedule_event (time (), "every10m", "s2member_auto_eot_system");
124
  /**/
125
- return true;
 
 
 
 
126
  }
127
  }
128
  /*
129
- Remove scheduled tasks for s2Member's Auto-EOT System.
130
  */
131
- function ws_plugin__s2member_remove_auto_eot_system ()
132
  {
133
- wp_clear_scheduled_hook ("s2member_auto_eot_system");
134
  /**/
135
- return true;
 
 
 
 
 
 
 
 
 
136
  }
137
  ?>
14
  if (realpath (__FILE__) === realpath ($_SERVER["SCRIPT_FILENAME"]))
15
  exit;
16
  /*
17
+ Function processed by WP-Cron. This handles Auto-EOTs.
18
  If you have a HUGE user-base, increase the max eots per process.
19
  To increase, use: add_filter("s2member_auto_eots_per_process");
20
  */
38
  /**/
39
  $user = new WP_User ($user_id); /* Acquire user object. */
40
  /**/
41
+ delete_usermeta ($user_id, "s2member_auto_eot_time"); /* Always delete this. */
42
  /* Removing this prevents re-runs on non WP Roles. Which are scanned for next. */
43
  /**/
44
  if (!ws_plugin__s2member_user_has_wp_role ($user)) /* Non WP Roles. */
73
  if (($url = preg_replace ("/%%user_full_name%%/i", urlencode (trim ($user->first_name . " " . $user->last_name)), $url)))
74
  if (($url = preg_replace ("/%%user_email%%/i", urlencode ($user->user_email), $url)))
75
  /**/
76
+ if (($url = trim ($url))) /* Empty? */
77
+ ws_plugin__s2member_remote ($url);
78
  }
79
  /**/
80
  do_action ("s2member_during_auto_eot_system_during_demote");
98
  return;
99
  }
100
  /*
101
+ This function allows the Auto-EOT Sytem to be
102
+ processed through a server-side Cron Job.
103
+ Attach to: add_action("init");
104
+ */
105
+ function ws_plugin__s2member_auto_eot_system_via_cron ()
106
+ {
107
+ do_action ("s2member_before_auto_eot_system_via_cron");
108
+ /**/
109
+ if ($_GET["s2member_auto_eot_system_via_cron"]) /* Being called through HTTP? */
110
+ {
111
+ if ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["auto_eot_system_enabled"]) /* Enabled? */
112
+ {
113
+ ws_plugin__s2member_auto_eot_system ();
114
+ /**/
115
+ do_action ("s2member_during_auto_eot_system_via_cron");
116
+ }
117
+ /**/
118
+ exit; /* Exit. */
119
+ }
120
+ /**/
121
+ do_action ("s2member_after_auto_eot_system_via_cron");
122
+ }
123
+ /*
124
+ Extends the WP-Cron schedules to support 10 minute intervals.
125
  Attach to: add_filter("cron_schedules");
126
  */
127
  function ws_plugin__s2member_extend_cron_schedules ($schedules = array ())
137
  */
138
  function ws_plugin__s2member_add_auto_eot_system ()
139
  {
140
+ do_action ("s2member_before_add_auto_eot_system");
141
+ /**/
142
+ if (!ws_plugin__s2member_delete_auto_eot_system ())
143
  {
144
+ return apply_filters ("s2member_add_auto_eot_system", false);
145
  }
146
+ else if (function_exists ("wp_cron")) /* Otherwise, we can schedule. */
147
  {
148
  wp_schedule_event (time (), "every10m", "s2member_auto_eot_system");
149
  /**/
150
+ return apply_filters ("s2member_add_auto_eot_system", true);
151
+ }
152
+ else /* Otherwise, it would appear that WP-Cron is not available. */
153
+ {
154
+ return apply_filters ("s2member_add_auto_eot_system", false);
155
  }
156
  }
157
  /*
158
+ Delete scheduled tasks for s2Member's Auto-EOT System.
159
  */
160
+ function ws_plugin__s2member_delete_auto_eot_system ()
161
  {
162
+ do_action ("s2member_before_delete_auto_eot_system");
163
  /**/
164
+ if (function_exists ("wp_cron"))
165
+ {
166
+ wp_clear_scheduled_hook ("s2member_auto_eot_system");
167
+ /**/
168
+ return apply_filters ("s2member_delete_auto_eot_system", true);
169
+ }
170
+ else /* Otherwise, it would appear that WP-Cron is not available. */
171
+ {
172
+ return apply_filters ("s2member_delete_auto_eot_system", false);
173
+ }
174
  }
175
  ?>
includes/functions/menu-pages.inc.php CHANGED
@@ -48,10 +48,10 @@ function ws_plugin__s2member_update_all_options ()
48
  /**/
49
  update_option ("ws_plugin__s2member_options", $options) . update_option ("ws_plugin__s2member_cache", array ());
50
  /**/
51
- if ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["auto_eot_system_enabled"])
52
- ws_plugin__s2member_add_auto_eot_system (); /* Uses WP_Cron. */
53
- else /* Otherwise, the Auto-EOT System needs to be disabled. */
54
- ws_plugin__s2member_remove_auto_eot_system ();
55
  /**/
56
  do_action ("s2member_during_update_all_options"); /* Purposely after the update. */
57
  /**/
48
  /**/
49
  update_option ("ws_plugin__s2member_options", $options) . update_option ("ws_plugin__s2member_cache", array ());
50
  /**/
51
+ if ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["auto_eot_system_enabled"] == 1)
52
+ ws_plugin__s2member_add_auto_eot_system (); /* 1 == WP-Cron. */
53
+ else /* Otherwise, the Auto-EOT System via WP-Cron is disabled. */
54
+ ws_plugin__s2member_delete_auto_eot_system ();
55
  /**/
56
  do_action ("s2member_during_update_all_options"); /* Purposely after the update. */
57
  /**/
includes/functions/paypal-notify.inc.php CHANGED
@@ -93,8 +93,8 @@ function ws_plugin__s2member_paypal_notify ()
93
  if (($url = preg_replace ("/%%full_name%%/i", urlencode (trim ($paypal["first_name"] . " " . $paypal["last_name"])), $url)))
94
  if (($url = preg_replace ("/%%payer_email%%/i", urlencode ($paypal["payer_email"]), $url)))
95
  /**/
96
- if (($url = trim ($url))) /* Make sure it is not empty. */
97
- ws_plugin__s2member_curlpsr ($url, "s2member=1");
98
  /**/
99
  $paypal["s2member_log"][] = "Specific Post/Page Access Notification URLs have been processed.";
100
  }
@@ -264,8 +264,8 @@ function ws_plugin__s2member_paypal_notify ()
264
  if (($url = preg_replace ("/%%full_name%%/i", urlencode (trim ($paypal["first_name"] . " " . $paypal["last_name"])), $url)))
265
  if (($url = preg_replace ("/%%payer_email%%/i", urlencode ($paypal["payer_email"]), $url)))
266
  /**/
267
- if (($url = trim ($url))) /* Make sure it is not empty. */
268
- ws_plugin__s2member_curlpsr ($url, "s2member=1");
269
  /**/
270
  $paypal["s2member_log"][] = "Signup Notification URLs have been processed.";
271
  }
@@ -298,8 +298,8 @@ function ws_plugin__s2member_paypal_notify ()
298
  if (($url = preg_replace ("/%%full_name%%/i", urlencode (trim ($paypal["first_name"] . " " . $paypal["last_name"])), $url)))
299
  if (($url = preg_replace ("/%%payer_email%%/i", urlencode ($paypal["payer_email"]), $url)))
300
  /**/
301
- if (($url = trim ($url))) /* Make sure it is not empty. */
302
- ws_plugin__s2member_curlpsr ($url, "s2member=1");
303
  /**/
304
  $paypal["s2member_log"][] = "Payment Notification URLs have been processed.";
305
  }
@@ -397,8 +397,8 @@ function ws_plugin__s2member_paypal_notify ()
397
  if (($url = preg_replace ("/%%full_name%%/i", urlencode (trim ($paypal["first_name"] . " " . $paypal["last_name"])), $url)))
398
  if (($url = preg_replace ("/%%payer_email%%/i", urlencode ($paypal["payer_email"]), $url)))
399
  /**/
400
- if (($url = trim ($url))) /* Make sure it is not empty. */
401
- ws_plugin__s2member_curlpsr ($url, "s2member=1");
402
  /**/
403
  $paypal["s2member_log"][] = "Payment Notification URLs have been processed.";
404
  }
@@ -506,8 +506,8 @@ function ws_plugin__s2member_paypal_notify ()
506
  if (($url = preg_replace ("/%%user_full_name%%/i", urlencode (trim ($user->first_name . " " . $user->last_name)), $url)))
507
  if (($url = preg_replace ("/%%user_email%%/i", urlencode ($user->user_email), $url)))
508
  /**/
509
- if (($url = trim ($url))) /* Make sure it is not empty. */
510
- ws_plugin__s2member_curlpsr ($url, "s2member=1");
511
  /**/
512
  $paypal["s2member_log"][] = "EOT/Deletion Notification URLs have been processed.";
513
  }
@@ -576,8 +576,8 @@ function ws_plugin__s2member_paypal_notify ()
576
  if (($url = preg_replace ("/%%full_name%%/i", urlencode (trim ($paypal["first_name"] . " " . $paypal["last_name"])), $url)))
577
  if (($url = preg_replace ("/%%payer_email%%/i", urlencode ($paypal["payer_email"]), $url)))
578
  /**/
579
- if (($url = trim ($url))) /* Make sure it is not empty. */
580
- ws_plugin__s2member_curlpsr ($url, "s2member=1");
581
  /**/
582
  $paypal["s2member_log"][] = "Refund/Reversal Notification URLs have been processed.";
583
  }
93
  if (($url = preg_replace ("/%%full_name%%/i", urlencode (trim ($paypal["first_name"] . " " . $paypal["last_name"])), $url)))
94
  if (($url = preg_replace ("/%%payer_email%%/i", urlencode ($paypal["payer_email"]), $url)))
95
  /**/
96
+ if (($url = trim ($url))) /* Empty? */
97
+ ws_plugin__s2member_remote ($url);
98
  /**/
99
  $paypal["s2member_log"][] = "Specific Post/Page Access Notification URLs have been processed.";
100
  }
264
  if (($url = preg_replace ("/%%full_name%%/i", urlencode (trim ($paypal["first_name"] . " " . $paypal["last_name"])), $url)))
265
  if (($url = preg_replace ("/%%payer_email%%/i", urlencode ($paypal["payer_email"]), $url)))
266
  /**/
267
+ if (($url = trim ($url))) /* Empty? */
268
+ ws_plugin__s2member_remote ($url);
269
  /**/
270
  $paypal["s2member_log"][] = "Signup Notification URLs have been processed.";
271
  }
298
  if (($url = preg_replace ("/%%full_name%%/i", urlencode (trim ($paypal["first_name"] . " " . $paypal["last_name"])), $url)))
299
  if (($url = preg_replace ("/%%payer_email%%/i", urlencode ($paypal["payer_email"]), $url)))
300
  /**/
301
+ if (($url = trim ($url))) /* Empty? */
302
+ ws_plugin__s2member_remote ($url);
303
  /**/
304
  $paypal["s2member_log"][] = "Payment Notification URLs have been processed.";
305
  }
397
  if (($url = preg_replace ("/%%full_name%%/i", urlencode (trim ($paypal["first_name"] . " " . $paypal["last_name"])), $url)))
398
  if (($url = preg_replace ("/%%payer_email%%/i", urlencode ($paypal["payer_email"]), $url)))
399
  /**/
400
+ if (($url = trim ($url))) /* Empty? */
401
+ ws_plugin__s2member_remote ($url);
402
  /**/
403
  $paypal["s2member_log"][] = "Payment Notification URLs have been processed.";
404
  }
506
  if (($url = preg_replace ("/%%user_full_name%%/i", urlencode (trim ($user->first_name . " " . $user->last_name)), $url)))
507
  if (($url = preg_replace ("/%%user_email%%/i", urlencode ($user->user_email), $url)))
508
  /**/
509
+ if (($url = trim ($url))) /* Empty? */
510
+ ws_plugin__s2member_remote ($url);
511
  /**/
512
  $paypal["s2member_log"][] = "EOT/Deletion Notification URLs have been processed.";
513
  }
576
  if (($url = preg_replace ("/%%full_name%%/i", urlencode (trim ($paypal["first_name"] . " " . $paypal["last_name"])), $url)))
577
  if (($url = preg_replace ("/%%payer_email%%/i", urlencode ($paypal["payer_email"]), $url)))
578
  /**/
579
+ if (($url = trim ($url))) /* Empty? */
580
+ ws_plugin__s2member_remote ($url);
581
  /**/
582
  $paypal["s2member_log"][] = "Refund/Reversal Notification URLs have been processed.";
583
  }
includes/functions/paypal-utilities.inc.php CHANGED
@@ -24,14 +24,13 @@ function ws_plugin__s2member_paypal_postvars ()
24
  {
25
  if ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["paypal_identity_token"])
26
  {
27
- $postback = "cmd=_notify-synch";
28
- /**/
29
- $postback .= "&tx=" . urlencode ($_GET["tx"]);
30
- $postback .= "&at=" . urlencode ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["paypal_identity_token"]);
31
  /**/
32
  $endpoint = ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["paypal_sandbox"]) ? "www.sandbox.paypal.com" : "www.paypal.com";
33
  /**/
34
- if (preg_match ("/^SUCCESS/i", ($response = trim (ws_plugin__s2member_curlpsr ("https://" . $endpoint . "/cgi-bin/webscr", $postback)))))
35
  {
36
  foreach (preg_split ("/[\r\n]+/", preg_replace ("/^SUCCESS/i", "", $response)) as $varline)
37
  {
@@ -48,17 +47,15 @@ function ws_plugin__s2member_paypal_postvars ()
48
  }
49
  else if (is_array ($postvars = stripslashes_deep ($_POST)))
50
  {
51
- $postback = "cmd=_notify-validate";
52
- /**/
53
- foreach ($postvars as $key => $value)
54
- $postback .= "&" . $key . "=" . urlencode ($value);
55
  /**/
56
  foreach ($postvars as $key => $value)
57
  $postvars[$key] = trim ($value);
58
  /**/
59
  $endpoint = ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["paypal_sandbox"]) ? "www.sandbox.paypal.com" : "www.paypal.com";
60
  /**/
61
- if (strtolower (trim (ws_plugin__s2member_curlpsr ("https://" . $endpoint . "/cgi-bin/webscr", $postback))) === "verified")
62
  {
63
  return apply_filters ("s2member_paypal_postvars", $postvars);
64
  }
24
  {
25
  if ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["paypal_identity_token"])
26
  {
27
+ $postback["tx"] = $_GET["tx"];
28
+ $postback["cmd"] = "_notify-synch";
29
+ $postback["at"] = $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["paypal_identity_token"];
 
30
  /**/
31
  $endpoint = ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["paypal_sandbox"]) ? "www.sandbox.paypal.com" : "www.paypal.com";
32
  /**/
33
+ if (preg_match ("/^SUCCESS/i", ($response = trim (ws_plugin__s2member_remote ("https://" . $endpoint . "/cgi-bin/webscr", $postback)))))
34
  {
35
  foreach (preg_split ("/[\r\n]+/", preg_replace ("/^SUCCESS/i", "", $response)) as $varline)
36
  {
47
  }
48
  else if (is_array ($postvars = stripslashes_deep ($_POST)))
49
  {
50
+ $postback = $postvars;
51
+ $postback["cmd"] = "_notify-validate";
 
 
52
  /**/
53
  foreach ($postvars as $key => $value)
54
  $postvars[$key] = trim ($value);
55
  /**/
56
  $endpoint = ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["paypal_sandbox"]) ? "www.sandbox.paypal.com" : "www.paypal.com";
57
  /**/
58
+ if (strtolower (trim (ws_plugin__s2member_remote ("https://" . $endpoint . "/cgi-bin/webscr", $postback))) === "verified")
59
  {
60
  return apply_filters ("s2member_paypal_postvars", $postvars);
61
  }
includes/functions/register-access.inc.php CHANGED
@@ -184,9 +184,9 @@ function ws_plugin__s2member_register_link_gen ($subscr_id = FALSE, $custom = FA
184
  $register = ws_plugin__s2member_encrypt ("subscr_id_custom_item_number:.:|:.:" . $subscr_id . ":.:|:.:" . $custom . ":.:|:.:" . $item_number);
185
  $register_link = add_query_arg ("s2member_register", $register, get_bloginfo ("url") . "/");
186
  /**/
187
- if ($shrink && ($tinyurl = @file_get_contents ("http://tinyurl.com/api-create.php?url=" . rawurlencode ($register_link))))
188
  return apply_filters ("s2member_register_link_gen", $tinyurl); /* tinyURL is easier to work with. */
189
- else /* Else use the long one; tinyURL fails if allow_url_fopen = no. */
190
  return apply_filters ("s2member_register_link_gen", $register_link);
191
  }
192
  /**/
@@ -281,7 +281,7 @@ function ws_plugin__s2member_configure_user_registration ($user_id = FALSE)
281
  if (($transient = md5 ("s2member_transient_ipn_subscr_payment_" . $subscr_id)) && is_array ($subscr_payment = get_transient ($transient)))
282
  {
283
  $proxy = array ("s2member_paypal_notify" => "1", "s2member_paypal_proxy" => "s2member_transient_ipn_subscr_payment");
284
- ws_plugin__s2member_curlpsr (add_query_arg ($proxy, get_bloginfo ("url")), $subscr_payment);
285
  delete_transient ($transient);
286
  }
287
  /**/
@@ -379,8 +379,8 @@ function ws_plugin__s2member_configure_user_registration ($user_id = FALSE)
379
  if (($url = preg_replace ("/%%user_email%%/i", urlencode ($email), $url)))
380
  if (($url = preg_replace ("/%%user_login%%/i", urlencode ($login), $url)))
381
  if (($url = preg_replace ("/%%user_pass%%/i", urlencode ($pass), $url)))
382
- if (($url = trim ($url))) /* Make sure it is not empty. */
383
- ws_plugin__s2member_curlpsr ($url, "s2member=1");
384
  /**/
385
  setcookie ("s2member_subscr_id", "", time () + 31556926, "/");
386
  setcookie ("s2member_custom", "", time () + 31556926, "/");
184
  $register = ws_plugin__s2member_encrypt ("subscr_id_custom_item_number:.:|:.:" . $subscr_id . ":.:|:.:" . $custom . ":.:|:.:" . $item_number);
185
  $register_link = add_query_arg ("s2member_register", $register, get_bloginfo ("url") . "/");
186
  /**/
187
+ if ($shrink && ($tinyurl = ws_plugin__s2member_remote ("http://tinyurl.com/api-create.php?url=" . rawurlencode ($register_link))))
188
  return apply_filters ("s2member_register_link_gen", $tinyurl); /* tinyURL is easier to work with. */
189
+ else /* Else use the long one; tinyURL fails if the server is down. */
190
  return apply_filters ("s2member_register_link_gen", $register_link);
191
  }
192
  /**/
281
  if (($transient = md5 ("s2member_transient_ipn_subscr_payment_" . $subscr_id)) && is_array ($subscr_payment = get_transient ($transient)))
282
  {
283
  $proxy = array ("s2member_paypal_notify" => "1", "s2member_paypal_proxy" => "s2member_transient_ipn_subscr_payment");
284
+ ws_plugin__s2member_remote (add_query_arg ($proxy, get_bloginfo ("url")), stripslashes_deep ($subscr_payment));
285
  delete_transient ($transient);
286
  }
287
  /**/
379
  if (($url = preg_replace ("/%%user_email%%/i", urlencode ($email), $url)))
380
  if (($url = preg_replace ("/%%user_login%%/i", urlencode ($login), $url)))
381
  if (($url = preg_replace ("/%%user_pass%%/i", urlencode ($pass), $url)))
382
+ if (($url = trim ($url))) /* Empty? */
383
+ ws_plugin__s2member_remote ($url);
384
  /**/
385
  setcookie ("s2member_subscr_id", "", time () + 31556926, "/");
386
  setcookie ("s2member_custom", "", time () + 31556926, "/");
includes/functions/sp-access.inc.php CHANGED
@@ -25,9 +25,9 @@ function ws_plugin__s2member_sp_access_link_gen ($sp_IDs = FALSE, $hours = 72, $
25
  $sp_access = ws_plugin__s2member_encrypt ("sp_time_hours:.:|:.:" . $sp_IDs . ":.:|:.:" . strtotime ("now") . ":.:|:.:" . $hours);
26
  $sp_access_link = add_query_arg ("s2member_sp_access", $sp_access, get_permalink ($leading_ID));
27
  /**/
28
- if ($shrink && ($tinyurl = @file_get_contents ("http://tinyurl.com/api-create.php?url=" . rawurlencode ($sp_access_link))))
29
  return apply_filters ("s2member_sp_access_link_gen", $tinyurl); /* tinyURL is easier to work with. */
30
- else /* Else use the long one; tinyURL fails if allow_url_fopen = no. */
31
  return apply_filters ("s2member_sp_access_link_gen", $sp_access_link);
32
  }
33
  /**/
25
  $sp_access = ws_plugin__s2member_encrypt ("sp_time_hours:.:|:.:" . $sp_IDs . ":.:|:.:" . strtotime ("now") . ":.:|:.:" . $hours);
26
  $sp_access_link = add_query_arg ("s2member_sp_access", $sp_access, get_permalink ($leading_ID));
27
  /**/
28
+ if ($shrink && ($tinyurl = ws_plugin__s2member_remote ("http://tinyurl.com/api-create.php?url=" . rawurlencode ($sp_access_link))))
29
  return apply_filters ("s2member_sp_access_link_gen", $tinyurl); /* tinyURL is easier to work with. */
30
+ else /* Else use the long one; tinyURL fails if the server is down. */
31
  return apply_filters ("s2member_sp_access_link_gen", $sp_access_link);
32
  }
33
  /**/
includes/functions/tracking-codes.inc.php CHANGED
@@ -35,11 +35,11 @@ function ws_plugin__s2member_display_signup_tracking_codes ()
35
  {
36
  if (($code = get_transient ($transient = md5 ("s2member_transient_signup_tracking_codes_" . $subscr_id))))
37
  {
38
- delete_transient ($transient); /* Only display this ONE time. Remove transient immediately. */
39
  /**/
40
  echo '<img src="' . add_query_arg ("s2member_delete_signup_tracking_cookie", "1", get_bloginfo ("url")) . '" alt="." style="width:1px; height:1px; border:0;" />' . "\n";
41
  /**/
42
- if ($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["is_wpmu_farm"])
43
  {
44
  echo $code . "\n"; /* No PHP allowed here. */
45
  }
@@ -55,14 +55,14 @@ function ws_plugin__s2member_display_signup_tracking_codes ()
55
  do_action ("s2member_after_display_signup_tracking_codes");
56
  }
57
  /*
58
- Removes s2Member's temporary tracking cookie.
59
  Attach to: add_action("init");
60
  */
61
  function ws_plugin__s2member_delete_signup_tracking_cookie ()
62
  {
63
  do_action ("s2member_before_delete_signup_tracking_cookie");
64
  /**/
65
- if ($_GET["s2member_delete_signup_tracking_cookie"]) /* Removes cookie. */
66
  {
67
  setcookie ("s2member_signup_tracking", "", time () + 31556926, "/");
68
  /**/
@@ -91,11 +91,11 @@ function ws_plugin__s2member_display_sp_tracking_codes ()
91
  {
92
  if (($code = get_transient ($transient = md5 ("s2member_transient_sp_tracking_codes_" . $txn_id))))
93
  {
94
- delete_transient ($transient); /* Only display this ONE time. Remove transient immediately. */
95
  /**/
96
  echo '<img src="' . add_query_arg ("s2member_delete_sp_tracking_cookie", "1", get_bloginfo ("url")) . '" alt="." style="width:1px; height:1px; border:0;" />' . "\n";
97
  /**/
98
- if ($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["is_wpmu_farm"])
99
  {
100
  echo $code . "\n"; /* No PHP allowed here. */
101
  }
@@ -111,14 +111,14 @@ function ws_plugin__s2member_display_sp_tracking_codes ()
111
  do_action ("s2member_after_display_sp_tracking_codes");
112
  }
113
  /*
114
- Removes s2Member's temporary tracking cookie.
115
  Attach to: add_action("init");
116
  */
117
  function ws_plugin__s2member_delete_sp_tracking_cookie ()
118
  {
119
  do_action ("s2member_before_delete_sp_tracking_cookie");
120
  /**/
121
- if ($_GET["s2member_delete_sp_tracking_cookie"]) /* Removes cookie. */
122
  {
123
  setcookie ("s2member_sp_tracking", "", time () + 31556926, "/");
124
  /**/
35
  {
36
  if (($code = get_transient ($transient = md5 ("s2member_transient_signup_tracking_codes_" . $subscr_id))))
37
  {
38
+ delete_transient ($transient); /* Only display this ONE time. Delete transient immediately. */
39
  /**/
40
  echo '<img src="' . add_query_arg ("s2member_delete_signup_tracking_cookie", "1", get_bloginfo ("url")) . '" alt="." style="width:1px; height:1px; border:0;" />' . "\n";
41
  /**/
42
+ if ($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["is_multisite_farm"])
43
  {
44
  echo $code . "\n"; /* No PHP allowed here. */
45
  }
55
  do_action ("s2member_after_display_signup_tracking_codes");
56
  }
57
  /*
58
+ Deletes s2Member's temporary tracking cookie.
59
  Attach to: add_action("init");
60
  */
61
  function ws_plugin__s2member_delete_signup_tracking_cookie ()
62
  {
63
  do_action ("s2member_before_delete_signup_tracking_cookie");
64
  /**/
65
+ if ($_GET["s2member_delete_signup_tracking_cookie"]) /* Deletes cookie. */
66
  {
67
  setcookie ("s2member_signup_tracking", "", time () + 31556926, "/");
68
  /**/
91
  {
92
  if (($code = get_transient ($transient = md5 ("s2member_transient_sp_tracking_codes_" . $txn_id))))
93
  {
94
+ delete_transient ($transient); /* Only display this ONE time. Delete transient immediately. */
95
  /**/
96
  echo '<img src="' . add_query_arg ("s2member_delete_sp_tracking_cookie", "1", get_bloginfo ("url")) . '" alt="." style="width:1px; height:1px; border:0;" />' . "\n";
97
  /**/
98
+ if ($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["is_multisite_farm"])
99
  {
100
  echo $code . "\n"; /* No PHP allowed here. */
101
  }
111
  do_action ("s2member_after_display_sp_tracking_codes");
112
  }
113
  /*
114
+ Deletes s2Member's temporary tracking cookie.
115
  Attach to: add_action("init");
116
  */
117
  function ws_plugin__s2member_delete_sp_tracking_cookie ()
118
  {
119
  do_action ("s2member_before_delete_sp_tracking_cookie");
120
  /**/
121
+ if ($_GET["s2member_delete_sp_tracking_cookie"]) /* Deletes cookie. */
122
  {
123
  setcookie ("s2member_sp_tracking", "", time () + 31556926, "/");
124
  /**/
includes/functions/user-deletions.inc.php CHANGED
@@ -34,8 +34,8 @@ function ws_plugin__s2member_handle_user_deletions ($user_id = FALSE)
34
  if (($url = preg_replace ("/%%user_full_name%%/i", urlencode (trim ($user->first_name . " " . $user->last_name)), $url)))
35
  if (($url = preg_replace ("/%%user_email%%/i", urlencode ($user->user_email), $url)))
36
  /**/
37
- if (($url = trim ($url))) /* Make sure it is not empty. */
38
- ws_plugin__s2member_curlpsr ($url, "s2member=1");
39
  /**/
40
  do_action ("s2member_during_handle_user_deletions");
41
  }
34
  if (($url = preg_replace ("/%%user_full_name%%/i", urlencode (trim ($user->first_name . " " . $user->last_name)), $url)))
35
  if (($url = preg_replace ("/%%user_email%%/i", urlencode ($user->user_email), $url)))
36
  /**/
37
+ if (($url = trim ($url))) /* Empty? */
38
+ ws_plugin__s2member_remote ($url);
39
  /**/
40
  do_action ("s2member_during_handle_user_deletions");
41
  }
includes/functions/utilities.inc.php CHANGED
@@ -14,6 +14,29 @@ Direct access denial.
14
  if (realpath (__FILE__) === realpath ($_SERVER["SCRIPT_FILENAME"]))
15
  exit;
16
  /*
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
17
  Function that extends array_unique to
18
  support multi-dimensional arrays.
19
  */
@@ -99,6 +122,13 @@ function ws_plugin__s2member_get ($function = FALSE)
99
  return;
100
  }
101
  /*
 
 
 
 
 
 
 
102
  Function checks if a post is in a child category.
103
  */
104
  function ws_plugin__s2member_in_descendant_category ($cats = FALSE, $post_ID = FALSE)
@@ -113,42 +143,6 @@ function ws_plugin__s2member_in_descendant_category ($cats = FALSE, $post_ID = F
113
  return false;
114
  }
115
  /*
116
- Curl operation for posting data and reading response.
117
- */
118
- function ws_plugin__s2member_curlpsr ($url = FALSE, $vars = FALSE)
119
- {
120
- if ($url && ($c = curl_init ()))
121
- {
122
- curl_setopt ($c, CURLOPT_URL, $url);
123
- curl_setopt ($c, CURLOPT_POST, true);
124
- curl_setopt ($c, CURLOPT_TIMEOUT, 20);
125
- curl_setopt ($c, CURLOPT_CONNECTTIMEOUT, 20);
126
- curl_setopt ($c, CURLOPT_FOLLOWLOCATION, false);
127
- curl_setopt ($c, CURLOPT_MAXREDIRS, 0);
128
- curl_setopt ($c, CURLOPT_HEADER, false);
129
- curl_setopt ($c, CURLOPT_VERBOSE, true);
130
- curl_setopt ($c, CURLOPT_ENCODING, "");
131
- curl_setopt ($c, CURLOPT_SSL_VERIFYPEER, false);
132
- curl_setopt ($c, CURLOPT_RETURNTRANSFER, true);
133
- curl_setopt ($c, CURLOPT_FORBID_REUSE, true);
134
- curl_setopt ($c, CURLOPT_FAILONERROR, true);
135
- curl_setopt ($c, CURLOPT_POSTFIELDS, $vars);
136
- /**/
137
- $o = trim (curl_exec ($c));
138
- /**/
139
- curl_close ($c);
140
- }
141
- /**/
142
- return (strlen ($o)) ? $o : false;
143
- }
144
- /*
145
- Function escapes single quotes.
146
- */
147
- function ws_plugin__s2member_esc_sq ($string = FALSE)
148
- {
149
- return preg_replace ("/'/", "\'", $string);
150
- }
151
- /*
152
  RIJNDAEL 256: two-way encryption/decryption, with a url-safe base64 wrapper.
153
  Includes a built-in fallback on XOR encryption when mcrypt is not available.
154
  */
14
  if (realpath (__FILE__) === realpath ($_SERVER["SCRIPT_FILENAME"]))
15
  exit;
16
  /*
17
+ Function that handles a remote request.
18
+ This extends wp_remote_request() through the `WP_Http` class.
19
+ */
20
+ function ws_plugin__s2member_remote ($url = FALSE, $post_vars = FALSE, $args = array ())
21
+ {
22
+ $args = (!is_array ($args)) ? array (): $args;
23
+ /**/
24
+ if ($url) /* Obviously, we must have a URL to do anything. */
25
+ {
26
+ if (is_array ($post_vars) && !empty ($post_vars))
27
+ {
28
+ $args["method"] = "POST";
29
+ $args["body"] = $post_vars;
30
+ }
31
+ /**/
32
+ if (!is_wp_error ($response = wp_remote_request ($url, $args)))
33
+ if (strlen ($response["body"]))
34
+ return $response["body"];
35
+ }
36
+ /**/
37
+ return false;
38
+ }
39
+ /*
40
  Function that extends array_unique to
41
  support multi-dimensional arrays.
42
  */
122
  return;
123
  }
124
  /*
125
+ Function escapes single quotes.
126
+ */
127
+ function ws_plugin__s2member_esc_sq ($string = FALSE)
128
+ {
129
+ return preg_replace ("/'/", "\'", $string);
130
+ }
131
+ /*
132
  Function checks if a post is in a child category.
133
  */
134
  function ws_plugin__s2member_in_descendant_category ($cats = FALSE, $post_ID = FALSE)
143
  return false;
144
  }
145
  /*
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
146
  RIJNDAEL 256: two-way encryption/decryption, with a url-safe base64 wrapper.
147
  Includes a built-in fallback on XOR encryption when mcrypt is not available.
148
  */
includes/hooks.inc.php CHANGED
@@ -28,6 +28,7 @@ add_action ("init", "ws_plugin__s2member_check_file_download_access");
28
  add_action ("init", "ws_plugin__s2member_handle_profile_modifications");
29
  add_action ("init", "ws_plugin__s2member_delete_signup_tracking_cookie");
30
  add_action ("init", "ws_plugin__s2member_delete_sp_tracking_cookie");
 
31
  /**/
32
  add_action ("template_redirect", "ws_plugin__s2member_check_ruri_level_access", 1);
33
  add_action ("template_redirect", "ws_plugin__s2member_check_catg_level_access", 1);
28
  add_action ("init", "ws_plugin__s2member_handle_profile_modifications");
29
  add_action ("init", "ws_plugin__s2member_delete_signup_tracking_cookie");
30
  add_action ("init", "ws_plugin__s2member_delete_sp_tracking_cookie");
31
+ add_action ("init", "ws_plugin__s2member_auto_eot_system_via_cron");
32
  /**/
33
  add_action ("template_redirect", "ws_plugin__s2member_check_ruri_level_access", 1);
34
  add_action ("template_redirect", "ws_plugin__s2member_check_catg_level_access", 1);
includes/mailchimp/nc-mcapi.inc.php CHANGED
@@ -3,6 +3,9 @@
3
  NC_MCAPI ( no conflict version ) Modified by WebSharks, Inc. / 2010.
4
  Uses custom a class name to avoid conflicts with other instances.
5
 
 
 
 
6
  Original MCAPI ( class intact ).
7
  © Copyright MailChimp® <http://www.mailchimp.com/>
8
  <http://www.mailchimp.com/contact/>
@@ -1719,75 +1722,52 @@ class NC_MCAPI {
1719
  * Actually connect to the server and call the requested methods, parsing the result
1720
  * You should never have to call this function manually
1721
  */
1722
- function callServer($method, $params) {
1723
- $dc = "us1";
1724
- if (strstr($this->api_key,"-")){
1725
- list($key, $dc) = explode("-",$this->api_key,2);
1726
- if (!$dc) $dc = "us1";
1727
- }
1728
- $host = $dc.".".$this->apiUrl["host"];
1729
- $params["apikey"] = $this->api_key;
1730
 
1731
- $this->errorMessage = "";
1732
- $this->errorCode = "";
1733
- $post_vars = $this->httpBuildQuery($params);
1734
-
1735
- $payload = "POST " . $this->apiUrl["path"] . "?" . $this->apiUrl["query"] . "&method=" . $method . " HTTP/1.0\r\n";
1736
- $payload .= "Host: " . $host . "\r\n";
1737
- $payload .= "User-Agent: MCAPI/" . $this->version ."\r\n";
1738
- $payload .= "Content-type: application/x-www-form-urlencoded\r\n";
1739
- $payload .= "Content-length: " . strlen($post_vars) . "\r\n";
1740
- $payload .= "Connection: close \r\n\r\n";
1741
- $payload .= $post_vars;
1742
-
1743
- ob_start();
1744
- if ($this->secure){
1745
- $sock = fsockopen("ssl://".$host, 443, $errno, $errstr, 30);
1746
- } else {
1747
- $sock = fsockopen($host, 80, $errno, $errstr, 30);
1748
- }
1749
- if(!$sock) {
1750
- $this->errorMessage = "Could not connect (ERR $errno: $errstr)";
1751
- $this->errorCode = "-99";
1752
- ob_end_clean();
1753
- return false;
1754
- }
1755
-
1756
- $response = "";
1757
- fwrite($sock, $payload);
1758
- stream_set_timeout($sock, $this->timeout);
1759
- $info = stream_get_meta_data($sock);
1760
- while ((!feof($sock)) && (!$info["timed_out"])) {
1761
- $response .= fread($sock, $this->chunkSize);
1762
- $info = stream_get_meta_data($sock);
1763
- }
1764
- if ($info["timed_out"]) {
1765
- $this->errorMessage = "Could not read response (timed out)";
1766
- $this->errorCode = -98;
1767
- }
1768
- fclose($sock);
1769
- ob_end_clean();
1770
- if ($info["timed_out"]) return false;
 
 
1771
 
1772
- list($throw, $response) = explode("\r\n\r\n", $response, 2);
1773
-
1774
- if(ini_get("magic_quotes_runtime")) $response = stripslashes($response);
1775
-
1776
- $serial = unserialize($response);
1777
- if($response && $serial === false) {
1778
- $response = array("error" => "Bad Response. Got This: " . $response, "code" => "-99");
1779
- } else {
1780
- $response = $serial;
1781
- }
1782
- if(is_array($response) && isset($response["error"])) {
1783
- $this->errorMessage = $response["error"];
1784
- $this->errorCode = $response["code"];
1785
- return false;
1786
- }
1787
-
1788
- return $response;
1789
- }
1790
-
1791
  /**
1792
  * Re-implement http_build_query for systems that do not already have it
1793
  */
3
  NC_MCAPI ( no conflict version ) Modified by WebSharks, Inc. / 2010.
4
  Uses custom a class name to avoid conflicts with other instances.
5
 
6
+ This version has also been modified to use the s2Member function:
7
+ ws_plugin__s2member_open_url(). Removing reliance on allow_url_fopen.
8
+
9
  Original MCAPI ( class intact ).
10
  © Copyright MailChimp® <http://www.mailchimp.com/>
11
  <http://www.mailchimp.com/contact/>
1722
  * Actually connect to the server and call the requested methods, parsing the result
1723
  * You should never have to call this function manually
1724
  */
1725
+ function callServer($method, $params)
1726
+ {
 
 
 
 
 
 
1727
 
1728
+ $dc = "us1";
1729
+
1730
+ $this->errorMessage = "";
1731
+ $this->errorCode = "";
1732
+
1733
+ if (strstr ($this->api_key, "-"))
1734
+ {
1735
+ list ($key, $dc) = explode ("-", $this->api_key, 2);
1736
+ if (!$dc) $dc = "us1";
1737
+ }
1738
+
1739
+ $host = $dc. "." . $this->apiUrl["host"];
1740
+ $host_uri = $host . $this->apiUrl["path"] . "?" . $this->apiUrl["query"] . "&method=" . urlencode ($method);
1741
+ $url = ($this->secure) ? "https://" . $host_uri : "http://" . $host_uri;
1742
+ $args["user-agent"] = "MCAPI/" . $this->version;
1743
+ $params["apikey"] = $this->api_key;
1744
+ $post_vars = $params;
1745
+
1746
+ if (!strlen ($_response = ws_plugin__s2member_remote ($url, $post_vars, $args)))
1747
+ {
1748
+ $this->errorMessage = "Could not connect.";
1749
+ $this->errorCode = "-99";
1750
+ return false;
1751
+ }
1752
+
1753
+ if (ini_get ("magic_quotes_runtime"))
1754
+ $_response = stripslashes ($_response);
1755
+
1756
+ if (!is_array ($response = @unserialize ($_response)))
1757
+ {
1758
+ $response = array ("error" => "Bad Response. Got This: " . $_response, "code" => "-99");
1759
+ }
1760
+
1761
+ if (isset ($response["error"]))
1762
+ {
1763
+ $this->errorMessage = $response["error"];
1764
+ $this->errorCode = $response["code"];
1765
+ return false;
1766
+ }
1767
+
1768
+ return $response;
1769
+ }
1770
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1771
  /**
1772
  * Re-implement http_build_query for systems that do not already have it
1773
  */
includes/menu-pages/api-ops.inc.php CHANGED
@@ -54,7 +54,7 @@ echo '<tr>' . "\n";
54
  echo '<td>' . "\n";
55
  echo 'You can input multiple Notification URLs by inserting one per line.<br />' . "\n";
56
  echo '<textarea name="ws_plugin__s2member_signup_notification_urls" id="ws-plugin--s2member-signup-notification-urls" rows="3" wrap="off">' . format_to_edit ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["signup_notification_urls"]) . '</textarea><br />' . "\n";
57
- echo 'Signup Notifications take place silently behind-the-scene, using a cURL connection. Each URL will be notified every time a new user signs up successfully through PayPal.<br /><br />' . "\n";
58
  echo '<strong>You can also use these special replacement codes if you need them:</strong>' . "\n";
59
  echo '<ul>' . "\n";
60
  echo '<li><code>%%subscr_id%% = The PayPal® Subscription ID, which remains constant throughout any &amp; all future payments.</code> [ <a href="#" onclick="alert(\'There is one exception. If you are selling Lifetime or Fixed-Term ( non-recurring ) access, using a Buy It Now button; the %%subscr_id%% is actually set to the Transaction ID for the purchase.\\n\\nPayPal® does not provide a specific Subscription ID for Buy It Now purchases. Since Lifetime &amp; Fixed-Term Subscriptions are NOT recurring ( i.e. there is only ONE payment ), using the Transaction ID as the Subscription ID is a graceful way to deal with this minor conflict.\'); return false;">?</a> ]</li>' . "\n";
@@ -109,7 +109,7 @@ echo '<tr>' . "\n";
109
  echo '<td>' . "\n";
110
  echo 'You can input multiple Notification URLs by inserting one per line.<br />' . "\n";
111
  echo '<textarea name="ws_plugin__s2member_registration_notification_urls" id="ws-plugin--s2member-registration-notification-urls" rows="3" wrap="off">' . format_to_edit ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["registration_notification_urls"]) . '</textarea><br />' . "\n";
112
- echo 'Registration Notifications take place silently behind-the-scene, using a cURL connection. Each URL will be notified every time a new user registers a Username.<br /><br />' . "\n";
113
  echo '<strong>You can also use these special replacement codes if you need them:</strong>' . "\n";
114
  echo '<ul>' . "\n";
115
  echo '<li><code>%%level%% = The level number ( 0, 1, 2, 3, 4 ) 0 = Free Subscriber.</code></li>' . "\n";
@@ -159,7 +159,7 @@ echo '<tr>' . "\n";
159
  echo '<td>' . "\n";
160
  echo 'You can input multiple Notification URLs by inserting one per line.<br />' . "\n";
161
  echo '<textarea name="ws_plugin__s2member_payment_notification_urls" id="ws-plugin--s2member-payment-notification-urls" rows="3" wrap="off">' . format_to_edit ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["payment_notification_urls"]) . '</textarea><br />' . "\n";
162
- echo 'Payment Notifications take place silently behind-the-scene, using a cURL connection. Each URL will be notified every time an initial and/or recurring payment occurs.<br /><br />' . "\n";
163
  echo '<strong>You can also use these special replacement codes if you need them:</strong>' . "\n";
164
  echo '<ul>' . "\n";
165
  echo '<li><code>%%subscr_id%% = The PayPal® Subscription ID, which remains constant throughout any &amp; all future payments.</code> [ <a href="#" onclick="alert(\'There is one exception. If you are selling Lifetime or Fixed-Term ( non-recurring ) access, using a Buy It Now button; the %%subscr_id%% is actually set to the Transaction ID for the payment.\\n\\nPayPal® does not provide a specific Subscription ID for Buy It Now purchases. Since Lifetime &amp; Fixed-Term Subscriptions are NOT recurring ( i.e. there is only ONE payment ), using the Transaction ID as the Subscription ID is a graceful way to deal with this minor conflict.\'); return false;">?</a> ]</li>' . "\n";
@@ -213,7 +213,7 @@ echo '<tr>' . "\n";
213
  echo '<td>' . "\n";
214
  echo 'You can input multiple Notification URLs by inserting one per line.<br />' . "\n";
215
  echo '<textarea name="ws_plugin__s2member_eot_del_notification_urls" id="ws-plugin--s2member-eot-del-notification-urls" rows="3" wrap="off">' . format_to_edit ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["eot_del_notification_urls"]) . '</textarea><br />' . "\n";
216
- echo 'EOT/Deletion Notifications take place silently behind-the-scene, using a cURL connection. Each URL will be notified every time a Subscription hits an EOT, or is deleted.<br /><br />' . "\n";
217
  echo '<strong>You can also use these special replacement codes if you need them:</strong>' . "\n";
218
  echo '<ul>' . "\n";
219
  echo '<li><code>%%subscr_id%% = The PayPal® Subscription ID, which remained constant throughout the lifetime of the membership.</code> [ <a href="#" onclick="alert(\'There is one exception. If you are selling Lifetime or Fixed-Term ( non-recurring ) access, using a Buy It Now button; the %%subscr_id%% is actually set to the original Transaction ID for the purchase.\\n\\nPayPal® does not provide a specific Subscription ID for Buy It Now purchases. Since Lifetime &amp; Fixed-Term Subscriptions are NOT recurring ( i.e. there was only ONE payment ), using the Transaction ID as the Subscription ID is a graceful way to deal with this minor conflict.\'); return false;">?</a> ]</li>' . "\n";
@@ -262,7 +262,7 @@ echo '<tr>' . "\n";
262
  echo '<td>' . "\n";
263
  echo 'You can input multiple Notification URLs by inserting one per line.<br />' . "\n";
264
  echo '<textarea name="ws_plugin__s2member_ref_rev_notification_urls" id="ws-plugin--s2member-ref-rev-notification-urls" rows="3" wrap="off">' . format_to_edit ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["ref_rev_notification_urls"]) . '</textarea><br />' . "\n";
265
- echo 'Refund/Reversal Notifications take place silently behind-the-scene, using a cURL connection. Each URL will be notified every time a payment is refunded through PayPal® or a chargeback occurs.<br /><br />' . "\n";
266
  echo '<strong>You can also use these special replacement codes if you need them:</strong>' . "\n";
267
  echo '<ul>' . "\n";
268
  echo '<li><code>%%subscr_id%% = The PayPal® Subscription ID, which remained constant throughout the lifetime of the membership.</code> [ <a href="#" onclick="alert(\'There is one exception. If you are selling Lifetime or Fixed-Term ( non-recurring ) access, using a Buy It Now button; the %%subscr_id%% is actually set to the original Transaction ID for the purchase.\\n\\nPayPal® does not provide a specific Subscription ID for Buy It Now purchases. Since Lifetime &amp; Fixed-Term Subscriptions are NOT recurring ( i.e. there was only ONE payment ), using the Transaction ID as the Subscription ID is a graceful way to deal with this minor conflict.\'); return false;">?</a> ]</li>' . "\n";
@@ -314,7 +314,7 @@ echo '<tr>' . "\n";
314
  echo '<td>' . "\n";
315
  echo 'You can input multiple Notification URLs by inserting one per line.<br />' . "\n";
316
  echo '<textarea name="ws_plugin__s2member_sp_notification_urls" id="ws-plugin--s2member-sp-notification-urls" rows="3" wrap="off">' . format_to_edit ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["sp_notification_urls"]) . '</textarea><br />' . "\n";
317
- echo 'Specific Post/Page Notifications take place silently behind-the-scene, using a cURL connection. Each URL will be notified every time a sale occurs.<br /><br />' . "\n";
318
  echo '<strong>You can also use these special replacement codes if you need them:</strong>' . "\n";
319
  echo '<ul>' . "\n";
320
  echo '<li><code>%%sp_access_url%% = The full URL ( generated by s2Member ) where the Customer can gain access.</code></li>' . "\n";
54
  echo '<td>' . "\n";
55
  echo 'You can input multiple Notification URLs by inserting one per line.<br />' . "\n";
56
  echo '<textarea name="ws_plugin__s2member_signup_notification_urls" id="ws-plugin--s2member-signup-notification-urls" rows="3" wrap="off">' . format_to_edit ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["signup_notification_urls"]) . '</textarea><br />' . "\n";
57
+ echo 'Signup Notifications take place silently behind-the-scene, using an HTTP connection. Each URL will be notified every time a new user signs up successfully through PayPal.<br /><br />' . "\n";
58
  echo '<strong>You can also use these special replacement codes if you need them:</strong>' . "\n";
59
  echo '<ul>' . "\n";
60
  echo '<li><code>%%subscr_id%% = The PayPal® Subscription ID, which remains constant throughout any &amp; all future payments.</code> [ <a href="#" onclick="alert(\'There is one exception. If you are selling Lifetime or Fixed-Term ( non-recurring ) access, using a Buy It Now button; the %%subscr_id%% is actually set to the Transaction ID for the purchase.\\n\\nPayPal® does not provide a specific Subscription ID for Buy It Now purchases. Since Lifetime &amp; Fixed-Term Subscriptions are NOT recurring ( i.e. there is only ONE payment ), using the Transaction ID as the Subscription ID is a graceful way to deal with this minor conflict.\'); return false;">?</a> ]</li>' . "\n";
109
  echo '<td>' . "\n";
110
  echo 'You can input multiple Notification URLs by inserting one per line.<br />' . "\n";
111
  echo '<textarea name="ws_plugin__s2member_registration_notification_urls" id="ws-plugin--s2member-registration-notification-urls" rows="3" wrap="off">' . format_to_edit ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["registration_notification_urls"]) . '</textarea><br />' . "\n";
112
+ echo 'Registration Notifications take place silently behind-the-scene, using an HTTP connection. Each URL will be notified every time a new user registers a Username.<br /><br />' . "\n";
113
  echo '<strong>You can also use these special replacement codes if you need them:</strong>' . "\n";
114
  echo '<ul>' . "\n";
115
  echo '<li><code>%%level%% = The level number ( 0, 1, 2, 3, 4 ) 0 = Free Subscriber.</code></li>' . "\n";
159
  echo '<td>' . "\n";
160
  echo 'You can input multiple Notification URLs by inserting one per line.<br />' . "\n";
161
  echo '<textarea name="ws_plugin__s2member_payment_notification_urls" id="ws-plugin--s2member-payment-notification-urls" rows="3" wrap="off">' . format_to_edit ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["payment_notification_urls"]) . '</textarea><br />' . "\n";
162
+ echo 'Payment Notifications take place silently behind-the-scene, using an HTTP connection. Each URL will be notified every time an initial and/or recurring payment occurs.<br /><br />' . "\n";
163
  echo '<strong>You can also use these special replacement codes if you need them:</strong>' . "\n";
164
  echo '<ul>' . "\n";
165
  echo '<li><code>%%subscr_id%% = The PayPal® Subscription ID, which remains constant throughout any &amp; all future payments.</code> [ <a href="#" onclick="alert(\'There is one exception. If you are selling Lifetime or Fixed-Term ( non-recurring ) access, using a Buy It Now button; the %%subscr_id%% is actually set to the Transaction ID for the payment.\\n\\nPayPal® does not provide a specific Subscription ID for Buy It Now purchases. Since Lifetime &amp; Fixed-Term Subscriptions are NOT recurring ( i.e. there is only ONE payment ), using the Transaction ID as the Subscription ID is a graceful way to deal with this minor conflict.\'); return false;">?</a> ]</li>' . "\n";
213
  echo '<td>' . "\n";
214
  echo 'You can input multiple Notification URLs by inserting one per line.<br />' . "\n";
215
  echo '<textarea name="ws_plugin__s2member_eot_del_notification_urls" id="ws-plugin--s2member-eot-del-notification-urls" rows="3" wrap="off">' . format_to_edit ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["eot_del_notification_urls"]) . '</textarea><br />' . "\n";
216
+ echo 'EOT/Deletion Notifications take place silently behind-the-scene, using an HTTP connection. Each URL will be notified every time a Subscription hits an EOT, or is deleted.<br /><br />' . "\n";
217
  echo '<strong>You can also use these special replacement codes if you need them:</strong>' . "\n";
218
  echo '<ul>' . "\n";
219
  echo '<li><code>%%subscr_id%% = The PayPal® Subscription ID, which remained constant throughout the lifetime of the membership.</code> [ <a href="#" onclick="alert(\'There is one exception. If you are selling Lifetime or Fixed-Term ( non-recurring ) access, using a Buy It Now button; the %%subscr_id%% is actually set to the original Transaction ID for the purchase.\\n\\nPayPal® does not provide a specific Subscription ID for Buy It Now purchases. Since Lifetime &amp; Fixed-Term Subscriptions are NOT recurring ( i.e. there was only ONE payment ), using the Transaction ID as the Subscription ID is a graceful way to deal with this minor conflict.\'); return false;">?</a> ]</li>' . "\n";
262
  echo '<td>' . "\n";
263
  echo 'You can input multiple Notification URLs by inserting one per line.<br />' . "\n";
264
  echo '<textarea name="ws_plugin__s2member_ref_rev_notification_urls" id="ws-plugin--s2member-ref-rev-notification-urls" rows="3" wrap="off">' . format_to_edit ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["ref_rev_notification_urls"]) . '</textarea><br />' . "\n";
265
+ echo 'Refund/Reversal Notifications take place silently behind-the-scene, using an HTTP connection. Each URL will be notified every time a payment is refunded through PayPal® or a chargeback occurs.<br /><br />' . "\n";
266
  echo '<strong>You can also use these special replacement codes if you need them:</strong>' . "\n";
267
  echo '<ul>' . "\n";
268
  echo '<li><code>%%subscr_id%% = The PayPal® Subscription ID, which remained constant throughout the lifetime of the membership.</code> [ <a href="#" onclick="alert(\'There is one exception. If you are selling Lifetime or Fixed-Term ( non-recurring ) access, using a Buy It Now button; the %%subscr_id%% is actually set to the original Transaction ID for the purchase.\\n\\nPayPal® does not provide a specific Subscription ID for Buy It Now purchases. Since Lifetime &amp; Fixed-Term Subscriptions are NOT recurring ( i.e. there was only ONE payment ), using the Transaction ID as the Subscription ID is a graceful way to deal with this minor conflict.\'); return false;">?</a> ]</li>' . "\n";
314
  echo '<td>' . "\n";
315
  echo 'You can input multiple Notification URLs by inserting one per line.<br />' . "\n";
316
  echo '<textarea name="ws_plugin__s2member_sp_notification_urls" id="ws-plugin--s2member-sp-notification-urls" rows="3" wrap="off">' . format_to_edit ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["sp_notification_urls"]) . '</textarea><br />' . "\n";
317
+ echo 'Specific Post/Page Notifications take place silently behind-the-scene, using an HTTP connection. Each URL will be notified every time a sale occurs.<br /><br />' . "\n";
318
  echo '<strong>You can also use these special replacement codes if you need them:</strong>' . "\n";
319
  echo '<ul>' . "\n";
320
  echo '<li><code>%%sp_access_url%% = The full URL ( generated by s2Member ) where the Customer can gain access.</code></li>' . "\n";
includes/menu-pages/menu-pages.js CHANGED
@@ -164,6 +164,20 @@ jQuery(document).ready (function($)
164
  };
165
  }
166
  /**/
 
 
 
 
 
 
 
 
 
 
 
 
 
 
167
  else if (location.href.match (/page\=ws-plugin--s2member-els-ops/))
168
  {
169
  $('select#ws-plugin--s2member-custom-reg-opt-in').change (function()
164
  };
165
  }
166
  /**/
167
+ else if (location.href.match (/page\=ws-plugin--s2member-paypal-ops/))
168
+ {
169
+ $('select#ws-plugin--s2member-auto-eot-system-enabled').change (function()
170
+ {
171
+ var $this = $(this), val = $this.val ();
172
+ var $viaCron = $('p#ws-plugin--s2member-auto-eot-system-enabled-via-cron');
173
+ /**/
174
+ if (val == 2) /* Display Cron instructions. */
175
+ $viaCron.show ()
176
+ else /* Hide instructions. */
177
+ $viaCron.hide ();
178
+ });
179
+ }
180
+ /**/
181
  else if (location.href.match (/page\=ws-plugin--s2member-els-ops/))
182
  {
183
  $('select#ws-plugin--s2member-custom-reg-opt-in').change (function()
includes/menu-pages/paypal-ops.inc.php CHANGED
@@ -107,7 +107,7 @@ echo '<p>Log into your PayPal® account and navigate to this section:<br /><code
107
  echo '<p>Edit your IPN settings &amp; turn IPN Notifications: <strong><code>On</code></strong></p>' . "\n";
108
  echo '<p>You\'ll need your IPN URL, which is:<br /><code>' . get_bloginfo ("url") . '/?s2member_paypal_notify=1</code></p>' . "\n";
109
  echo '<p><em><strong>*Quick Tip*</strong> In addition to the default IPN Settings inside your PayPal® account, the IPN URL is also set on a per-transaction basis by the special PayPal® Button Code that s2Member provides you with. In other words, if you have multiple sites operating on one PayPal® account, that\'s OK. s2Member dynamically sets the IPN URL for each transaction. The result is that the IPN URL configured from within your PayPal® account, becomes the default, which is then overwritten on a per transaction basis. In fact, PayPal® recently updated their system to support IPN URL preservation. One PayPal® account can handle multiple sites, all using different IPN URLs.</em></p>' . "\n";
110
- echo '<p><em><strong>*More Information*</strong> You\'ll be happy to know that s2Member handles cancellations, expirations, failed payments ( more than 2 in a row ), terminations ( e.g. refunds &amp; chargebacks ) for you automatically. If you log into your PayPal® account and cancel a Member\'s Subscription, or, if the Member logs into their PayPal® account and cancels their own Subscription, s2Member will be notified of these important changes and react accordingly through the PayPal® IPN service that runs silently behind-the-scene. The PayPal® IPN service will notify s2Member whenever a Member\'s payments have been failing ( more than 2 times in a row ), and/or whenever a Member\'s Subscription has expired for any reason. Even refunds &amp; chargeback reversals are supported through the IPN service. If you issue a refund to an unhappy Customer through PayPal®, s2Member will be notified, and the account for that Customer will either be demoted to a Free Subscriber, or deleted automatically ( based on your configuration ). The communication from PayPal® -> s2Member is seamless.</em></p>' . "\n";
111
  echo '<p><em><strong>*2010 PayPal® Accounts*</strong> s2Member has been updated to support newer PayPal® accounts ( those opened after Oct 15th, 2009 ). Newer PayPal® accounts do NOT send a <strong>IPN</strong>/<code>subscr_eot</code> in all cases. s2Member deals with this gracefully, by keeping a record of payments/periods/changes, and monitoring other signals sent by PayPal® over an extended period. This allows s2Member to take control of the situation at the appropriate time. The communication from PayPal® -> s2Member is seamless; even in PayPal® accounts created after October 15th, 2009. You can learn more about <code>subscr_eot</code> changes <a href="https://www.x.com/search.jspa?q=subscr+eot" target="_blank" rel="external">here</a>.</em></p>' . "\n";
112
  echo '</div>' . "\n";
113
  /**/
@@ -293,7 +293,8 @@ echo '<div class="ws-menu-page-group" title="PayPal® EOT Behavior">' . "\n";
293
  /**/
294
  echo '<div class="ws-menu-page-section ws-plugin--s2member-eot-behavior-section">' . "\n";
295
  echo '<h3>PayPal® EOT Behavior ( required, please choose )</h3>' . "\n";
296
- 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 paid 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";
 
297
  echo '<table class="form-table">' . "\n";
298
  echo '<tbody>' . "\n";
299
  echo '<tr>' . "\n";
@@ -309,11 +310,12 @@ echo '<tr>' . "\n";
309
  /**/
310
  echo '<td>' . "\n";
311
  echo '<select name="ws_plugin__s2member_auto_eot_system_enabled" id="ws-plugin--s2member-auto-eot-system-enabled">' . "\n";
312
- echo ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["auto_eot_system_enabled"] && !wp_get_schedule ("s2member_auto_eot_system")) ? '<option value="" selected="selected"></option>' : '';
313
- echo '<option value="1"' . (($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["auto_eot_system_enabled"] && wp_get_schedule ("s2member_auto_eot_system")) ? ' selected="selected"' : '') . '>Yes ( enable the Auto-EOT System through WP_Cron )</option>' . "\n";
314
- echo '<option value="0"' . ((!$GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["auto_eot_system_enabled"]) ? ' selected="selected"' : '') . '>No ( temporarily disable the Auto-EOT System )</option>' . "\n";
 
315
  echo '</select><br />' . "\n";
316
- echo 'Recommended setting: ( <code>Yes / enable</code> )' . "\n";
317
  echo '</td>' . "\n";
318
  /**/
319
  echo '</tr>' . "\n";
107
  echo '<p>Edit your IPN settings &amp; turn IPN Notifications: <strong><code>On</code></strong></p>' . "\n";
108
  echo '<p>You\'ll need your IPN URL, which is:<br /><code>' . get_bloginfo ("url") . '/?s2member_paypal_notify=1</code></p>' . "\n";
109
  echo '<p><em><strong>*Quick Tip*</strong> In addition to the default IPN Settings inside your PayPal® account, the IPN URL is also set on a per-transaction basis by the special PayPal® Button Code that s2Member provides you with. In other words, if you have multiple sites operating on one PayPal® account, that\'s OK. s2Member dynamically sets the IPN URL for each transaction. The result is that the IPN URL configured from within your PayPal® account, becomes the default, which is then overwritten on a per transaction basis. In fact, PayPal® recently updated their system to support IPN URL preservation. One PayPal® account can handle multiple sites, all using different IPN URLs.</em></p>' . "\n";
110
+ echo '<p><em><strong>*More Information*</strong> You\'ll be happy to know that s2Member handles cancellations, expirations, failed payments, terminations ( e.g. refunds &amp; chargebacks ) for you automatically. If you log into your PayPal® account and cancel a Member\'s Subscription, or, if the Member logs into their PayPal® account and cancels their own Subscription, s2Member will be notified of these important changes and react accordingly through the PayPal® IPN service that runs silently behind-the-scene. The PayPal® IPN service will notify s2Member whenever a Member\'s payments have been failing, and/or whenever a Member\'s Subscription has expired for any reason. Even refunds &amp; chargeback reversals are supported through the IPN service. If you issue a refund to an unhappy Customer through PayPal®, s2Member will be notified, and the account for that Customer will either be demoted to a Free Subscriber, or deleted automatically ( based on your configuration ). The communication from PayPal® -> s2Member is seamless.</em></p>' . "\n";
111
  echo '<p><em><strong>*2010 PayPal® Accounts*</strong> s2Member has been updated to support newer PayPal® accounts ( those opened after Oct 15th, 2009 ). Newer PayPal® accounts do NOT send a <strong>IPN</strong>/<code>subscr_eot</code> in all cases. s2Member deals with this gracefully, by keeping a record of payments/periods/changes, and monitoring other signals sent by PayPal® over an extended period. This allows s2Member to take control of the situation at the appropriate time. The communication from PayPal® -> s2Member is seamless; even in PayPal® accounts created after October 15th, 2009. You can learn more about <code>subscr_eot</code> changes <a href="https://www.x.com/search.jspa?q=subscr+eot" target="_blank" rel="external">here</a>.</em></p>' . "\n";
112
  echo '</div>' . "\n";
113
  /**/
293
  /**/
294
  echo '<div class="ws-menu-page-section ws-plugin--s2member-eot-behavior-section">' . "\n";
295
  echo '<h3>PayPal® EOT Behavior ( required, please choose )</h3>' . "\n";
296
+ 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";
297
+ 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 ("s2member_auto_eot_system"))) ? '' : ' 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 ("url") . "/")) . '</code></p>' . "\n";
298
  echo '<table class="form-table">' . "\n";
299
  echo '<tbody>' . "\n";
300
  echo '<tr>' . "\n";
310
  /**/
311
  echo '<td>' . "\n";
312
  echo '<select name="ws_plugin__s2member_auto_eot_system_enabled" id="ws-plugin--s2member-auto-eot-system-enabled">' . "\n";
313
+ echo '<option value="">&mdash; Select &mdash;</option>' . "\n"; /* « If the Auto-EOT System is not running, or not fully configured, this will indicate no option is currently set. */
314
+ echo '<option value="1"' . (($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["auto_eot_system_enabled"] == 1 && function_exists ("wp_cron") && wp_get_schedule ("s2member_auto_eot_system")) ? ' selected="selected"' : '') . '>Yes ( enable the Auto-EOT System through WP-Cron )</option>' . "\n";
315
+ echo '<option value="2"' . (($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["auto_eot_system_enabled"] == 2 && (!function_exists ("wp_cron") || !wp_get_schedule ("s2member_auto_eot_system"))) ? ' selected="selected"' : '') . '>Yes ( but, I\'ll run it with my own Cron Job )</option>' . "\n";
316
+ echo '<option value="0"' . ((!$GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["auto_eot_system_enabled"]) ? ' selected="selected"' : '') . '>No ( disable the Auto-EOT System )</option>' . "\n";
317
  echo '</select><br />' . "\n";
318
+ echo 'Recommended setting: ( <code>Yes / enable via WP-Cron</code> )' . "\n";
319
  echo '</td>' . "\n";
320
  /**/
321
  echo '</tr>' . "\n";
includes/menu-pages/start.inc.php CHANGED
@@ -83,8 +83,8 @@ echo '<div class="ws-menu-page-group" title="Subscription Cancellations">' . "\n
83
  /**/
84
  echo '<div class="ws-menu-page-section ws-plugin--s2member-automation-process-section">' . "\n";
85
  echo '<h3>Subscription Cancellations / Expirations / Terminations</h3>' . "\n";
86
- echo '<p>You\'ll be happy to know that s2Member handles cancellations, expirations, failed payments ( more than 2 in a row ), terminations ( e.g. refunds &amp; chargebacks ) for you automatically. If you log into your PayPal® account and cancel a Member\'s Subscription, or, if the Member logs into their PayPal® account and cancels their own Subscription, s2Member will be notified of these important changes and react accordingly through the PayPal® IPN service that runs silently behind-the-scene.</p>' . "\n";
87
- echo '<p>The PayPal® IPN service will notify s2Member whenever a Member\'s payments have been failing ( more than 2 times in a row ), 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";
88
  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";
89
  echo '<p><em><strong>*2010 PayPal® Accounts*</strong> s2Member has been updated to support newer PayPal® accounts ( those opened after Oct 15th, 2009 ). Newer PayPal® accounts do NOT send an <strong>IPN</strong>/<code>subscr_eot</code> in all cases. s2Member deals with this gracefully, by keeping a record of payments/periods/changes, and monitoring other signals sent by PayPal® over an extended period. This allows s2Member to take control of the situation at the appropriate time, using s2Member\'s built-in Auto-EOT System. The communication from PayPal® -> s2Member is seamless; even in PayPal® accounts created after October 15th, 2009. You can learn more about <code>subscr_eot</code> changes <a href="https://www.x.com/search.jspa?q=subscr+eot" target="_blank" rel="external">here</a>.</em></p>' . "\n";
90
  echo '</div>' . "\n";
83
  /**/
84
  echo '<div class="ws-menu-page-section ws-plugin--s2member-automation-process-section">' . "\n";
85
  echo '<h3>Subscription Cancellations / Expirations / Terminations</h3>' . "\n";
86
+ echo '<p>You\'ll be happy to know that s2Member handles cancellations, expirations, failed payments, terminations ( e.g. refunds &amp; chargebacks ) for you automatically. If you log into your PayPal® account and cancel a Member\'s Subscription, or, if the Member logs into their PayPal® account and cancels their own Subscription, s2Member will be notified of these important changes and react accordingly through the PayPal® IPN service that runs silently behind-the-scene.</p>' . "\n";
87
+ 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";
88
  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";
89
  echo '<p><em><strong>*2010 PayPal® Accounts*</strong> s2Member has been updated to support newer PayPal® accounts ( those opened after Oct 15th, 2009 ). Newer PayPal® accounts do NOT send an <strong>IPN</strong>/<code>subscr_eot</code> in all cases. s2Member deals with this gracefully, by keeping a record of payments/periods/changes, and monitoring other signals sent by PayPal® over an extended period. This allows s2Member to take control of the situation at the appropriate time, using s2Member\'s built-in Auto-EOT System. The communication from PayPal® -> s2Member is seamless; even in PayPal® accounts created after October 15th, 2009. You can learn more about <code>subscr_eot</code> changes <a href="https://www.x.com/search.jspa?q=subscr+eot" target="_blank" rel="external">here</a>.</em></p>' . "\n";
90
  echo '</div>' . "\n";
includes/menu-pages/trk-ops.inc.php CHANGED
@@ -36,7 +36,7 @@ echo '<div class="ws-menu-page-group" title="Membership Signup Tracking Codes">'
36
  /**/
37
  echo '<div class="ws-menu-page-section ws-plugin--s2member-signup-tracking-section">' . "\n";
38
  echo '<h3>Membership Signup Tracking Codes ( optional )</h3>' . "\n";
39
- echo '<p>If you use affiliate software, a list server, tracking codes from advertising networks, or the like; you\'ll want to read this section. The HTML' . ((!$GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["is_wpmu_farm"]) ? ' and/or PHP' : '') . ' code that you enter below, will be loaded up in a web browser, after a Customer returns from a successful Signup through PayPal®. Tracking Codes are only displayed/processed one time for each Customer. s2Member will display your Tracking Codes in one of three possible locations... <strong>1.</strong> If possible, on the Registration Form, after returning from PayPal®. <strong>2.</strong> Otherwise, if possible, on the Login Form after Registration is completed. <strong>3.</strong> Otherwise, in the footer of your WordPress® theme, after the Customer\'s very first Login.</p>' . "\n";
40
  echo '<p>Signup Tracking Codes are displayed for all types of Membership Level Access. Including: Recurring Subscriptions ( with or without a free trial period ), Non-Recurring Subscriptions ( with or without a free trial period ), Lifetime Subscriptions, and even Fixed-Term Subscriptions. All of these are supported by s2Member\'s Button Generator, and all of these are supported here.</p>' . "\n";
41
  echo '<table class="form-table">' . "\n";
42
  echo '<tbody>' . "\n";
@@ -53,7 +53,7 @@ echo '<tr>' . "\n";
53
  /**/
54
  echo '<td>' . "\n";
55
  echo '<textarea name="ws_plugin__s2member_signup_tracking_codes" id="ws-plugin--s2member-signup-tracking-codes" rows="8" wrap="off" spellcheck="false" style="font-family:Consolas, monospace;">' . format_to_edit ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["signup_tracking_codes"]) . '</textarea><br />' . "\n";
56
- echo 'Any valid XHTML / JavaScript' . ((!$GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["is_wpmu_farm"]) ? ' ( or even PHP )' : '') . ' code will work just fine here. Just try not to put anything here that would actually be visible to the Customer. Things like 1x1 pixel images that load up silently and/or JavaScript tracking routines will be fine. Google® Analytics code works just fine, AdSense® performance tracking, as well as Yahoo® tracking and other affiliate network codes are all OK here.<br /><br />' . "\n";
57
  echo '<strong>You can also use these special replacement codes if you need them:</strong>' . "\n";
58
  echo '<ul>' . "\n";
59
  echo '<li><code>%%subscr_id%% = The PayPal® Subscription ID, which remains constant throughout any &amp; all future payments.</code> [ <a href="#" onclick="alert(\'There is one exception. If you are selling Lifetime or Fixed-Term ( non-recurring ) access, using a Buy It Now button; the %%subscr_id%% is actually set to the Transaction ID for the purchase.\\n\\nPayPal® does not provide a specific Subscription ID for Buy It Now purchases. Since Lifetime &amp; Fixed-Term Subscriptions are NOT recurring ( i.e. there is only ONE payment ), using the Transaction ID as the Subscription ID is a graceful way to deal with this minor conflict.\'); return false;">?</a> ]</li>' . "\n";
@@ -90,7 +90,7 @@ echo '<div class="ws-menu-page-group" title="Specific Post/Page Tracking Codes">
90
  /**/
91
  echo '<div class="ws-menu-page-section ws-plugin--s2member-sp-tracking-section">' . "\n";
92
  echo '<h3>Tracking Codes For Specific Post/Page Access ( optional )</h3>' . "\n";
93
- echo '<p>If you use affiliate software, a list server, tracking codes from advertising networks, or the like; you\'ll want to read this section. The HTML' . ((!$GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["is_wpmu_farm"]) ? ' and/or PHP' : '') . ' code that you enter below, will be loaded up in a web browser, after a Customer returns from a successful transaction at PayPal®; specifically for Post/Page Access. These Codes are NOT injected for any type of Member Level Access. These are only for Specific Post/Page transactions. The Tracking Codes that you enter below, will be displayed in the footer section of your WordPress® theme, after a Customer returns from PayPal®.</p>' . "\n";
94
  echo '<table class="form-table">' . "\n";
95
  echo '<tbody>' . "\n";
96
  echo '<tr>' . "\n";
@@ -106,7 +106,7 @@ echo '<tr>' . "\n";
106
  /**/
107
  echo '<td>' . "\n";
108
  echo '<textarea name="ws_plugin__s2member_sp_tracking_codes" id="ws-plugin--s2member-sp-tracking-codes" rows="8" wrap="off" spellcheck="false" style="font-family:Consolas, monospace;">' . format_to_edit ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["sp_tracking_codes"]) . '</textarea><br />' . "\n";
109
- echo 'Any valid XHTML / JavaScript' . ((!$GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["is_wpmu_farm"]) ? ' ( or even PHP )' : '') . ' code will work just fine here. Just try not to put anything here that would actually be visible to the Customer. Things like 1x1 pixel images that load up silently and/or JavaScript tracking routines will be fine. Google® Analytics code works just fine, AdSense® performance tracking, as well as Yahoo® tracking and other affiliate network codes are all OK here.<br /><br />' . "\n";
110
  echo '<strong>You can also use these special replacement codes if you need them:</strong>' . "\n";
111
  echo '<ul>' . "\n";
112
  echo '<li><code>%%txn_id%% = The PayPal® Transaction ID. PayPal® assigns a unique identifier for every purchase.</code></li>' . "\n";
@@ -175,7 +175,7 @@ echo '<div class="ws-menu-page-group" title="Other Tracking Methods Available">'
175
  /**/
176
  echo '<div class="ws-menu-page-section ws-plugin--s2member-other-methods-section">' . "\n";
177
  echo '<h3>Other Tracking Methods Are Available ( there\'s always a way )</h3>' . "\n";
178
- echo '<p>Check the s2Member API Notifications panel. You\'ll find additional layers of automation available through the use of the `Signup`, `Registration`, `Payment`, `EOT/Deletion`, `Refund/Reversal`, and `Specific Post/Page` notifications that are available to you through the s2Member API. The s2Member API Notifications make it possible to integrate with 3rd party applications; like list servers, affiliate programs, and other back-office routines; in more advanced ways. Since the s2Member API Notifications operate silently on the back-end, in conjunction with the PayPal® IPN system, they tend to be more reliable and also more versatile. That being said, nothing replaces the simplicity of Tracking Codes. The more advanced API Notifications are NOT always the best tool for the job. For instance, API Notifications will NOT work with Google® Analytics, or 1 pixel &lt;img&gt; tags. They operate silently behind-the-scene, using cURL connections, as opposed to being loaded in a browser.</p>' . "\n";
179
  echo '</div>' . "\n";
180
  /**/
181
  echo '</div>' . "\n";
36
  /**/
37
  echo '<div class="ws-menu-page-section ws-plugin--s2member-signup-tracking-section">' . "\n";
38
  echo '<h3>Membership Signup Tracking Codes ( optional )</h3>' . "\n";
39
+ echo '<p>If you use affiliate software, a list server, tracking codes from advertising networks, or the like; you\'ll want to read this section. The HTML' . ((!$GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["is_multisite_farm"]) ? ' and/or PHP' : '') . ' code that you enter below, will be loaded up in a web browser, after a Customer returns from a successful Signup through PayPal®. Tracking Codes are only displayed/processed one time for each Customer. s2Member will display your Tracking Codes in one of three possible locations... <strong>1.</strong> If possible, on the Registration Form, after returning from PayPal®. <strong>2.</strong> Otherwise, if possible, on the Login Form after Registration is completed. <strong>3.</strong> Otherwise, in the footer of your WordPress® theme, after the Customer\'s very first Login.</p>' . "\n";
40
  echo '<p>Signup Tracking Codes are displayed for all types of Membership Level Access. Including: Recurring Subscriptions ( with or without a free trial period ), Non-Recurring Subscriptions ( with or without a free trial period ), Lifetime Subscriptions, and even Fixed-Term Subscriptions. All of these are supported by s2Member\'s Button Generator, and all of these are supported here.</p>' . "\n";
41
  echo '<table class="form-table">' . "\n";
42
  echo '<tbody>' . "\n";
53
  /**/
54
  echo '<td>' . "\n";
55
  echo '<textarea name="ws_plugin__s2member_signup_tracking_codes" id="ws-plugin--s2member-signup-tracking-codes" rows="8" wrap="off" spellcheck="false" style="font-family:Consolas, monospace;">' . format_to_edit ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["signup_tracking_codes"]) . '</textarea><br />' . "\n";
56
+ echo 'Any valid XHTML / JavaScript' . ((!$GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["is_multisite_farm"]) ? ' ( or even PHP )' : '') . ' code will work just fine here. Just try not to put anything here that would actually be visible to the Customer. Things like 1x1 pixel images that load up silently and/or JavaScript tracking routines will be fine. Google® Analytics code works just fine, AdSense® performance tracking, as well as Yahoo® tracking and other affiliate network codes are all OK here.<br /><br />' . "\n";
57
  echo '<strong>You can also use these special replacement codes if you need them:</strong>' . "\n";
58
  echo '<ul>' . "\n";
59
  echo '<li><code>%%subscr_id%% = The PayPal® Subscription ID, which remains constant throughout any &amp; all future payments.</code> [ <a href="#" onclick="alert(\'There is one exception. If you are selling Lifetime or Fixed-Term ( non-recurring ) access, using a Buy It Now button; the %%subscr_id%% is actually set to the Transaction ID for the purchase.\\n\\nPayPal® does not provide a specific Subscription ID for Buy It Now purchases. Since Lifetime &amp; Fixed-Term Subscriptions are NOT recurring ( i.e. there is only ONE payment ), using the Transaction ID as the Subscription ID is a graceful way to deal with this minor conflict.\'); return false;">?</a> ]</li>' . "\n";
90
  /**/
91
  echo '<div class="ws-menu-page-section ws-plugin--s2member-sp-tracking-section">' . "\n";
92
  echo '<h3>Tracking Codes For Specific Post/Page Access ( optional )</h3>' . "\n";
93
+ echo '<p>If you use affiliate software, a list server, tracking codes from advertising networks, or the like; you\'ll want to read this section. The HTML' . ((!$GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["is_multisite_farm"]) ? ' and/or PHP' : '') . ' code that you enter below, will be loaded up in a web browser, after a Customer returns from a successful transaction at PayPal®; specifically for Post/Page Access. These Codes are NOT injected for any type of Member Level Access. These are only for Specific Post/Page transactions. The Tracking Codes that you enter below, will be displayed in the footer section of your WordPress® theme, after a Customer returns from PayPal®.</p>' . "\n";
94
  echo '<table class="form-table">' . "\n";
95
  echo '<tbody>' . "\n";
96
  echo '<tr>' . "\n";
106
  /**/
107
  echo '<td>' . "\n";
108
  echo '<textarea name="ws_plugin__s2member_sp_tracking_codes" id="ws-plugin--s2member-sp-tracking-codes" rows="8" wrap="off" spellcheck="false" style="font-family:Consolas, monospace;">' . format_to_edit ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["sp_tracking_codes"]) . '</textarea><br />' . "\n";
109
+ echo 'Any valid XHTML / JavaScript' . ((!$GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["is_multisite_farm"]) ? ' ( or even PHP )' : '') . ' code will work just fine here. Just try not to put anything here that would actually be visible to the Customer. Things like 1x1 pixel images that load up silently and/or JavaScript tracking routines will be fine. Google® Analytics code works just fine, AdSense® performance tracking, as well as Yahoo® tracking and other affiliate network codes are all OK here.<br /><br />' . "\n";
110
  echo '<strong>You can also use these special replacement codes if you need them:</strong>' . "\n";
111
  echo '<ul>' . "\n";
112
  echo '<li><code>%%txn_id%% = The PayPal® Transaction ID. PayPal® assigns a unique identifier for every purchase.</code></li>' . "\n";
175
  /**/
176
  echo '<div class="ws-menu-page-section ws-plugin--s2member-other-methods-section">' . "\n";
177
  echo '<h3>Other Tracking Methods Are Available ( there\'s always a way )</h3>' . "\n";
178
+ echo '<p>Check the s2Member API Notifications panel. You\'ll find additional layers of automation available through the use of the `Signup`, `Registration`, `Payment`, `EOT/Deletion`, `Refund/Reversal`, and `Specific Post/Page` notifications that are available to you through the s2Member API. The s2Member API Notifications make it possible to integrate with 3rd party applications; like list servers, affiliate programs, and other back-office routines; in more advanced ways. Since the s2Member API Notifications operate silently on the back-end, in conjunction with the PayPal® IPN system, they tend to be more reliable and also more versatile. That being said, nothing replaces the simplicity of Tracking Codes. The more advanced API Notifications are NOT always the best tool for the job. For instance, API Notifications will NOT work with Google® Analytics, or 1 pixel &lt;img&gt; tags. They operate silently behind-the-scene, using HTTP connections, as opposed to being loaded in a browser.</p>' . "\n";
179
  echo '</div>' . "\n";
180
  /**/
181
  echo '</div>' . "\n";
includes/syscon.inc.php CHANGED
@@ -20,13 +20,13 @@ if (realpath (__FILE__) === realpath ($_SERVER["SCRIPT_FILENAME"]))
20
  /*
21
  Configure the version for this release.
22
  */
23
- $GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["version"] = "3.0"; /* Since s2Member 3.0. */
24
  /*
25
- Detect if we are inside an MU installation.
26
  */
27
- if (($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["is_wpmu"] = function_exists ("wpmu_current_site"))/**/
28
- && (file_exists (dirname (dirname (__FILE__)) . "/wpmu.farm") || file_exists (TEMPLATEPATH . "/wpmu.farm")))
29
- $GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["is_wpmu_farm"] = true; /* Requires /wpmu.farm file. */
30
  /*
31
  Determine the full url to the directory this plugin resides in.
32
  */
@@ -165,10 +165,10 @@ function ws_plugin__s2member_configure_options_and_their_defaults ($options = FA
165
  "level3_catgs" => "", /* A comma-delimited list of Category IDs to protect. */
166
  "level4_catgs" => "", /* A comma-delimited list of Category IDs to protect. */
167
  /**/
168
- "level1_ptags" => "", /* A comma-delimited list of Page/Post Tags to protect. */
169
- "level2_ptags" => "", /* A comma-delimited list of Page/Post Tags to protect. */
170
- "level3_ptags" => "", /* A comma-delimited list of Page/Post Tags to protect. */
171
- "level4_ptags" => "", /* A comma-delimited list of Page/Post Tags to protect. */
172
  /**/
173
  "level1_posts" => "", /* A comma-delimited list of Post IDs to protect. */
174
  "level2_posts" => "", /* A comma-delimited list of Post IDs to protect. */
@@ -183,7 +183,7 @@ function ws_plugin__s2member_configure_options_and_their_defaults ($options = FA
183
  "specific_ids" => "", /* Comma-delimited list of Specific Post/Page IDs. */
184
  /**/
185
  "membership_eot_behavior" => "demote", /* Demote or delete Members? */
186
- "auto_eot_system_enabled" => "1"); /* Enabled by default; when options are updated. */
187
  /*
188
  Here they are merged. user options will overwrite some or all default values.
189
  */
20
  /*
21
  Configure the version for this release.
22
  */
23
+ $GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["version"] = "3.0.1"; /* Available since s2Member 3.0. */
24
  /*
25
+ Detect if this is WordPress® with Multisite/Networking.
26
  */
27
+ if (($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["is_multisite"] = ((function_exists ("is_multisite") && is_multisite ()) || function_exists ("wpmu_current_site")))/**/
28
+ && ((defined ("MULTISITE_FARM") && MULTISITE_FARM) || file_exists (dirname (dirname (__FILE__)) . "/multisite.farm"))) /* For Multisite Blog Farms. */
29
+ $GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["is_multisite_farm"] = true;
30
  /*
31
  Determine the full url to the directory this plugin resides in.
32
  */
165
  "level3_catgs" => "", /* A comma-delimited list of Category IDs to protect. */
166
  "level4_catgs" => "", /* A comma-delimited list of Category IDs to protect. */
167
  /**/
168
+ "level1_ptags" => "", /* A comma-delimited list of Post/Page Tags to protect. */
169
+ "level2_ptags" => "", /* A comma-delimited list of Post/Page Tags to protect. */
170
+ "level3_ptags" => "", /* A comma-delimited list of Post/Page Tags to protect. */
171
+ "level4_ptags" => "", /* A comma-delimited list of Post/Page Tags to protect. */
172
  /**/
173
  "level1_posts" => "", /* A comma-delimited list of Post IDs to protect. */
174
  "level2_posts" => "", /* A comma-delimited list of Post IDs to protect. */
183
  "specific_ids" => "", /* Comma-delimited list of Specific Post/Page IDs. */
184
  /**/
185
  "membership_eot_behavior" => "demote", /* Demote or delete Members? */
186
+ "auto_eot_system_enabled" => "1"); /* 0|1|2. 1 = WP-Cron, 2 = Cron tab. */
187
  /*
188
  Here they are merged. user options will overwrite some or all default values.
189
  */
readme.txt CHANGED
@@ -1,16 +1,17 @@
1
  === s2Member ( Membership w/ PayPal® Integration ) also works w/ BuddyPress ===
2
 
3
- Version: 3.0
4
- Stable tag: 3.0
5
- Framework: WS-P-2.1
6
 
7
  WordPress Compatible: yes
8
  BuddyPress Compatible: yes
9
- WP-Multisite Compatible: soon
 
10
 
11
  Tested up to: 3.0
12
- Requires at least: 2.8.4
13
- Requires: WordPress® 2.8.4+, PHP 5.2+
14
 
15
  Copyright: © 2009 WebSharks, Inc.
16
  License: GNU General Public License
@@ -40,7 +41,7 @@ s2Member is a robust/powerful ( and free ) membership management system for Word
40
 
41
  s2Member supports up to four primary Membership Levels, and unlimited Custom Capability Packages. This allows you to create an unlimited number of Membership Packages, all with different Capabilities and prices. You can label your primary Membership Levels anything you like. The defaults are Bronze, Silver, Gold, and Platinum.
42
 
43
- 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 Pages/Posts/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.
44
 
45
  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. For instance, s2Member is compatible with BuddyPress!
46
 
@@ -80,7 +81,7 @@ Yes, s2Member supports automation of account activation, welcome emails, confirm
80
  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`.
81
 
82
  = How does s2Member protect content from public access? =
83
- 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 Pages/Posts/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`.
84
 
85
  = Does s2Member provide an API that I can connect to? =
86
  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.
@@ -102,11 +103,21 @@ Archived releases of s2Member are maintained [here](http://wordpress.org/extend/
102
 
103
  == Upgrade Notice ==
104
 
 
 
 
105
  = 3.0 =
106
- Upgrade highly recommended. After upgrading, go to: `s2Member -> PayPal® Options -> EOT Behavior` to enable the Auto-EOT System ( new ). For full details, please read the Changelog.
107
 
108
  == Changelog ==
109
 
 
 
 
 
 
 
 
110
  = 3.0 =
111
  * Naming convention change. s2Member's Single-Page Access, is now referred to as "Specific Post/Page Access". The reason for this will become obvious after reading through some of the other changes in this version. Among other things, "Posts" are now supported, instead of just Pages. Custom "Post-Types" are also supported now. Custom Post-Types are coming in WordPress® 3.0+. WordPress® 3.0 is scheduled for official release in May 2010.
112
  * Specific Post/Page Access. s2Member now supports "Specific Post/Page Packages" too ( optional ). You can choose a "Leading" Post/Page, and also include "Additional" Posts/Pages. Customers will still land on your Leading Post/Page; BUT, they'll ALSO have access to any Additional Posts/Pages you've packaged together into one transaction. See: `s2Member -> PayPal® Buttons -> Specific Post/Page Buttons` for further details.
@@ -229,7 +240,7 @@ Upgrade highly recommended. After upgrading, go to: `s2Member -> PayPal® Option
229
  * The PayPal® Button Generator has been improved significantly. It now supports MANY new options for Subscription Lengths. All the way up to 5 years &amp; also Lifetime Access.
230
  * The PayPal® Button Generator now supports LIFETIME Subscriptions using `Buy It Now` buttons. Just choose `Lifetime` from the drop-down menu. This allows you to charge a Customer ONCE, and they'll never expire. It also makes the checkout experience more user-friendly, whenever your intention is to provide them lifetime access; as opposed to a specific number of days/weeks/months/years with recurring charges. s2Member now supports all of these methods.
231
  * The PayPal® Button Generator now supports over 20 different international currencies.
232
- * The PayPal® Button Generator now provides an alternative `Shortcode` method of insertion into Posts/Pages. If you were having problems associated with the Visual Editor for WordPress® ( i.e. raw code getting corrupted ), please use the new alternative format. This new format is made available after you click `Generate`. The Shortcode syntax is a more elegant solution than the Raw HTML plugin many of you were forced to use in previous versions of s2Member. The Alternative Shortcode syntax is every bit as powerful, without the headaches. The Shortcode syntax is also compatible with WordPress® MU filters.
233
  * Under `s2Member->General Options->Login Customizations`, you can now use a wider Logo Image, which automatically forces the Login/Registration forms to become wider overall. This adds a nice touch whenever you're using lots of Custom Fields. Otherwise you'll end up with a tall/narrow stack of form fields that really does not look nice :-). Try using a Logo Image about 550px wide.
234
  * Documentation updated throughout. Many files modified. Some minor changes in the menu structure and naming conventions. Stay tuned! Have fun, and make some money!
235
  * Please thank [Jennifer Stuart](http://scriptygoddess.com/) for a generous donation that helped make s2Member v2.8 possible.
1
  === s2Member ( Membership w/ PayPal® Integration ) also works w/ BuddyPress ===
2
 
3
+ Version: 3.0.1
4
+ Stable tag: 3.0.1
5
+ Framework: WS-P-2.2
6
 
7
  WordPress Compatible: yes
8
  BuddyPress Compatible: yes
9
+ WP Multisite Compatible: soon
10
+ Multisite Blog Farm Compatible: no
11
 
12
  Tested up to: 3.0
13
+ Requires at least: 2.9.2
14
+ Requires: WordPress® 2.9.2+, PHP 5.2+
15
 
16
  Copyright: © 2009 WebSharks, Inc.
17
  License: GNU General Public License
41
 
42
  s2Member supports up to four primary Membership Levels, and unlimited Custom Capability Packages. This allows you to create an unlimited number of Membership Packages, all with different Capabilities and prices. You can label your primary Membership Levels anything you like. The defaults are Bronze, Silver, Gold, and Platinum.
43
 
44
+ 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.
45
 
46
  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. For instance, s2Member is compatible with BuddyPress!
47
 
81
  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`.
82
 
83
  = How does s2Member protect content from public access? =
84
+ 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`.
85
 
86
  = Does s2Member provide an API that I can connect to? =
87
  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.
103
 
104
  == Upgrade Notice ==
105
 
106
+ = 3.0.1 =
107
+ No major changes. Just a few compatiblity improvements.
108
+
109
  = 3.0 =
110
+ Many new features, fixes, and improvements. Upgrade highly recommended.
111
 
112
  == Changelog ==
113
 
114
+ = 3.0.1 =
115
+ * Compatibility. The function `ws_plugin__s2member_curlpsr()` has been replaced by `ws_plugin__s2member_remote()`, which makes use of `wp_remote_request()` through the WP_Http class. This removes s2Member's absolute dependency on the cURL extension for PHP. Removing this dependency, allows s2Member/WordPress® to work out the best method of communication; based on what the installation server has available.
116
+ * Compatibility. The MailChimp® API Class has also been modified to use `ws_plugin__s2member_remote()`. In previous versions of s2Member, the MailChimp® API required `allow_url_fopen = on` because it used the fsockopen method to communicate with the MailChimp® server. Removing this dependency on fsockopen, allows s2Member/WordPress® to work out the best method of communication; based on what the installation server has available.
117
+ * Compatibility. s2Member's Auto-EOT System is no longer absolutely dependent on WP-Cron. A new option has been added that allows you to run s2Member's Auto-EOT System through a server-side Cron Job - if you wish to. This makes s2Member compatible with hosting providers that disable WP-Cron for one reason or another.
118
+ * Updated minimum requirements to WordPress® 2.9.2.
119
+ * Framework updated to WS-P-2.2.
120
+
121
  = 3.0 =
122
  * Naming convention change. s2Member's Single-Page Access, is now referred to as "Specific Post/Page Access". The reason for this will become obvious after reading through some of the other changes in this version. Among other things, "Posts" are now supported, instead of just Pages. Custom "Post-Types" are also supported now. Custom Post-Types are coming in WordPress® 3.0+. WordPress® 3.0 is scheduled for official release in May 2010.
123
  * Specific Post/Page Access. s2Member now supports "Specific Post/Page Packages" too ( optional ). You can choose a "Leading" Post/Page, and also include "Additional" Posts/Pages. Customers will still land on your Leading Post/Page; BUT, they'll ALSO have access to any Additional Posts/Pages you've packaged together into one transaction. See: `s2Member -> PayPal® Buttons -> Specific Post/Page Buttons` for further details.
240
  * The PayPal® Button Generator has been improved significantly. It now supports MANY new options for Subscription Lengths. All the way up to 5 years &amp; also Lifetime Access.
241
  * The PayPal® Button Generator now supports LIFETIME Subscriptions using `Buy It Now` buttons. Just choose `Lifetime` from the drop-down menu. This allows you to charge a Customer ONCE, and they'll never expire. It also makes the checkout experience more user-friendly, whenever your intention is to provide them lifetime access; as opposed to a specific number of days/weeks/months/years with recurring charges. s2Member now supports all of these methods.
242
  * The PayPal® Button Generator now supports over 20 different international currencies.
243
+ * The PayPal® Button Generator now provides an alternative `Shortcode` method of insertion into Posts/Pages. If you were having problems associated with the Visual Editor for WordPress® ( i.e. raw code getting corrupted ), please use the new alternative format. This new format is made available after you click `Generate`. The Shortcode syntax is a more elegant solution than the Raw HTML plugin many of you were forced to use in previous versions of s2Member. The Alternative Shortcode syntax is every bit as powerful, without the headaches. The Shortcode syntax is also compatible with WordPress® Multisite KSES filters.
244
  * Under `s2Member->General Options->Login Customizations`, you can now use a wider Logo Image, which automatically forces the Login/Registration forms to become wider overall. This adds a nice touch whenever you're using lots of Custom Fields. Otherwise you'll end up with a tall/narrow stack of form fields that really does not look nice :-). Try using a Logo Image about 550px wide.
245
  * Documentation updated throughout. Many files modified. Some minor changes in the menu structure and naming conventions. Stay tuned! Have fun, and make some money!
246
  * Please thank [Jennifer Stuart](http://scriptygoddess.com/) for a generous donation that helped make s2Member v2.8 possible.
s2member.php CHANGED
@@ -9,17 +9,18 @@ along with this software. In the main directory, see: /licensing/
9
  If not, see: <http://www.gnu.org/licenses/>.
10
  */
11
  /*
12
- Version: 3.0
13
- Stable tag: 3.0
14
- Framework: WS-P-2.1
15
 
16
  WordPress Compatible: yes
17
  BuddyPress Compatible: yes
18
- WP-Multisite Compatible: soon
 
19
 
20
  Tested up to: 3.0
21
- Requires at least: 2.8.4
22
- Requires: WordPress® 2.8.4+, PHP 5.2+
23
 
24
  Copyright: © 2009 WebSharks, Inc.
25
  License: GNU General Public License
@@ -43,7 +44,7 @@ if (realpath (__FILE__) === realpath ($_SERVER["SCRIPT_FILENAME"]))
43
  /*
44
  Compatibility checks.
45
  */
46
- if (version_compare (PHP_VERSION, "5.2", ">=") && version_compare (get_bloginfo ("version"), "2.8.4", ">=") && !isset ($GLOBALS["WS_PLUGIN__"]["s2member"]) && function_exists ("curl_init"))
47
  {
48
  /*
49
  Record the location of this file.
@@ -71,13 +72,9 @@ else if (is_admin () || ($_GET["preview"] && $_GET["template"]))
71
  {
72
  register_shutdown_function (create_function ('', 'echo \'<script type="text/javascript">alert(\\\'You need PHP version 5.2 or higher to use the s2Member plugin.\\\');</script>\';'));
73
  }
74
- else if (!version_compare (get_bloginfo ("version"), "2.8.4", ">="))
75
  {
76
- register_shutdown_function (create_function ('', 'echo \'<script type="text/javascript">alert(\\\'You need WordPress® 2.8.4 or higher to use the s2Member plugin.\\\');</script>\';'));
77
- }
78
- else if (!function_exists ("curl_init"))
79
- {
80
- register_shutdown_function (create_function ('', 'echo \'<script type="text/javascript">alert(\\\'You need the CURL extension for PHP to use the s2Member plugin.\\\');</script>\';'));
81
  }
82
  }
83
  ?>
9
  If not, see: <http://www.gnu.org/licenses/>.
10
  */
11
  /*
12
+ Version: 3.0.1
13
+ Stable tag: 3.0.1
14
+ Framework: WS-P-2.2
15
 
16
  WordPress Compatible: yes
17
  BuddyPress Compatible: yes
18
+ WP Multisite Compatible: soon
19
+ Multisite Blog Farm Compatible: no
20
 
21
  Tested up to: 3.0
22
+ Requires at least: 2.9.2
23
+ Requires: WordPress® 2.9.2+, PHP 5.2+
24
 
25
  Copyright: © 2009 WebSharks, Inc.
26
  License: GNU General Public License
44
  /*
45
  Compatibility checks.
46
  */
47
+ if (version_compare (PHP_VERSION, "5.2", ">=") && version_compare (get_bloginfo ("version"), "2.9.2", ">=") && !isset ($GLOBALS["WS_PLUGIN__"]["s2member"]))
48
  {
49
  /*
50
  Record the location of this file.
72
  {
73
  register_shutdown_function (create_function ('', 'echo \'<script type="text/javascript">alert(\\\'You need PHP version 5.2 or higher to use the s2Member plugin.\\\');</script>\';'));
74
  }
75
+ else if (!version_compare (get_bloginfo ("version"), "2.9.2", ">="))
76
  {
77
+ register_shutdown_function (create_function ('', 'echo \'<script type="text/javascript">alert(\\\'You need WordPress® 2.9.2 or higher to use the s2Member plugin.\\\');</script>\';'));
 
 
 
 
78
  }
79
  }
80
  ?>