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

Version Description

  • Powerful new feature! - s2Member now supports unlimited Custom Capabilities. This allows you to create an unlimited number of Membership Packages, all with different Capabilities ( customized specifically for what your site offers ). Custom Capabilities can also be configured on a per-User basis through your WordPress Dashboard, under Users. For further details, see: s2Member -> API Scripting -> Custom Capability Packages.
  • Powerful new feature! - Now you can sell Single-Page Access too, using "Buy Now" buttons. Single-Page Access works independently from Member Level Access. That is, you can sell an unlimited number of Pages using "Buy Now" Buttons, and your Customers will NOT be required to have a Membership Account with your site in order to receive access. If they are already a Member, that's fine, but they won't need to be. Further details are provided under s2Member -> PayPal Buttons.
  • MailChimp integration. s2Member can now be integrated with MailChimp. MailChimp is an email marketing service. MailChimp makes it easy to send email newsletters to your Customers, manage your MailChimp subscriber lists, and track campaign performance. Although s2Member can be integrated with almost ANY list server, we highly recommend MailChimp; because of their powerful API for MailChimp services. In future versions of s2Member, we plan to build additional features into s2Member that work with, and extend, MailChimp services.
  • AWeber integration. As a secondary option, s2Member can also be integrated with AWeber. AWeber is an email marketing service. Whether you're looking to get your first email campaign off the ground, or you're a seasoned veteran who wants to dig into advanced tools like detailed email web analytics, activity based segmentation, geo-targeting and broadcast split-testing, AWeber's got just what you need to make email marketing work for you.
  • Bug fix. Some of the %%replacement_codes%% for email messages were returning URL-encoded values. Replacement codes DO return URL-encoded values for API Notifications, because those are designed for use within URLs. However, they should NOT be encoded for email messages. This has been corrected in s2Member v2.8.6.
  • Bug fix. S2MEMBER_LOGIN_WELCOME_PAGE_URL was missing in the s2Member JavaScript API. This has been corrected in s2Member v2.8.6.
  • Important change. The API Constant: S2MEMBER_CURRENT_USER_FIELDS is now a JSON-encoded array, rather than a serialized array. Check s2Member -> API Scripting for code samples. This makes S2MEMBER_CURRENT_USER_FIELDS compatible with the PHP API, and also with the s2Member JavaScript API. In PHP, use json_decode() instead of unserialize().
  • Important change. The API Constant: S2MEMBER_CURRENT_USER_IS_LOGGED_IN works a little bit differently than it has in previous versions. Starting with s2Member v2.8.6, you should change any existing references to: S2MEMBER_CURRENT_USER_IS_LOGGED_IN, into this new API Constant: S2MEMBER_CURRENT_USER_IS_LOGGED_IN_AS_MEMBER. These two API Constants are documented under s2Member -> API Scripting. We're not getting rid of S2MEMBER_CURRENT_USER_IS_LOGGED_IN ( it's still useful ), but it does work a bit differently than it has in previous versions. Check the documentation if you're unsure, and we're sorry for the change-up.
  • Under s2Member -> General Options, there is a new configuration option for Profile Modifications.
  • Under s2Member -> PayPal Options, there is a new configuration option for EOT behavior.
  • The s2Member -> API Tracking field for Signup Confirmation, now supports PHP code too!
  • The PayPal Button Generator for s2Member, now supports Subscription Modification Buttons.
  • The PayPal Button Generator for s2Member, now supports Subscription Cancellation Buttons.
  • A new s2Member API Notification event has been added for Single-Page Access.
  • The PayPal Button Generator for s2Member, now supports "Buy Now" Buttons.
  • A new s2Member API Notification event has been added for Registrations.
  • We've added a new Quick Start Guide for site owners.
  • Documentation and code samples updated throughout.
  • Support for WordPress MU has been dropped, for now. Once WP 3.0 is released, we will come back to this. If anyone can help contribute to this effort, I would be very appreciative.
Download this release

Release Info

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

Code changes from version 2.8.5 to 2.8.6

Files changed (115) hide show
  1. images/ajax-loader.gif +0 -0
  2. images/aweber-logo.png +0 -0
  3. images/brand-installation.fla +0 -0
  4. images/brand-installation.png +0 -0
  5. images/logo.fla +0 -0
  6. images/logo.png +0 -0
  7. images/mailchimp-stamp.png +0 -0
  8. includes/functions/activate-deactivate.inc.php +13 -0
  9. includes/functions/admin-lockout.inc.php +2 -3
  10. includes/functions/constants.inc.php +8 -4
  11. includes/functions/js-globals.inc.php +6 -0
  12. includes/functions/menu-pages.inc.php +31 -19
  13. includes/functions/page-level-access.inc.php +3 -0
  14. includes/functions/paypal-notify.inc.php +221 -128
  15. includes/functions/paypal-register.inc.php +0 -40
  16. includes/functions/paypal-return.inc.php +144 -65
  17. includes/functions/register-access.inc.php +202 -8
  18. includes/functions/shortcodes.inc.php +73 -32
  19. includes/functions/sp-access.inc.php +73 -0
  20. includes/functions/user-deletions.inc.php +7 -6
  21. includes/functions/users-list.inc.php +36 -3
  22. includes/functions/utilities.inc.php +25 -18
  23. includes/hooks.inc.php +2 -1
  24. includes/mailchimp/index.php +0 -0
  25. includes/mailchimp/nc-mcapi.inc.php +1814 -0
  26. includes/menu-pages/api-ops.inc.php +152 -47
  27. includes/menu-pages/button.html +9 -8
  28. includes/menu-pages/buttons.inc.php +254 -26
  29. includes/menu-pages/c-button.html +3 -0
  30. includes/menu-pages/c-shortcode.html +1 -0
  31. includes/menu-pages/{con-samps/current_user_access_label.php → code-samples/current-user-access-label.php} +0 -0
  32. includes/menu-pages/code-samples/current-user-access-level-conditional-upgrades.php +11 -0
  33. includes/menu-pages/{con-samps/current_user_access_level.php → code-samples/current-user-access-level.php} +6 -6
  34. includes/menu-pages/code-samples/current-user-can-ccaps-1.php +15 -0
  35. includes/menu-pages/code-samples/current-user-can-ccaps-2.php +28 -0
  36. includes/menu-pages/code-samples/current-user-can-constants-1.php +7 -0
  37. includes/menu-pages/code-samples/current-user-can-constants-2.php +13 -0
  38. includes/menu-pages/code-samples/current-user-can-full-access.php +5 -0
  39. includes/menu-pages/code-samples/current-user-can-specific-content.php +13 -0
  40. includes/menu-pages/{con-samps/current_user_custom.php → code-samples/current-user-custom.php} +0 -0
  41. includes/menu-pages/{con-samps/current_user_display_name.php → code-samples/current-user-display-name.php} +0 -0
  42. includes/menu-pages/{con-samps/current_user_downloads_allowed_days.php → code-samples/current-user-downloads-allowed-days.php} +0 -0
  43. includes/menu-pages/{con-samps/current_user_downloads_allowed_is_unlimited.php → code-samples/current-user-downloads-allowed-is-unlimited.php} +0 -0
  44. includes/menu-pages/{con-samps/current_user_downloads_allowed.php → code-samples/current-user-downloads-allowed.php} +0 -0
  45. includes/menu-pages/{con-samps/current_user_downloads_currently.php → code-samples/current-user-downloads-currently.php} +0 -0
  46. includes/menu-pages/{con-samps/current_user_email.php → code-samples/current-user-email.php} +0 -0
  47. includes/menu-pages/code-samples/current-user-fields.php +7 -0
  48. includes/menu-pages/{con-samps/current_user_first_name.php → code-samples/current-user-first-name.php} +0 -0
  49. includes/menu-pages/{con-samps/current_user_id.php → code-samples/current-user-id.php} +0 -0
  50. includes/menu-pages/{con-samps/current_user_ip.php → code-samples/current-user-ip.php} +0 -0
  51. includes/menu-pages/code-samples/current-user-is-logged-in-as-member.php +3 -0
  52. includes/menu-pages/code-samples/current-user-is-logged-in.php +3 -0
  53. includes/menu-pages/{con-samps/current_user_last_name.php → code-samples/current-user-last-name.php} +0 -0
  54. includes/menu-pages/{con-samps/current_user_login.php → code-samples/current-user-login.php} +0 -0
  55. includes/menu-pages/code-samples/current-user-profile-modification-page-url-1.php +1 -0
  56. includes/menu-pages/code-samples/current-user-profile-modification-page-url-2.php +5 -0
  57. includes/menu-pages/code-samples/current-user-profile-modification-page-url-3.php +1 -0
  58. includes/menu-pages/code-samples/current-user-registration-days-dripping.php +17 -0
  59. includes/menu-pages/code-samples/current-user-registration-days.php +22 -0
  60. includes/menu-pages/{con-samps/current_user_registration_time.php → code-samples/current-user-registration-time.php} +0 -0
  61. includes/menu-pages/{con-samps/current_user_subscr_id.php → code-samples/current-user-subscr-id.php} +0 -0
  62. includes/menu-pages/code-samples/current-user-value-for-pp-on0-os0.php +4 -0
  63. includes/menu-pages/{con-samps/file_download_limit_exceeded_page_url.php → code-samples/file-download-limit-exceeded-page-url.php} +0 -0
  64. includes/menu-pages/code-samples/index.php +0 -0
  65. includes/menu-pages/code-samples/is-user-logged-in.php +5 -0
  66. includes/menu-pages/{con-samps/level1_file_downloads_allowed.php → code-samples/level1-file-downloads-allowed-days.php} +0 -0
  67. includes/menu-pages/{con-samps/level1_file_downloads_allowed_days.php → code-samples/level1-file-downloads-allowed.php} +0 -0
  68. includes/menu-pages/{con-samps/level1_label.php → code-samples/level1-label.php} +0 -0
  69. includes/menu-pages/{con-samps/level2_file_downloads_allowed.php → code-samples/level2-file-downloads-allowed-days.php} +0 -0
  70. includes/menu-pages/{con-samps/level2_file_downloads_allowed_days.php → code-samples/level2-file-downloads-allowed.php} +0 -0
  71. includes/menu-pages/{con-samps/level2_label.php → code-samples/level2-label.php} +0 -0
  72. includes/menu-pages/{con-samps/level3_file_downloads_allowed.php → code-samples/level3-file-downloads-allowed-days.php} +0 -0
  73. includes/menu-pages/{con-samps/level3_file_downloads_allowed_days.php → code-samples/level3-file-downloads-allowed.php} +0 -0
  74. includes/menu-pages/{con-samps/level3_label.php → code-samples/level3-label.php} +0 -0
  75. includes/menu-pages/{con-samps/level4_file_downloads_allowed.php → code-samples/level4-file-downloads-allowed-days.php} +0 -0
  76. includes/menu-pages/{con-samps/level4_file_downloads_allowed_days.php → code-samples/level4-file-downloads-allowed.php} +0 -0
  77. includes/menu-pages/{con-samps/level4_label.php → code-samples/level4-label.php} +0 -0
  78. includes/menu-pages/{con-samps/login_page_url.php → code-samples/login-page-url.php} +0 -0
  79. includes/menu-pages/{con-samps/login_welcome_page_url.php → code-samples/login-welcome-page-url.php} +0 -0
  80. includes/menu-pages/{con-samps/logout_page_url.php → code-samples/logout-page-url.php} +0 -0
  81. includes/menu-pages/{con-samps/membership_options_page_url.php → code-samples/membership-options-page-url.php} +0 -0
  82. includes/menu-pages/{con-samps/paypal_business.php → code-samples/paypal-business.php} +0 -0
  83. includes/menu-pages/{con-samps/paypal_endpoint.php → code-samples/paypal-endpoint.php} +0 -0
  84. includes/menu-pages/{con-samps/paypal_notify_url.php → code-samples/paypal-notify-url.php} +0 -0
  85. includes/menu-pages/{con-samps/paypal_return_url.php → code-samples/paypal-return-url.php} +0 -0
  86. includes/menu-pages/{con-samps/reg_email_from_email.php → code-samples/reg-email-from-email.php} +0 -0
  87. includes/menu-pages/{con-samps/reg_email_from_name.php → code-samples/reg-email-from-name.php} +0 -0
  88. includes/menu-pages/con-samps/current_user_fields.php +0 -7
  89. includes/menu-pages/con-samps/current_user_is_logged_in.php +0 -3
  90. includes/menu-pages/con-samps/current_user_profile_modification_page_url.php +0 -8
  91. includes/menu-pages/con-samps/current_user_registration_days.php +0 -15
  92. includes/menu-pages/cur-samps.php +0 -33
  93. includes/menu-pages/down-ops.inc.php +7 -5
  94. includes/menu-pages/drip-samps.php +0 -9
  95. includes/menu-pages/els-ops.inc.php +291 -0
  96. includes/menu-pages/events.inc.php +0 -118
  97. includes/menu-pages/info.inc.php +2 -0
  98. includes/menu-pages/menu-pages.css +10 -1
  99. includes/menu-pages/menu-pages.js +153 -81
  100. includes/menu-pages/mod-samps.php +0 -33
  101. includes/menu-pages/options.inc.php +143 -38
  102. includes/menu-pages/paypal-ops.inc.php +129 -25
  103. includes/menu-pages/s2m-samps.php +0 -33
  104. includes/menu-pages/scripting.inc.php +196 -99
  105. includes/menu-pages/shortcode.html +1 -1
  106. includes/menu-pages/sp-button.html +20 -0
  107. includes/menu-pages/sp-shortcode.html +1 -0
  108. includes/menu-pages/start.inc.php +147 -0
  109. includes/menu-pages/trk-ops.inc.php +33 -22
  110. includes/s2member-min.js +1 -1
  111. includes/s2member.js +1 -1
  112. includes/syscon.inc.php +71 -8
  113. licensing/license.txt +17 -3
  114. readme.txt +45 -17
  115. s2member.php +4 -3
images/ajax-loader.gif ADDED
Binary file
images/aweber-logo.png ADDED
Binary file
images/brand-installation.fla ADDED
Binary file
images/brand-installation.png ADDED
Binary file
images/logo.fla CHANGED
Binary file
images/logo.png CHANGED
Binary file
images/mailchimp-stamp.png ADDED
Binary file
includes/functions/activate-deactivate.inc.php CHANGED
@@ -108,6 +108,19 @@ function ws_plugin__s2member_activate ()
108
  if (!is_array (get_option ("ws_plugin__s2member_options")))
109
  update_option ("ws_plugin__s2member_options", array ());
110
  /**/
 
 
 
 
 
 
 
 
 
 
 
 
 
111
  return;
112
  }
113
  /*
108
  if (!is_array (get_option ("ws_plugin__s2member_options")))
109
  update_option ("ws_plugin__s2member_options", array ());
110
  /**/
111
+ if (get_option ("ws_plugin__s2member_configured")) /* If they already have s2Member configured, read the Changelog. */
112
+ {
113
+ $notice = '<strong>s2Member</strong> has been <strong>re-activated</strong>, with the latest version.<br />';
114
+ $notice .= 'Have fun, <a href="admin.php?page=ws-plugin--s2member-info">read the Changelog</a>, and make some money! :-)';
115
+ ws_plugin__s2member_enqueue_admin_notice ($notice, array ("plugins.php", "ws-plugin--s2member-options"));
116
+ }
117
+ else /* Otherwise, we'll help the site owner out by giving them a link to the Quick Start Guide. */
118
+ {
119
+ $notice = '<strong>s2Member</strong> has been <strong>activated</strong>, with the latest version.<br />';
120
+ $notice .= 'Have fun, <a href="admin.php?page=ws-plugin--s2member-start">read the Quick Start Guide</a>, and make some money! :-)';
121
+ ws_plugin__s2member_enqueue_admin_notice ($notice, array ("plugins.php", "ws-plugin--s2member-options"));
122
+ }
123
+ /**/
124
  return;
125
  }
126
  /*
includes/functions/admin-lockout.inc.php CHANGED
@@ -19,9 +19,8 @@ Attach to: add_action("admin_init");
19
  */
20
  function ws_plugin__s2member_admin_lockout ()
21
  {
22
- /* This prevents users ( who cannot edit ) from gaining any access to the admin area. */
23
- /* WordPress® handles most of this on its own, but this prevents profile access also. */
24
- if (!current_user_can ("edit_posts") /* In other words, if they are a subscriber or a member. */
25
  && wp_redirect (get_page_link ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["login_welcome_page"])) !== "nill")
26
  exit;
27
  /**/
19
  */
20
  function ws_plugin__s2member_admin_lockout ()
21
  {
22
+ if ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["force_admin_lockouts"]/**/
23
+ && !current_user_can ("edit_posts") /* In other words: Subscribers and Members. */
 
24
  && wp_redirect (get_page_link ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["login_welcome_page"])) !== "nill")
25
  exit;
26
  /**/
includes/functions/constants.inc.php CHANGED
@@ -27,8 +27,9 @@ function ws_plugin__s2member_constants ()
27
  $file_downloads = ws_plugin__s2member_user_downloads ("", $metas["s2member_file_download_access_log"]);
28
  $login_redirection_override = $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["login_redirection_override"];
29
  /**/
30
- define ("S2MEMBER_CURRENT_USER_IS_LOGGED_IN", (($level >= 1) ? true : false)); /* This will always be (bool) true or false. False if they are not currently logged in. */
31
- define ("S2MEMBER_CURRENT_USER_ACCESS_LEVEL", (int)$level); /* This will always be (int) negative 1 thru positive 4. -1 if user is not logged in. 0 if logged in w/o access. */
 
32
  define ("S2MEMBER_CURRENT_USER_ACCESS_LABEL", $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["level" . $level . "_label"]); /* This will always be a (string). Empty if not logged in. */
33
  define ("S2MEMBER_CURRENT_USER_SUBSCR_ID", (($current_user) ? (($metas["s2member_subscr_id"]) ? $metas["s2member_subscr_id"] : $current_user->ID) : "")); /* Empty if not logged in. */
34
  define ("S2MEMBER_CURRENT_USER_CUSTOM", (($current_user) ? $metas["s2member_custom"] : "")); /* This will always a (string). However, it will be empty if not logged in. */
@@ -41,10 +42,10 @@ function ws_plugin__s2member_constants ()
41
  define ("S2MEMBER_CURRENT_USER_EMAIL", (($current_user) ? $current_user->user_email : "")); /* This will always be a (string). Empty if not logged in. */
42
  define ("S2MEMBER_CURRENT_USER_IP", $_SERVER["REMOTE_ADDR"]); /* This will always be a (string). It may be empty if the user is browsing anonymously. */
43
  define ("S2MEMBER_CURRENT_USER_ID", (($current_user) ? (int)$current_user->ID : 0)); /* This will always be an (int). Zero if not logged in. */
44
- define ("S2MEMBER_CURRENT_USER_FIELDS", (($current_user) ? serialize (array_merge /* Always a serialized (array). This includes custom fields. */
45
  (array ("id" => S2MEMBER_CURRENT_USER_ID, "ip" => S2MEMBER_CURRENT_USER_IP, "email" => S2MEMBER_CURRENT_USER_EMAIL, "login" => S2MEMBER_CURRENT_USER_LOGIN,/**/
46
  "first_name" => S2MEMBER_CURRENT_USER_FIRST_NAME, "last_name" => S2MEMBER_CURRENT_USER_LAST_NAME, "display_name" => S2MEMBER_CURRENT_USER_DISPLAY_NAME,/**/
47
- "subscr_id" => S2MEMBER_CURRENT_USER_SUBSCR_ID, "custom" => S2MEMBER_CURRENT_USER_CUSTOM), $metas["s2member_custom_fields"])) : serialize (array ())));
48
  /**/
49
  define ("S2MEMBER_CURRENT_USER_DOWNLOADS_ALLOWED", (int)$file_downloads["allowed"]); /* This will always be an integer value (int) >= 0 where 0 means no access. */
50
  define ("S2MEMBER_CURRENT_USER_DOWNLOADS_ALLOWED_IS_UNLIMITED", (($file_downloads["allowed"] >= 999999999) ? true : false)); /* This will always be (bool). */
@@ -85,6 +86,9 @@ function ws_plugin__s2member_constants ()
85
  define ("S2MEMBER_PAYPAL_ENDPOINT", (($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["paypal_sandbox"]) ? "www.sandbox.paypal.com" : "www.paypal.com")); /* Using sandbox? */
86
  define ("S2MEMBER_PAYPAL_BUSINESS", $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["paypal_business"]); /* This is the email address that identifies your paypal business. */
87
  /**/
 
 
 
88
  return;
89
  }
90
  /*
27
  $file_downloads = ws_plugin__s2member_user_downloads ("", $metas["s2member_file_download_access_log"]);
28
  $login_redirection_override = $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["login_redirection_override"];
29
  /**/
30
+ define ("S2MEMBER_CURRENT_USER_IS_LOGGED_IN", (($current_user) ? true : false)); /* This will always be (bool) true or false. False if they are NOT currently logged in. */
31
+ define ("S2MEMBER_CURRENT_USER_IS_LOGGED_IN_AS_MEMBER", (($current_user && $level >= 1) ? true : false)); /* This will always be (bool) true or false. Level >= 1 for Members. */
32
+ define ("S2MEMBER_CURRENT_USER_ACCESS_LEVEL", (int)$level); /* This will always be (int) negative 1 thru positive 4. -1 if user is not logged in. 0 if logged in as a Subscriber. */
33
  define ("S2MEMBER_CURRENT_USER_ACCESS_LABEL", $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["level" . $level . "_label"]); /* This will always be a (string). Empty if not logged in. */
34
  define ("S2MEMBER_CURRENT_USER_SUBSCR_ID", (($current_user) ? (($metas["s2member_subscr_id"]) ? $metas["s2member_subscr_id"] : $current_user->ID) : "")); /* Empty if not logged in. */
35
  define ("S2MEMBER_CURRENT_USER_CUSTOM", (($current_user) ? $metas["s2member_custom"] : "")); /* This will always a (string). However, it will be empty if not logged in. */
42
  define ("S2MEMBER_CURRENT_USER_EMAIL", (($current_user) ? $current_user->user_email : "")); /* This will always be a (string). Empty if not logged in. */
43
  define ("S2MEMBER_CURRENT_USER_IP", $_SERVER["REMOTE_ADDR"]); /* This will always be a (string). It may be empty if the user is browsing anonymously. */
44
  define ("S2MEMBER_CURRENT_USER_ID", (($current_user) ? (int)$current_user->ID : 0)); /* This will always be an (int). Zero if not logged in. */
45
+ define ("S2MEMBER_CURRENT_USER_FIELDS", (($current_user) ? json_encode (array_merge /* Always a json_encode (array). This includes custom fields. */
46
  (array ("id" => S2MEMBER_CURRENT_USER_ID, "ip" => S2MEMBER_CURRENT_USER_IP, "email" => S2MEMBER_CURRENT_USER_EMAIL, "login" => S2MEMBER_CURRENT_USER_LOGIN,/**/
47
  "first_name" => S2MEMBER_CURRENT_USER_FIRST_NAME, "last_name" => S2MEMBER_CURRENT_USER_LAST_NAME, "display_name" => S2MEMBER_CURRENT_USER_DISPLAY_NAME,/**/
48
+ "subscr_id" => S2MEMBER_CURRENT_USER_SUBSCR_ID, "custom" => S2MEMBER_CURRENT_USER_CUSTOM), $metas["s2member_custom_fields"])) : json_encode (array ())));
49
  /**/
50
  define ("S2MEMBER_CURRENT_USER_DOWNLOADS_ALLOWED", (int)$file_downloads["allowed"]); /* This will always be an integer value (int) >= 0 where 0 means no access. */
51
  define ("S2MEMBER_CURRENT_USER_DOWNLOADS_ALLOWED_IS_UNLIMITED", (($file_downloads["allowed"] >= 999999999) ? true : false)); /* This will always be (bool). */
86
  define ("S2MEMBER_PAYPAL_ENDPOINT", (($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["paypal_sandbox"]) ? "www.sandbox.paypal.com" : "www.paypal.com")); /* Using sandbox? */
87
  define ("S2MEMBER_PAYPAL_BUSINESS", $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["paypal_business"]); /* This is the email address that identifies your paypal business. */
88
  /**/
89
+ define ("S2MEMBER_CURRENT_USER_VALUE_FOR_PP_ON0", ((S2MEMBER_CURRENT_USER_SUBSCR_ID) ? "Updating Subscr" : "")); /* Auto-fills the on0 value in PayPal buttons. */
90
+ define ("S2MEMBER_CURRENT_USER_VALUE_FOR_PP_OS0", ((S2MEMBER_CURRENT_USER_VALUE_FOR_PP_ON0) ? S2MEMBER_CURRENT_USER_SUBSCR_ID : "")); /* For the os0 value. */
91
+ /**/
92
  return;
93
  }
94
  /*
includes/functions/js-globals.inc.php CHANGED
@@ -61,6 +61,7 @@ function ws_plugin__s2member_js_w_globals ()
61
  header ("Pragma: public");
62
  /**/
63
  $g = "var S2MEMBER_CURRENT_USER_IS_LOGGED_IN = " . ((S2MEMBER_CURRENT_USER_IS_LOGGED_IN) ? "true" : "false") . ",";
 
64
  $g .= "S2MEMBER_CURRENT_USER_ACCESS_LEVEL = " . S2MEMBER_CURRENT_USER_ACCESS_LEVEL . ",";
65
  $g .= "S2MEMBER_CURRENT_USER_ACCESS_LABEL = '" . preg_replace ("/'/", "\'", S2MEMBER_CURRENT_USER_ACCESS_LABEL) . "',";
66
  $g .= "S2MEMBER_CURRENT_USER_SUBSCR_ID = '" . preg_replace ("/'/", "\'", S2MEMBER_CURRENT_USER_SUBSCR_ID) . "',";
@@ -74,6 +75,7 @@ function ws_plugin__s2member_js_w_globals ()
74
  $g .= "S2MEMBER_CURRENT_USER_EMAIL = '" . preg_replace ("/'/", "\'", S2MEMBER_CURRENT_USER_EMAIL) . "',";
75
  $g .= "S2MEMBER_CURRENT_USER_IP = '" . preg_replace ("/'/", "\'", S2MEMBER_CURRENT_USER_IP) . "',";
76
  $g .= "S2MEMBER_CURRENT_USER_ID = " . S2MEMBER_CURRENT_USER_ID . ",";
 
77
  /**/
78
  $g .= "S2MEMBER_CURRENT_USER_DOWNLOADS_ALLOWED = " . S2MEMBER_CURRENT_USER_DOWNLOADS_ALLOWED . ",";
79
  $g .= "S2MEMBER_CURRENT_USER_DOWNLOADS_ALLOWED_IS_UNLIMITED = " . ((S2MEMBER_CURRENT_USER_DOWNLOADS_ALLOWED_IS_UNLIMITED) ? "true" : "false") . ",";
@@ -87,6 +89,7 @@ function ws_plugin__s2member_js_w_globals ()
87
  $g .= "S2MEMBER_CURRENT_USER_PROFILE_MODIFICATION_PAGE_URL = '" . preg_replace ("/'/", "\'", S2MEMBER_CURRENT_USER_PROFILE_MODIFICATION_PAGE_URL) . "',";
88
  $g .= "S2MEMBER_FILE_DOWNLOAD_LIMIT_EXCEEDED_PAGE_URL = '" . preg_replace ("/'/", "\'", S2MEMBER_FILE_DOWNLOAD_LIMIT_EXCEEDED_PAGE_URL) . "',";
89
  $g .= "S2MEMBER_MEMBERSHIP_OPTIONS_PAGE_URL = '" . preg_replace ("/'/", "\'", S2MEMBER_MEMBERSHIP_OPTIONS_PAGE_URL) . "',";
 
90
  $g .= "S2MEMBER_LOGOUT_PAGE_URL = '" . preg_replace ("/'/", "\'", S2MEMBER_LOGOUT_PAGE_URL) . "',";
91
  $g .= "S2MEMBER_LOGIN_PAGE_URL = '" . preg_replace ("/'/", "\'", S2MEMBER_LOGIN_PAGE_URL) . "',";
92
  /**/
@@ -113,6 +116,9 @@ function ws_plugin__s2member_js_w_globals ()
113
  $g .= "S2MEMBER_PAYPAL_ENDPOINT = '" . preg_replace ("/'/", "\'", S2MEMBER_PAYPAL_ENDPOINT) . "',";
114
  $g .= "S2MEMBER_PAYPAL_BUSINESS = '" . preg_replace ("/'/", "\'", S2MEMBER_PAYPAL_BUSINESS) . "',";
115
  /**/
 
 
 
116
  $g = trim ($g, " ,") . ";"; /* Trim & add semicolon. */
117
  $j = file_get_contents (dirname (dirname (__FILE__)) . "/s2member-min.js");
118
  $j = preg_replace ("/('|\")%%globals%%('|\");/", $g, $j);
61
  header ("Pragma: public");
62
  /**/
63
  $g = "var S2MEMBER_CURRENT_USER_IS_LOGGED_IN = " . ((S2MEMBER_CURRENT_USER_IS_LOGGED_IN) ? "true" : "false") . ",";
64
+ $g .= "S2MEMBER_CURRENT_USER_IS_LOGGED_IN_AS_MEMBER = " . ((S2MEMBER_CURRENT_USER_IS_LOGGED_IN_AS_MEMBER) ? "true" : "false") . ",";
65
  $g .= "S2MEMBER_CURRENT_USER_ACCESS_LEVEL = " . S2MEMBER_CURRENT_USER_ACCESS_LEVEL . ",";
66
  $g .= "S2MEMBER_CURRENT_USER_ACCESS_LABEL = '" . preg_replace ("/'/", "\'", S2MEMBER_CURRENT_USER_ACCESS_LABEL) . "',";
67
  $g .= "S2MEMBER_CURRENT_USER_SUBSCR_ID = '" . preg_replace ("/'/", "\'", S2MEMBER_CURRENT_USER_SUBSCR_ID) . "',";
75
  $g .= "S2MEMBER_CURRENT_USER_EMAIL = '" . preg_replace ("/'/", "\'", S2MEMBER_CURRENT_USER_EMAIL) . "',";
76
  $g .= "S2MEMBER_CURRENT_USER_IP = '" . preg_replace ("/'/", "\'", S2MEMBER_CURRENT_USER_IP) . "',";
77
  $g .= "S2MEMBER_CURRENT_USER_ID = " . S2MEMBER_CURRENT_USER_ID . ",";
78
+ $g .= "S2MEMBER_CURRENT_USER_FIELDS = " . S2MEMBER_CURRENT_USER_FIELDS . ",";
79
  /**/
80
  $g .= "S2MEMBER_CURRENT_USER_DOWNLOADS_ALLOWED = " . S2MEMBER_CURRENT_USER_DOWNLOADS_ALLOWED . ",";
81
  $g .= "S2MEMBER_CURRENT_USER_DOWNLOADS_ALLOWED_IS_UNLIMITED = " . ((S2MEMBER_CURRENT_USER_DOWNLOADS_ALLOWED_IS_UNLIMITED) ? "true" : "false") . ",";
89
  $g .= "S2MEMBER_CURRENT_USER_PROFILE_MODIFICATION_PAGE_URL = '" . preg_replace ("/'/", "\'", S2MEMBER_CURRENT_USER_PROFILE_MODIFICATION_PAGE_URL) . "',";
90
  $g .= "S2MEMBER_FILE_DOWNLOAD_LIMIT_EXCEEDED_PAGE_URL = '" . preg_replace ("/'/", "\'", S2MEMBER_FILE_DOWNLOAD_LIMIT_EXCEEDED_PAGE_URL) . "',";
91
  $g .= "S2MEMBER_MEMBERSHIP_OPTIONS_PAGE_URL = '" . preg_replace ("/'/", "\'", S2MEMBER_MEMBERSHIP_OPTIONS_PAGE_URL) . "',";
92
+ $g .= "S2MEMBER_LOGIN_WELCOME_PAGE_URL = '" . preg_replace ("/'/", "\'", S2MEMBER_LOGIN_WELCOME_PAGE_URL) . "',";
93
  $g .= "S2MEMBER_LOGOUT_PAGE_URL = '" . preg_replace ("/'/", "\'", S2MEMBER_LOGOUT_PAGE_URL) . "',";
94
  $g .= "S2MEMBER_LOGIN_PAGE_URL = '" . preg_replace ("/'/", "\'", S2MEMBER_LOGIN_PAGE_URL) . "',";
95
  /**/
116
  $g .= "S2MEMBER_PAYPAL_ENDPOINT = '" . preg_replace ("/'/", "\'", S2MEMBER_PAYPAL_ENDPOINT) . "',";
117
  $g .= "S2MEMBER_PAYPAL_BUSINESS = '" . preg_replace ("/'/", "\'", S2MEMBER_PAYPAL_BUSINESS) . "',";
118
  /**/
119
+ $g .= "S2MEMBER_CURRENT_USER_VALUE_FOR_PP_ON0 = '" . preg_replace ("/'/", "\'", S2MEMBER_CURRENT_USER_VALUE_FOR_PP_ON0) . "',";
120
+ $g .= "S2MEMBER_CURRENT_USER_VALUE_FOR_PP_OS0 = '" . preg_replace ("/'/", "\'", S2MEMBER_CURRENT_USER_VALUE_FOR_PP_OS0) . "',";
121
+ /**/
122
  $g = trim ($g, " ,") . ";"; /* Trim & add semicolon. */
123
  $j = file_get_contents (dirname (dirname (__FILE__)) . "/s2member-min.js");
124
  $j = preg_replace ("/('|\")%%globals%%('|\");/", $g, $j);
includes/functions/menu-pages.inc.php CHANGED
@@ -59,16 +59,17 @@ function ws_plugin__s2member_add_admin_options ()
59
  {
60
  add_filter ("plugin_action_links", "_ws_plugin__s2member_add_settings_link", 10, 2);
61
  /**/
62
- add_menu_page ("s2Member Options", "s2Member", "edit_plugins", "ws-plugin--s2member-options", "ws_plugin__s2member_options_page");
63
- add_submenu_page ("ws-plugin--s2member-options", "s2Member General Options", "General Options", "edit_plugins", "ws-plugin--s2member-options", "ws_plugin__s2member_options_page");
64
- add_submenu_page ("ws-plugin--s2member-options", "s2Member PayPal Options", "PayPal® Options", "edit_plugins", "ws-plugin--s2member-paypal-ops", "ws_plugin__s2member_paypal_ops_page");
65
- add_submenu_page ("ws-plugin--s2member-options", "s2Member PayPal® Buttons", "PayPal® Buttons", "edit_plugins", "ws-plugin--s2member-buttons", "ws_plugin__s2member_buttons_page");
66
- add_submenu_page ("ws-plugin--s2member-options", "s2Member File Download Options", "Download Options", "edit_plugins", "ws-plugin--s2member-down-ops", "ws_plugin__s2member_down_ops_page");
67
- add_submenu_page ("ws-plugin--s2member-options", "s2Member API / Tracking", "API / Tracking", "edit_plugins", "ws-plugin--s2member-trk-ops", "ws_plugin__s2member_trk_ops_page");
68
- add_submenu_page ("ws-plugin--s2member-options", "s2Member API / Notifications", "API / Notifications", "edit_plugins", "ws-plugin--s2member-api-ops", "ws_plugin__s2member_api_ops_page");
69
- add_submenu_page ("ws-plugin--s2member-options", "s2Member API / Scripting", "API / Scripting", "edit_plugins", "ws-plugin--s2member-scripting", "ws_plugin__s2member_scripting_page");
70
- add_submenu_page ("ws-plugin--s2member-options", "s2Member Flow Of Events", "Flow Of Events", "edit_plugins", "ws-plugin--s2member-events", "ws_plugin__s2member_events_page");
71
- add_submenu_page ("ws-plugin--s2member-options", "s2Member Information", "s2Member Info", "edit_plugins", "ws-plugin--s2member-info", "ws_plugin__s2member_info_page");
 
72
  /**/
73
  return;
74
  }
@@ -160,6 +161,15 @@ function ws_plugin__s2member_menu_pages_css ()
160
  }
161
  }
162
  /*
 
 
 
 
 
 
 
 
 
163
  Function for building and handling the General Options page.
164
  */
165
  function ws_plugin__s2member_options_page ()
@@ -248,6 +258,17 @@ function ws_plugin__s2member_trk_ops_page ()
248
  return;
249
  }
250
  /*
 
 
 
 
 
 
 
 
 
 
 
251
  Function for building and handling the API Notifications page.
252
  */
253
  function ws_plugin__s2member_api_ops_page ()
@@ -277,15 +298,6 @@ function ws_plugin__s2member_scripting_page ()
277
  return;
278
  }
279
  /*
280
- Function for building the Flow Of Events page.
281
- */
282
- function ws_plugin__s2member_events_page ()
283
- {
284
- include_once dirname (dirname (__FILE__)) . "/menu-pages/events.inc.php";
285
- /**/
286
- return;
287
- }
288
- /*
289
  Function for building the s2Member Info page.
290
  */
291
  function ws_plugin__s2member_info_page ()
59
  {
60
  add_filter ("plugin_action_links", "_ws_plugin__s2member_add_settings_link", 10, 2);
61
  /**/
62
+ add_menu_page ("s2Member Options", "s2Member", "edit_plugins", "ws-plugin--s2member-start", "ws_plugin__s2member_start_page");
63
+ add_submenu_page ("ws-plugin--s2member-start", "s2Member Quick Start Guide", "Quick Start Guide", "edit_plugins", "ws-plugin--s2member-start", "ws_plugin__s2member_start_page");
64
+ add_submenu_page ("ws-plugin--s2member-start", "s2Member General Options", "General Options", "edit_plugins", "ws-plugin--s2member-options", "ws_plugin__s2member_options_page");
65
+ add_submenu_page ("ws-plugin--s2member-start", "s2Member PayPal Options", "PayPal® Options", "edit_plugins", "ws-plugin--s2member-paypal-ops", "ws_plugin__s2member_paypal_ops_page");
66
+ add_submenu_page ("ws-plugin--s2member-start", "s2Member PayPal® Buttons", "PayPal® Buttons", "edit_plugins", "ws-plugin--s2member-buttons", "ws_plugin__s2member_buttons_page");
67
+ add_submenu_page ("ws-plugin--s2member-start", "s2Member File Download Options", "Download Options", "edit_plugins", "ws-plugin--s2member-down-ops", "ws_plugin__s2member_down_ops_page");
68
+ add_submenu_page ("ws-plugin--s2member-start", "s2Member API / Tracking", "API / Tracking", "edit_plugins", "ws-plugin--s2member-trk-ops", "ws_plugin__s2member_trk_ops_page");
69
+ add_submenu_page ("ws-plugin--s2member-start", "s2Member API / List Servers", "API / List Servers", "edit_plugins", "ws-plugin--s2member-els-ops", "ws_plugin__s2member_els_ops_page");
70
+ add_submenu_page ("ws-plugin--s2member-start", "s2Member API / Notifications", "API / Notifications", "edit_plugins", "ws-plugin--s2member-api-ops", "ws_plugin__s2member_api_ops_page");
71
+ add_submenu_page ("ws-plugin--s2member-start", "s2Member API / Scripting", "API / Scripting", "edit_plugins", "ws-plugin--s2member-scripting", "ws_plugin__s2member_scripting_page");
72
+ add_submenu_page ("ws-plugin--s2member-start", "s2Member Information", "s2Member Info", "edit_plugins", "ws-plugin--s2member-info", "ws_plugin__s2member_info_page");
73
  /**/
74
  return;
75
  }
161
  }
162
  }
163
  /*
164
+ Function for building and handling the Quick Start page.
165
+ */
166
+ function ws_plugin__s2member_start_page ()
167
+ {
168
+ include_once dirname (dirname (__FILE__)) . "/menu-pages/start.inc.php";
169
+ /**/
170
+ return;
171
+ }
172
+ /*
173
  Function for building and handling the General Options page.
174
  */
175
  function ws_plugin__s2member_options_page ()
258
  return;
259
  }
260
  /*
261
+ Function for building and handling the API List Server options page.
262
+ */
263
+ function ws_plugin__s2member_els_ops_page ()
264
+ {
265
+ ws_plugin__s2member_update_all_options ();
266
+ /**/
267
+ include_once dirname (dirname (__FILE__)) . "/menu-pages/els-ops.inc.php";
268
+ /**/
269
+ return;
270
+ }
271
+ /*
272
  Function for building and handling the API Notifications page.
273
  */
274
  function ws_plugin__s2member_api_ops_page ()
298
  return;
299
  }
300
  /*
 
 
 
 
 
 
 
 
 
301
  Function for building the s2Member Info page.
302
  */
303
  function ws_plugin__s2member_info_page ()
includes/functions/page-level-access.inc.php CHANGED
@@ -54,6 +54,9 @@ function ws_plugin__s2member_check_page_level_access ()
54
  /**/
55
  else if (in_array ($page_ID, preg_split ("/,/", $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["level4_pages"])) && ws_plugin__s2member_nocache_constants () !== "nill" && (!$current_user || !current_user_can ("access_s2member_level4")) && !ws_plugin__s2member_is_systematic_use_page () && wp_redirect (ws_plugin__s2member_append_query_var (get_page_link ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["membership_options_page"]), "s2member_level_req=4")) !== "nill")
56
  exit;
 
 
 
57
  }
58
  /**/
59
  return;
54
  /**/
55
  else if (in_array ($page_ID, preg_split ("/,/", $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["level4_pages"])) && ws_plugin__s2member_nocache_constants () !== "nill" && (!$current_user || !current_user_can ("access_s2member_level4")) && !ws_plugin__s2member_is_systematic_use_page () && wp_redirect (ws_plugin__s2member_append_query_var (get_page_link ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["membership_options_page"]), "s2member_level_req=4")) !== "nill")
56
  exit;
57
+ /**/
58
+ else if (in_array ($page_ID, preg_split ("/,/", $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["single_pages"])) && ws_plugin__s2member_nocache_constants () !== "nill" && !ws_plugin__s2member_sp_access ($page_ID) && !ws_plugin__s2member_is_systematic_use_page () && wp_redirect (ws_plugin__s2member_append_query_var (get_page_link ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["membership_options_page"]), "s2member_sp_req=" . urlencode ($page_ID))) !== "nill")
59
+ exit;
60
  }
61
  /**/
62
  return;
includes/functions/paypal-notify.inc.php CHANGED
@@ -31,14 +31,73 @@ function ws_plugin__s2member_paypal_notify ()
31
  { /* The business address validation was removed from this routine, because PayPal® always fills that with the primary
32
  email address. In cases where an alternate PayPal® address is being paid, validation is not possible. */
33
  $paypal["s2member_log"][] = "s2Member originating domain ( _SERVER[HTTP_HOST] ) validated.";
34
- /**/
35
- if (preg_match ("/^(web_accept|subscr_signup)$/i", $paypal["txn_type"]) && $paypal["payer_email"] && ($paypal["subscr_id"] || ($paypal["subscr_id"] = $paypal["txn_id"])) && preg_match ("/^[1-4]$/", $paypal["item_number"]))
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
36
  {
37
  $paypal["s2member_log"][] = "s2Member txn_type identified as (web_accept|subscr_signup).";
38
  /**/
 
 
 
 
39
  if (preg_match ("/(updat|upgrad)/i", $paypal["option_name1"]) && $paypal["option_selection1"]) /* This is an advanced way to handle subscription update modifications. */
40
  /* This advanced method is required whenever a subscription that is already completed, or was never setup to recur in the first place needs to be modified. PayPal will not allow the
41
- modify=2 parameter to be used in those scenarios, because technically there is nothing to update. The only thing that actually needs to be updated is their existing account. */
42
  {
43
  $paypal["s2member_log"][] = "s2Member txn_type identified as (web_accept|subscr_signup) w/ update vars.";
44
  /**/
@@ -49,112 +108,79 @@ function ws_plugin__s2member_paypal_notify ()
49
  if ($user_id = $q->user_id) /* Got it! */
50
  {
51
  $user = new WP_User ($user_id);
52
- $user->set_role ("s2member_level" . $paypal["item_number"]);
53
  update_usermeta ($user_id, "s2member_subscr_id", $paypal["subscr_id"]);
54
  update_usermeta ($user_id, "s2member_custom", $paypal["custom"]);
 
 
 
 
 
 
 
 
 
55
  delete_usermeta ($user_id, "s2member_file_download_access_arc");
56
  delete_usermeta ($user_id, "s2member_file_download_access_log");
57
  /**/
58
- $paypal["s2member_log"][] = "s2Member level updated w/ advanced update routines.";
59
  }
60
  else
61
  {
62
- $paypal["s2member_log"][] = "Unable to get user_id from the DB.";
63
  }
64
  }
65
  else
66
  {
67
- $paypal["s2member_log"][] = "Unable to find subscription/subscriber in the DB.";
68
  }
69
  }
 
 
 
70
  else /* Else this is a normal subscription signup, we are not updating anything for a past subscription. */
71
  {
72
  $paypal["s2member_log"][] = "s2Member txn_type identified as (web_accept|subscr_signup) w/o update vars.";
73
  /**/
74
- if ($subscr_id_custom_item_number_xencrypted = ws_plugin__s2member_xencrypt ("subscr_id_custom_item_number:.:|:.:" . $paypal["subscr_id"] . ":.:|:.:" . $paypal["custom"] . ":.:|:.:" . $paypal["item_number"]))
75
  {
76
- if ($tinyurl = @file_get_contents ("http://tinyurl.com/api-create.php?url=" . rawurlencode (get_bloginfo ("url") . "/?s2member_paypal_register=" . urlencode ($subscr_id_custom_item_number_xencrypted))))
77
- {
78
- if (is_array ($cv = preg_split ("/\|/", $paypal["custom"]))) /* Values passed through the "custom" field to PayPal. */
79
- {
80
- $sbj = preg_replace ("/%%registration_url%%/i", $tinyurl, $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["signup_email_subject"]);
81
- $msg = preg_replace ("/%%registration_url%%/i", $tinyurl, $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["signup_email_message"]);
82
- /**/
83
- if (preg_match ("/^web_accept$/i", $paypal["txn_type"]))
84
- {
85
- $paypal["period3"] = "1 L"; /* 1 Lifetime. */
86
- $paypal["amount3"] = $paypal["payment_gross"];
87
- }
88
- /**/
89
- $initial_term = $paypal["period1"] ? $paypal["period1"] : "0 D"; /* Do not allow the initial period to be empty. */
90
- $initial = (isset ($paypal["amount1"]) && preg_match ("/^[1-9]/", $paypal["period1"])) ? $paypal["amount1"] : $paypal["amount3"];
91
- $regular = $paypal["amount3"]; /* This is the regular payment amount that is charged to the customer. Always required by PayPal. */
92
- $recurring = ($paypal["recurring"]) ? $paypal["amount3"] : "0"; /* If non-recurring, this should be zero, otherwise regular. */
93
- /* The initial amount will only be $0 if a trial was offered. If no trial was offered, they were charged a regular rate. */
94
- if (($sbj = preg_replace ("/%%cv([0-9]+)%%/ei", 'urlencode(trim($cv[$1]))', $sbj)) && ($sbj = preg_replace ("/%%subscr_id%%/i", urlencode ($paypal["subscr_id"]), $sbj)))
95
- if (($sbj = preg_replace ("/%%initial%%/i", urlencode ($initial), $sbj)) && ($sbj = preg_replace ("/%%recurring%%/i", urlencode ($recurring), $sbj))) /* Adv calculations. */
96
- if (($sbj = preg_replace ("/%%regular%%/i", urlencode ($regular), $sbj))) /* This is provided mostly for rare cases where a trial is offered, and there is NO recurrence. */
97
- /* In cases where there is a free trial offered, and no recurring charges either ( could happen ), both initial & recurring are 0. So regular should be reported then. */
98
- if (($sbj = preg_replace ("/%%initial_term%%/i", urlencode ($initial_term), $sbj)) && ($sbj = preg_replace ("/%%regular_term%%/i", urlencode ($paypal["period3"]), $sbj)))
99
- if (($sbj = preg_replace ("/%%item_number%%/i", urlencode ($paypal["item_number"]), $sbj)) && ($sbj = preg_replace ("/%%item_name%%/i", urlencode ($paypal["item_name"]), $sbj)))
100
- if (($sbj = preg_replace ("/%%first_name%%/i", urlencode ($paypal["first_name"]), $sbj)) && ($sbj = preg_replace ("/%%last_name%%/i", urlencode ($paypal["last_name"]), $sbj)))
101
- if (($sbj = preg_replace ("/%%full_name%%/i", urlencode (trim ($paypal["first_name"] . " " . $paypal["last_name"])), $sbj)))
102
- if (($sbj = preg_replace ("/%%payer_email%%/i", urlencode ($paypal["payer_email"]), $sbj)) && ($sbj = trim ($sbj)))
103
- if (($msg = preg_replace ("/%%cv([0-9]+)%%/ei", 'urlencode(trim($cv[$1]))', $msg)) && ($msg = preg_replace ("/%%subscr_id%%/i", urlencode ($paypal["subscr_id"]), $msg)))
104
- if (($msg = preg_replace ("/%%initial%%/i", urlencode ($initial), $msg)) && ($msg = preg_replace ("/%%recurring%%/i", urlencode ($recurring), $msg))) /* Adv calculations. */
105
- if (($msg = preg_replace ("/%%regular%%/i", urlencode ($regular), $msg))) /* This is provided mostly for rare cases where a trial is offered, and there is NO recurrence. */
106
- /* In cases where there is a free trial offered, and no recurring charges either ( could happen ), both initial & recurring are 0. So regular should be reported then. */
107
- if (($msg = preg_replace ("/%%initial_term%%/i", urlencode ($initial_term), $msg)) && ($msg = preg_replace ("/%%regular_term%%/i", urlencode ($paypal["period3"]), $msg)))
108
- if (($msg = preg_replace ("/%%item_number%%/i", urlencode ($paypal["item_number"]), $msg)) && ($msg = preg_replace ("/%%item_name%%/i", urlencode ($paypal["item_name"]), $msg)))
109
- if (($msg = preg_replace ("/%%first_name%%/i", urlencode ($paypal["first_name"]), $msg)) && ($msg = preg_replace ("/%%last_name%%/i", urlencode ($paypal["last_name"]), $msg)))
110
- if (($msg = preg_replace ("/%%full_name%%/i", urlencode (trim ($paypal["first_name"] . " " . $paypal["last_name"])), $msg)))
111
- if (($msg = preg_replace ("/%%payer_email%%/i", urlencode ($paypal["payer_email"]), $msg)) && ($msg = trim ($msg)))
112
- @mail ($paypal["payer_email"], $sbj, $msg, "From: \"" . preg_replace ('/"/', "'", $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["reg_email_from_name"]) . "\" <" . $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["reg_email_from_email"] . ">\r\nContent-Type: text/plain; charset=utf-8", "-f " . $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["reg_email_from_email"]);
113
- /**/
114
- $paypal["s2member_log"][] = "Email sent after signup, ( w/tiny URL ) to assist customer w/ registration.";
115
- }
116
- }
117
- else if ($longurl = get_bloginfo ("url") . "/?s2member_paypal_register=" . urlencode ($subscr_id_custom_item_number_xencrypted))
118
  {
119
- if (is_array ($cv = preg_split ("/\|/", $paypal["custom"]))) /* Values passed through the "custom" field to PayPal. */
120
- {
121
- $sbj = preg_replace ("/%%registration_url%%/i", $longurl, $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["signup_email_subject"]);
122
- $msg = preg_replace ("/%%registration_url%%/i", $longurl, $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["signup_email_message"]);
123
- /**/
124
- if (preg_match ("/^web_accept$/i", $paypal["txn_type"]))
125
- {
126
- $paypal["period3"] = "1 L"; /* 1 Lifetime. */
127
- $paypal["amount3"] = $paypal["payment_gross"];
128
- }
129
- /**/
130
- $initial_term = $paypal["period1"] ? $paypal["period1"] : "0 D"; /* Do not allow the initial period to be empty. */
131
- $initial = (isset ($paypal["amount1"]) && preg_match ("/^[1-9]/", $paypal["period1"])) ? $paypal["amount1"] : $paypal["amount3"];
132
- $regular = $paypal["amount3"]; /* This is the regular payment amount that is charged to the customer. Always required by PayPal. */
133
- $recurring = ($paypal["recurring"]) ? $paypal["amount3"] : "0"; /* If non-recurring, this should be zero, otherwise regular. */
134
- /* The initial amount will only be $0 if a trial was offered. If no trial was offered, they were charged a regular rate. */
135
- if (($sbj = preg_replace ("/%%cv([0-9]+)%%/ei", 'urlencode(trim($cv[$1]))', $sbj)) && ($sbj = preg_replace ("/%%subscr_id%%/i", urlencode ($paypal["subscr_id"]), $sbj)))
136
- if (($sbj = preg_replace ("/%%initial%%/i", urlencode ($initial), $sbj)) && ($sbj = preg_replace ("/%%recurring%%/i", urlencode ($recurring), $sbj))) /* Adv calculations. */
137
- if (($sbj = preg_replace ("/%%regular%%/i", urlencode ($regular), $sbj))) /* This is provided mostly for rare cases where a trial is offered, and there is NO recurrence. */
138
- /* In cases where there is a free trial offered, and no recurring charges either ( could happen ), both initial & recurring are 0. So regular should be reported then. */
139
- if (($sbj = preg_replace ("/%%initial_term%%/i", urlencode ($initial_term), $sbj)) && ($sbj = preg_replace ("/%%regular_term%%/i", urlencode ($paypal["period3"]), $sbj)))
140
- if (($sbj = preg_replace ("/%%item_number%%/i", urlencode ($paypal["item_number"]), $sbj)) && ($sbj = preg_replace ("/%%item_name%%/i", urlencode ($paypal["item_name"]), $sbj)))
141
- if (($sbj = preg_replace ("/%%first_name%%/i", urlencode ($paypal["first_name"]), $sbj)) && ($sbj = preg_replace ("/%%last_name%%/i", urlencode ($paypal["last_name"]), $sbj)))
142
- if (($sbj = preg_replace ("/%%full_name%%/i", urlencode (trim ($paypal["first_name"] . " " . $paypal["last_name"])), $sbj)))
143
- if (($sbj = preg_replace ("/%%payer_email%%/i", urlencode ($paypal["payer_email"]), $sbj)) && ($sbj = trim ($sbj)))
144
- if (($msg = preg_replace ("/%%cv([0-9]+)%%/ei", 'urlencode(trim($cv[$1]))', $msg)) && ($msg = preg_replace ("/%%subscr_id%%/i", urlencode ($paypal["subscr_id"]), $msg)))
145
- if (($msg = preg_replace ("/%%initial%%/i", urlencode ($initial), $msg)) && ($msg = preg_replace ("/%%recurring%%/i", urlencode ($recurring), $msg))) /* Adv calculations. */
146
- if (($msg = preg_replace ("/%%regular%%/i", urlencode ($regular), $msg))) /* This is provided mostly for rare cases where a trial is offered, and there is NO recurrence. */
147
- /* In cases where there is a free trial offered, and no recurring charges either ( could happen ), both initial & recurring are 0. So regular should be reported then. */
148
- if (($msg = preg_replace ("/%%initial_term%%/i", urlencode ($initial_term), $msg)) && ($msg = preg_replace ("/%%regular_term%%/i", urlencode ($paypal["period3"]), $msg)))
149
- if (($msg = preg_replace ("/%%item_number%%/i", urlencode ($paypal["item_number"]), $msg)) && ($msg = preg_replace ("/%%item_name%%/i", urlencode ($paypal["item_name"]), $msg)))
150
- if (($msg = preg_replace ("/%%first_name%%/i", urlencode ($paypal["first_name"]), $msg)) && ($msg = preg_replace ("/%%last_name%%/i", urlencode ($paypal["last_name"]), $msg)))
151
- if (($msg = preg_replace ("/%%full_name%%/i", urlencode (trim ($paypal["first_name"] . " " . $paypal["last_name"])), $msg)))
152
- if (($msg = preg_replace ("/%%payer_email%%/i", urlencode ($paypal["payer_email"]), $msg)) && ($msg = trim ($msg)))
153
- @mail ($paypal["payer_email"], $sbj, $msg, "From: \"" . preg_replace ('/"/', "'", $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["reg_email_from_name"]) . "\" <" . $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["reg_email_from_email"] . ">\r\nContent-Type: text/plain; charset=utf-8", "-f " . $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["reg_email_from_email"]);
154
- /**/
155
- $paypal["s2member_log"][] = "Email sent after signup, ( w/long URL ) to assist customer w/ registration.";
156
- }
157
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
158
  }
159
  }
160
  /**/
@@ -163,90 +189,155 @@ function ws_plugin__s2member_paypal_notify ()
163
  if (preg_match ("/^web_accept$/i", $paypal["txn_type"]))
164
  {
165
  $paypal["period3"] = "1 L"; /* 1 Lifetime. */
166
- $paypal["amount3"] = $paypal["payment_gross"];
167
  }
168
  /**/
169
- $initial_term = $paypal["period1"] ? $paypal["period1"] : "0 D"; /* Do not allow the initial period to be empty. */
170
- $initial = (isset ($paypal["amount1"]) && preg_match ("/^[1-9]/", $paypal["period1"])) ? $paypal["amount1"] : $paypal["amount3"];
171
- $regular = $paypal["amount3"]; /* This is the regular payment amount that is charged to the customer. Always required by PayPal. */
172
- $recurring = ($paypal["recurring"]) ? $paypal["amount3"] : "0"; /* If non-recurring, this should be zero, otherwise regular. */
173
  /* The initial amount will only be $0 if a trial was offered. If no trial was offered, they were charged a regular rate. */
 
174
  foreach (preg_split ("/[\r\n\t]+/", $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["signup_notification_urls"]) as $url)
 
175
  if (($url = preg_replace ("/%%cv([0-9]+)%%/ei", 'urlencode(trim($cv[$1]))', $url)) && ($url = preg_replace ("/%%subscr_id%%/i", urlencode ($paypal["subscr_id"]), $url)))
176
- if (($url = preg_replace ("/%%initial%%/i", urlencode ($initial), $url)) && ($url = preg_replace ("/%%recurring%%/i", urlencode ($recurring), $url))) /* Adv calculations. */
177
- if (($url = preg_replace ("/%%regular%%/i", urlencode ($regular), $url))) /* This is provided mostly for rare cases where a trial is offered, and there is NO recurrence. */
178
- /* In cases where there is a free trial offered, and no recurring charges either ( could happen ), both initial & recurring are 0. So regular should be reported then. */
179
- if (($url = preg_replace ("/%%initial_term%%/i", urlencode ($initial_term), $url)) && ($url = preg_replace ("/%%regular_term%%/i", urlencode ($paypal["period3"]), $url)))
180
- if (($url = preg_replace ("/%%item_number%%/i", urlencode ($paypal["item_number"]), $url)) && ($url = preg_replace ("/%%item_name%%/i", urlencode ($paypal["item_name"]), $url)))
181
- if (($url = preg_replace ("/%%first_name%%/i", urlencode ($paypal["first_name"]), $url)) && ($url = preg_replace ("/%%last_name%%/i", urlencode ($paypal["last_name"]), $url)))
182
- if (($url = preg_replace ("/%%full_name%%/i", urlencode (trim ($paypal["first_name"] . " " . $paypal["last_name"])), $url)))
183
- if (($url = preg_replace ("/%%payer_email%%/i", urlencode ($paypal["payer_email"]), $url)))
184
- if (($url = trim ($url))) /* Make sure it is not empty now. */
185
- ws_plugin__s2member_curlpsr ($url, "s2member=1");
186
  /**/
187
- $paypal["s2member_log"][] = "Signup notification URLs have been processed.";
188
  }
189
  }
190
- else if (preg_match ("/^subscr_modify$/i", $paypal["txn_type"]) && $paypal["subscr_id"] && preg_match ("/^[1-4]$/", $paypal["item_number"]))
 
 
 
191
  {
192
  $paypal["s2member_log"][] = "s2Member txn_type identified as subscr_modify.";
193
  /**/
 
 
194
  if ($q = $wpdb->get_row ("SELECT `user_id` FROM `" . $wpdb->usermeta . "` WHERE `meta_key` = 's2member_subscr_id' AND `meta_value` = '" . $wpdb->escape ($paypal["subscr_id"]) . "' LIMIT 1"))
195
  {
196
  if ($user_id = $q->user_id) /* Got it! */
197
  {
198
  $user = new WP_User ($user_id);
199
- $user->set_role ("s2member_level" . $paypal["item_number"]);
 
200
  update_usermeta ($user_id, "s2member_custom", $paypal["custom"]);
201
  /**/
202
- $paypal["s2member_log"][] = "s2Member level updated on subscription modification.";
 
 
 
 
 
 
 
 
 
 
 
203
  }
204
  else
205
  {
206
- $paypal["s2member_log"][] = "Unable to get user_id from the DB.";
207
  }
208
  }
209
  else
210
  {
211
- $paypal["s2member_log"][] = "Unable to find subscription in the DB.";
212
  }
213
  }
214
- else if (preg_match ("/^subscr_payment$/i", $paypal["txn_type"]) && $paypal["payer_email"] && $paypal["subscr_id"] && preg_match ("/^[1-4]$/", $paypal["item_number"]) && $paypal["txn_id"] && $paypal["payment_gross"])
 
 
 
215
  {
216
  $paypal["s2member_log"][] = "s2Member txn_type identified as subscr_payment.";
217
  /**/
 
 
218
  if ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["payment_notification_urls"] && is_array ($cv = preg_split ("/\|/", $paypal["custom"])))
219
  {
220
  foreach (preg_split ("/[\r\n\t]+/", $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["payment_notification_urls"]) as $url)
 
221
  if (($url = preg_replace ("/%%cv([0-9]+)%%/ei", 'urlencode(trim($cv[$1]))', $url)) && ($url = preg_replace ("/%%subscr_id%%/i", urlencode ($paypal["subscr_id"]), $url)))
222
- if (($url = preg_replace ("/%%amount%%/i", urlencode ($paypal["payment_gross"]), $url)) && ($url = preg_replace ("/%%txn_id%%/i", urlencode ($paypal["txn_id"]), $url)))
223
  if (($url = preg_replace ("/%%item_number%%/i", urlencode ($paypal["item_number"]), $url)) && ($url = preg_replace ("/%%item_name%%/i", urlencode ($paypal["item_name"]), $url)))
224
  if (($url = preg_replace ("/%%first_name%%/i", urlencode ($paypal["first_name"]), $url)) && ($url = preg_replace ("/%%last_name%%/i", urlencode ($paypal["last_name"]), $url)))
225
  if (($url = preg_replace ("/%%full_name%%/i", urlencode (trim ($paypal["first_name"] . " " . $paypal["last_name"])), $url)))
226
  if (($url = preg_replace ("/%%payer_email%%/i", urlencode ($paypal["payer_email"]), $url)))
227
- if (($url = trim ($url))) /* Make sure it is not empty now. */
 
228
  ws_plugin__s2member_curlpsr ($url, "s2member=1");
229
  /**/
230
- $paypal["s2member_log"][] = "Payment notification URLs have been processed.";
231
  }
232
  }
233
- else if ((preg_match ("/^subscr_eot$/i", $paypal["txn_type"]) || preg_match ("/^(refunded|reversed)$/i", $paypal["payment_status"])) && ($paypal["subscr_id"] || ($paypal["subscr_id"] = $paypal["parent_txn_id"])) && preg_match ("/^[1-4]$/", $paypal["item_number"]))
 
 
 
234
  {
235
  $paypal["s2member_log"][] = "s2Member txn_type identified as subscr_eot - or - payment_status (refunded|reversed).";
236
  /**/
 
 
237
  if ($q = $wpdb->get_row ("SELECT `user_id` FROM `" . $wpdb->usermeta . "` WHERE `meta_key` = 's2member_subscr_id' AND `meta_value` = '" . $wpdb->escape ($paypal["subscr_id"]) . "' LIMIT 1"))
238
  {
239
- if ($user_id = $q->user_id) /* Delete the user. Note that `ws_plugin__s2member_handle_user_deletions()` is fired too; it handles the `eot_del_notification_urls`. */
240
  {
241
- wp_delete_user ($user_id); /* This triggers `ws_plugin__s2member_handle_user_deletions()` */
242
- /**/
243
- $paypal["s2member_log"][] = "User account automatically deleted from the system.";
244
- /**/
245
- $paypal["s2member_log"][] = "EOT/Deletion notification URLs have been processed.";
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
246
  }
247
  else
248
  {
249
- $paypal["s2member_log"][] = "Unable to get user_id from the DB.";
250
  }
251
  /**/
252
  if (!preg_match ("/^subscr_eot$/i", $paypal["txn_type"]) && preg_match ("/^(refunded|reversed)$/i", $paypal["payment_status"]) && $paypal["parent_txn_id"])
@@ -254,37 +345,39 @@ function ws_plugin__s2member_paypal_notify ()
254
  if ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["ref_rev_notification_urls"] && is_array ($cv = preg_split ("/\|/", $paypal["custom"])))
255
  {
256
  foreach (preg_split ("/[\r\n\t]+/", $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["ref_rev_notification_urls"]) as $url)
 
257
  if (($url = preg_replace ("/%%cv([0-9]+)%%/ei", 'urlencode(trim($cv[$1]))', $url)) && ($url = preg_replace ("/%%subscr_id%%/i", urlencode ($paypal["subscr_id"]), $url)))
258
- if (($url = preg_replace ("/%%-amount%%/i", urlencode ($paypal["payment_gross"]), $url)) && ($url = preg_replace ("/%%parent_txn_id%%/i", urlencode ($paypal["parent_txn_id"]), $url)))
259
  if (($url = preg_replace ("/%%item_number%%/i", urlencode ($paypal["item_number"]), $url)) && ($url = preg_replace ("/%%item_name%%/i", urlencode ($paypal["item_name"]), $url)))
260
  if (($url = preg_replace ("/%%first_name%%/i", urlencode ($paypal["first_name"]), $url)) && ($url = preg_replace ("/%%last_name%%/i", urlencode ($paypal["last_name"]), $url)))
261
  if (($url = preg_replace ("/%%full_name%%/i", urlencode (trim ($paypal["first_name"] . " " . $paypal["last_name"])), $url)))
262
  if (($url = preg_replace ("/%%payer_email%%/i", urlencode ($paypal["payer_email"]), $url)))
263
- if (($url = trim ($url))) /* Make sure it is not empty now. */
 
264
  ws_plugin__s2member_curlpsr ($url, "s2member=1");
265
  /**/
266
- $paypal["s2member_log"][] = "Refund/Reversal notification URLs have been processed.";
267
  }
268
  }
269
  }
270
  else
271
  {
272
- $paypal["s2member_log"][] = "Unable to find subscription in the DB.";
273
  }
274
  }
275
  else
276
  {
277
- $paypal["s2member_log"][] = "The txn_type does not require any action on the part of s2Member.";
278
  }
279
  }
280
  else
281
  {
282
- $paypal["s2member_log"][] = "Unable to verify _SERVER[HTTP_HOST].";
283
  }
284
  }
285
  else
286
  {
287
- $paypal["s2member_log"][] = "Unable to verify POST vars.";
288
  }
289
  /**/
290
  if ($_GET["s2member_paypal_proxy"]) /* For proxy identification. */
31
  { /* The business address validation was removed from this routine, because PayPal® always fills that with the primary
32
  email address. In cases where an alternate PayPal® address is being paid, validation is not possible. */
33
  $paypal["s2member_log"][] = "s2Member originating domain ( _SERVER[HTTP_HOST] ) validated.";
34
+ /*
35
+ Single-Page Access.
36
+ */
37
+ if (preg_match ("/^web_accept$/i", $paypal["txn_type"]) && $paypal["payer_email"] && $paypal["txn_id"] && preg_match ("/^sp\:[0-9]+$/", $paypal["item_number"]))
38
+ {
39
+ $paypal["s2member_log"][] = "s2Member txn_type identified as (web_accept) for Single-Page access.";
40
+ /**/
41
+ list (, $paypal["page"]) = preg_split ("/\:/", $paypal["item_number"], 2);
42
+ /**/
43
+ if (($sp_access_url = ws_plugin__s2member_sp_access_link_gen ($paypal["page"])) && is_array ($cv = preg_split ("/\|/", $paypal["custom"])))
44
+ {
45
+ $sbj = preg_replace ("/%%sp_access_url%%/i", $sp_access_url, $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["single_page_email_subject"]);
46
+ $msg = preg_replace ("/%%sp_access_url%%/i", $sp_access_url, $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["single_page_email_message"]);
47
+ /**/
48
+ if (($sbj = preg_replace ("/%%cv([0-9]+)%%/ei", 'trim($cv[$1])', $sbj)) && ($sbj = preg_replace ("/%%txn_id%%/i", $paypal["txn_id"], $sbj)))
49
+ if (($sbj = preg_replace ("/%%amount%%/i", $paypal["mc_gross"], $sbj))) /* Full amount of the payment, before fee is subtracted. */
50
+ if (($sbj = preg_replace ("/%%item_number%%/i", $paypal["item_number"], $sbj)) && ($sbj = preg_replace ("/%%item_name%%/i", $paypal["item_name"], $sbj)))
51
+ if (($sbj = preg_replace ("/%%first_name%%/i", $paypal["first_name"], $sbj)) && ($sbj = preg_replace ("/%%last_name%%/i", $paypal["last_name"], $sbj)))
52
+ if (($sbj = preg_replace ("/%%full_name%%/i", trim ($paypal["first_name"] . " " . $paypal["last_name"]), $sbj)))
53
+ if (($sbj = preg_replace ("/%%payer_email%%/i", $paypal["payer_email"], $sbj)))
54
+ /**/
55
+ if (($msg = preg_replace ("/%%cv([0-9]+)%%/ei", 'trim($cv[$1])', $msg)) && ($msg = preg_replace ("/%%txn_id%%/i", $paypal["txn_id"], $msg)))
56
+ if (($msg = preg_replace ("/%%amount%%/i", $paypal["mc_gross"], $msg))) /* Full amount of the payment, before fee is subtracted. */
57
+ if (($msg = preg_replace ("/%%item_number%%/i", $paypal["item_number"], $msg)) && ($msg = preg_replace ("/%%item_name%%/i", $paypal["item_name"], $msg)))
58
+ if (($msg = preg_replace ("/%%first_name%%/i", $paypal["first_name"], $msg)) && ($msg = preg_replace ("/%%last_name%%/i", $paypal["last_name"], $msg)))
59
+ if (($msg = preg_replace ("/%%full_name%%/i", trim ($paypal["first_name"] . " " . $paypal["last_name"]), $msg)))
60
+ if (($msg = preg_replace ("/%%payer_email%%/i", $paypal["payer_email"], $msg)))
61
+ /**/
62
+ if (($sbj = trim ($sbj)) && ($msg = trim ($msg))) /* Make sure they are not empty. */
63
+ {
64
+ @mail ($paypal["payer_email"], $sbj, $msg, "From: \"" . preg_replace ('/"/', "'", $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["reg_email_from_name"]) . "\" <" . $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["reg_email_from_email"] . ">\r\nContent-Type: text/plain; charset=utf-8", "-f " . $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["reg_email_from_email"]);
65
+ /**/
66
+ $paypal["s2member_log"][] = "Email sent after purchase, with a URL that provides the Customer with Single-Page Access.";
67
+ }
68
+ /**/
69
+ if ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["sp_notification_urls"])
70
+ {
71
+ foreach (preg_split ("/[\r\n\t]+/", $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["sp_notification_urls"]) as $url)
72
+ /**/
73
+ if (($url = preg_replace ("/%%cv([0-9]+)%%/ei", 'urlencode(trim($cv[$1]))', $url)) && ($url = preg_replace ("/%%sp_access_url%%/i", rawurlencode ($sp_access_url), $url)))
74
+ if (($url = preg_replace ("/%%amount%%/i", urlencode ($paypal["mc_gross"]), $url)) && ($url = preg_replace ("/%%txn_id%%/i", urlencode ($paypal["txn_id"]), $url)))
75
+ if (($url = preg_replace ("/%%item_number%%/i", urlencode ($paypal["item_number"]), $url)) && ($url = preg_replace ("/%%item_name%%/i", urlencode ($paypal["item_name"]), $url)))
76
+ if (($url = preg_replace ("/%%first_name%%/i", urlencode ($paypal["first_name"]), $url)) && ($url = preg_replace ("/%%last_name%%/i", urlencode ($paypal["last_name"]), $url)))
77
+ if (($url = preg_replace ("/%%full_name%%/i", urlencode (trim ($paypal["first_name"] . " " . $paypal["last_name"])), $url)))
78
+ if (($url = preg_replace ("/%%payer_email%%/i", urlencode ($paypal["payer_email"]), $url)))
79
+ /**/
80
+ if (($url = trim ($url))) /* Make sure it is not empty. */
81
+ ws_plugin__s2member_curlpsr ($url, "s2member=1");
82
+ /**/
83
+ $paypal["s2member_log"][] = "Payment Notification URLs have been processed.";
84
+ }
85
+ }
86
+ }
87
+ /*
88
+ New subscriptions. Possibly containing advanced updated vars ( option_name1, option_selection1 ); which allow account modifications.
89
+ */
90
+ else if (preg_match ("/^(web_accept|subscr_signup)$/i", $paypal["txn_type"]) && $paypal["payer_email"] && ($paypal["subscr_id"] || ($paypal["subscr_id"] = $paypal["txn_id"])) && preg_match ("/^[1-4](\:|$)/", $paypal["item_number"]))
91
  {
92
  $paypal["s2member_log"][] = "s2Member txn_type identified as (web_accept|subscr_signup).";
93
  /**/
94
+ list ($paypal["level"], $paypal["ccaps"]) = preg_split ("/\:/", $paypal["item_number"], 2);
95
+ /*
96
+ New subscription with advanced update vars ( option_name1, option_selection1 ).
97
+ */
98
  if (preg_match ("/(updat|upgrad)/i", $paypal["option_name1"]) && $paypal["option_selection1"]) /* This is an advanced way to handle subscription update modifications. */
99
  /* This advanced method is required whenever a subscription that is already completed, or was never setup to recur in the first place needs to be modified. PayPal will not allow the
100
+ modify=1|2 parameter to be used in those scenarios, because technically there is nothing to update. The only thing that actually needs to be updated is their existing account. */
101
  {
102
  $paypal["s2member_log"][] = "s2Member txn_type identified as (web_accept|subscr_signup) w/ update vars.";
103
  /**/
108
  if ($user_id = $q->user_id) /* Got it! */
109
  {
110
  $user = new WP_User ($user_id);
111
+ $user->set_role ("s2member_level" . $paypal["level"]);
112
  update_usermeta ($user_id, "s2member_subscr_id", $paypal["subscr_id"]);
113
  update_usermeta ($user_id, "s2member_custom", $paypal["custom"]);
114
+ /**/
115
+ foreach ($user->allcaps as $cap => $cap_enabled)
116
+ if (preg_match ("/^access_s2member_ccap_/", $cap))
117
+ $user->remove_cap ($ccap = $cap);
118
+ /**/
119
+ foreach (preg_split ("/[\r\n\t\s;,]+/", $paypal["ccaps"]) as $ccap)
120
+ if (strlen ($ccap)) /* Don't add empty capabilities. */
121
+ $user->add_cap ("access_s2member_ccap_" . trim (strtolower ($ccap)));
122
+ /**/
123
  delete_usermeta ($user_id, "s2member_file_download_access_arc");
124
  delete_usermeta ($user_id, "s2member_file_download_access_log");
125
  /**/
126
+ $paypal["s2member_log"][] = "s2Member Level/Capabilities updated w/ advanced update routines.";
127
  }
128
  else
129
  {
130
+ $paypal["s2member_log"][] = "Unable to modify subscription. Could not get the existing user_id from the DB. Please check the on0 and os0 variables in your Button Code.";
131
  }
132
  }
133
  else
134
  {
135
+ $paypal["s2member_log"][] = "Unable to modify subscription. Could not find existing subscription in the DB. Please check the on0 and os0 variables in your Button Code.";
136
  }
137
  }
138
+ /*
139
+ New subscription. Normal subscription signup, we are not updating anything for a past subscription.
140
+ */
141
  else /* Else this is a normal subscription signup, we are not updating anything for a past subscription. */
142
  {
143
  $paypal["s2member_log"][] = "s2Member txn_type identified as (web_accept|subscr_signup) w/o update vars.";
144
  /**/
145
+ if ($registration_url = ws_plugin__s2member_register_link_gen ($paypal["subscr_id"], $paypal["custom"], $paypal["item_number"]) && is_array ($cv = preg_split ("/\|/", $paypal["custom"])))
146
  {
147
+ $sbj = preg_replace ("/%%registration_url%%/i", $registration_url, $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["signup_email_subject"]);
148
+ $msg = preg_replace ("/%%registration_url%%/i", $registration_url, $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["signup_email_message"]);
149
+ /**/
150
+ if (preg_match ("/^web_accept$/i", $paypal["txn_type"]))
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
151
  {
152
+ $paypal["period3"] = "1 L"; /* 1 Lifetime. */
153
+ $paypal["mc_amount3"] = $paypal["mc_gross"];
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
154
  }
155
+ /**/
156
+ $initial_term = $paypal["period1"] ? $paypal["period1"] : "0 D"; /* Do not allow the initial period to be empty. Defaults to 0 D. */
157
+ $initial = (isset ($paypal["mc_amount1"]) && preg_match ("/^[1-9]/", $paypal["period1"])) ? $paypal["mc_amount1"] : $paypal["mc_amount3"];
158
+ $regular = $paypal["mc_amount3"]; /* This is the regular payment amount that is charged to the customer. Always required by PayPal. */
159
+ $recurring = ($paypal["recurring"]) ? $paypal["mc_amount3"] : "0"; /* If non-recurring, this should be zero, otherwise regular. */
160
+ /* The initial amount will only be $0 if a trial was offered. If no trial was offered, they were charged a regular rate. */
161
+ /**/
162
+ if (($sbj = preg_replace ("/%%cv([0-9]+)%%/ei", 'trim($cv[$1])', $sbj)) && ($sbj = preg_replace ("/%%subscr_id%%/i", $paypal["subscr_id"], $sbj)))
163
+ if (($sbj = preg_replace ("/%%initial%%/i", $initial, $sbj)) && ($sbj = preg_replace ("/%%recurring%%/i", $recurring, $sbj)) && ($sbj = preg_replace ("/%%regular%%/i", $regular, $sbj)))
164
+ if (($sbj = preg_replace ("/%%initial_term%%/i", $initial_term, $sbj)) && ($sbj = preg_replace ("/%%regular_term%%/i", $paypal["period3"], $sbj)))
165
+ if (($sbj = preg_replace ("/%%item_number%%/i", $paypal["item_number"], $sbj)) && ($sbj = preg_replace ("/%%item_name%%/i", $paypal["item_name"], $sbj)))
166
+ if (($sbj = preg_replace ("/%%first_name%%/i", $paypal["first_name"], $sbj)) && ($sbj = preg_replace ("/%%last_name%%/i", $paypal["last_name"], $sbj)))
167
+ if (($sbj = preg_replace ("/%%full_name%%/i", trim ($paypal["first_name"] . " " . $paypal["last_name"]), $sbj)))
168
+ if (($sbj = preg_replace ("/%%payer_email%%/i", $paypal["payer_email"], $sbj)))
169
+ /**/
170
+ if (($msg = preg_replace ("/%%cv([0-9]+)%%/ei", 'trim($cv[$1])', $msg)) && ($msg = preg_replace ("/%%subscr_id%%/i", $paypal["subscr_id"], $msg)))
171
+ if (($msg = preg_replace ("/%%initial%%/i", $initial, $msg)) && ($msg = preg_replace ("/%%recurring%%/i", $recurring, $msg)) && ($msg = preg_replace ("/%%regular%%/i", $regular, $msg)))
172
+ if (($msg = preg_replace ("/%%initial_term%%/i", $initial_term, $msg)) && ($msg = preg_replace ("/%%regular_term%%/i", $paypal["period3"], $msg)))
173
+ if (($msg = preg_replace ("/%%item_number%%/i", $paypal["item_number"], $msg)) && ($msg = preg_replace ("/%%item_name%%/i", $paypal["item_name"], $msg)))
174
+ if (($msg = preg_replace ("/%%first_name%%/i", $paypal["first_name"], $msg)) && ($msg = preg_replace ("/%%last_name%%/i", $paypal["last_name"], $msg)))
175
+ if (($msg = preg_replace ("/%%full_name%%/i", trim ($paypal["first_name"] . " " . $paypal["last_name"]), $msg)))
176
+ if (($msg = preg_replace ("/%%payer_email%%/i", $paypal["payer_email"], $msg)))
177
+ /**/
178
+ if (($sbj = trim ($sbj)) && ($msg = trim ($msg))) /* Make sure they are not empty. */
179
+ {
180
+ @mail ($paypal["payer_email"], $sbj, $msg, "From: \"" . preg_replace ('/"/', "'", $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["reg_email_from_name"]) . "\" <" . $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["reg_email_from_email"] . ">\r\nContent-Type: text/plain; charset=utf-8", "-f " . $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["reg_email_from_email"]);
181
+ /**/
182
+ $paypal["s2member_log"][] = "Email sent after signup, with a URL to assist Customer w/ registration.";
183
+ }
184
  }
185
  }
186
  /**/
189
  if (preg_match ("/^web_accept$/i", $paypal["txn_type"]))
190
  {
191
  $paypal["period3"] = "1 L"; /* 1 Lifetime. */
192
+ $paypal["mc_amount3"] = $paypal["mc_gross"];
193
  }
194
  /**/
195
+ $initial_term = $paypal["period1"] ? $paypal["period1"] : "0 D"; /* Do not allow the initial period to be empty. Defaults to 0 D. */
196
+ $initial = (isset ($paypal["mc_amount1"]) && preg_match ("/^[1-9]/", $paypal["period1"])) ? $paypal["mc_amount1"] : $paypal["mc_amount3"];
197
+ $regular = $paypal["mc_amount3"]; /* This is the regular payment amount that is charged to the customer. Always required by PayPal. */
198
+ $recurring = ($paypal["recurring"]) ? $paypal["mc_amount3"] : "0"; /* If non-recurring, this should be zero, otherwise regular. */
199
  /* The initial amount will only be $0 if a trial was offered. If no trial was offered, they were charged a regular rate. */
200
+ /**/
201
  foreach (preg_split ("/[\r\n\t]+/", $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["signup_notification_urls"]) as $url)
202
+ /**/
203
  if (($url = preg_replace ("/%%cv([0-9]+)%%/ei", 'urlencode(trim($cv[$1]))', $url)) && ($url = preg_replace ("/%%subscr_id%%/i", urlencode ($paypal["subscr_id"]), $url)))
204
+ if (($url = preg_replace ("/%%initial%%/i", urlencode ($initial), $url)) && ($url = preg_replace ("/%%recurring%%/i", urlencode ($recurring), $url)) && ($url = preg_replace ("/%%regular%%/i", urlencode ($regular), $url)))
205
+ if (($url = preg_replace ("/%%initial_term%%/i", urlencode ($initial_term), $url)) && ($url = preg_replace ("/%%regular_term%%/i", urlencode ($paypal["period3"]), $url)))
206
+ if (($url = preg_replace ("/%%item_number%%/i", urlencode ($paypal["item_number"]), $url)) && ($url = preg_replace ("/%%item_name%%/i", urlencode ($paypal["item_name"]), $url)))
207
+ if (($url = preg_replace ("/%%first_name%%/i", urlencode ($paypal["first_name"]), $url)) && ($url = preg_replace ("/%%last_name%%/i", urlencode ($paypal["last_name"]), $url)))
208
+ if (($url = preg_replace ("/%%full_name%%/i", urlencode (trim ($paypal["first_name"] . " " . $paypal["last_name"])), $url)))
209
+ if (($url = preg_replace ("/%%payer_email%%/i", urlencode ($paypal["payer_email"]), $url)))
210
+ /**/
211
+ if (($url = trim ($url))) /* Make sure it is not empty. */
212
+ ws_plugin__s2member_curlpsr ($url, "s2member=1");
 
213
  /**/
214
+ $paypal["s2member_log"][] = "Signup Notification URLs have been processed.";
215
  }
216
  }
217
+ /*
218
+ Subscription modifications.
219
+ */
220
+ else if (preg_match ("/^subscr_modify$/i", $paypal["txn_type"]) && $paypal["subscr_id"] && preg_match ("/^[1-4](\:|$)/", $paypal["item_number"]))
221
  {
222
  $paypal["s2member_log"][] = "s2Member txn_type identified as subscr_modify.";
223
  /**/
224
+ list ($paypal["level"], $paypal["ccaps"]) = preg_split ("/\:/", $paypal["item_number"], 2);
225
+ /**/
226
  if ($q = $wpdb->get_row ("SELECT `user_id` FROM `" . $wpdb->usermeta . "` WHERE `meta_key` = 's2member_subscr_id' AND `meta_value` = '" . $wpdb->escape ($paypal["subscr_id"]) . "' LIMIT 1"))
227
  {
228
  if ($user_id = $q->user_id) /* Got it! */
229
  {
230
  $user = new WP_User ($user_id);
231
+ $user->set_role ("s2member_level" . $paypal["level"]);
232
+ update_usermeta ($user_id, "s2member_subscr_id", $paypal["subscr_id"]);
233
  update_usermeta ($user_id, "s2member_custom", $paypal["custom"]);
234
  /**/
235
+ foreach ($user->allcaps as $cap => $cap_enabled)
236
+ if (preg_match ("/^access_s2member_ccap_/", $cap))
237
+ $user->remove_cap ($ccap = $cap);
238
+ /**/
239
+ foreach (preg_split ("/[\r\n\t\s;,]+/", $paypal["ccaps"]) as $ccap)
240
+ if (strlen ($ccap)) /* Don't add empty capabilities. */
241
+ $user->add_cap ("access_s2member_ccap_" . trim (strtolower ($ccap)));
242
+ /**/
243
+ delete_usermeta ($user_id, "s2member_file_download_access_arc");
244
+ delete_usermeta ($user_id, "s2member_file_download_access_log");
245
+ /**/
246
+ $paypal["s2member_log"][] = "s2Member Level/Capabilities updated on subscription modification.";
247
  }
248
  else
249
  {
250
+ $paypal["s2member_log"][] = "Unable to modify subscription. Could not get the existing user_id from the DB.";
251
  }
252
  }
253
  else
254
  {
255
+ $paypal["s2member_log"][] = "Unable to modify subscription. Could not find existing subscription in the DB.";
256
  }
257
  }
258
+ /*
259
+ Subscription payments.
260
+ */
261
+ else if (preg_match ("/^subscr_payment$/i", $paypal["txn_type"]) && $paypal["payer_email"] && $paypal["subscr_id"] && preg_match ("/^[1-4](\:|$)/", $paypal["item_number"]) && $paypal["txn_id"] && $paypal["mc_gross"])
262
  {
263
  $paypal["s2member_log"][] = "s2Member txn_type identified as subscr_payment.";
264
  /**/
265
+ list ($paypal["level"], $paypal["ccaps"]) = preg_split ("/\:/", $paypal["item_number"], 2);
266
+ /**/
267
  if ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["payment_notification_urls"] && is_array ($cv = preg_split ("/\|/", $paypal["custom"])))
268
  {
269
  foreach (preg_split ("/[\r\n\t]+/", $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["payment_notification_urls"]) as $url)
270
+ /**/
271
  if (($url = preg_replace ("/%%cv([0-9]+)%%/ei", 'urlencode(trim($cv[$1]))', $url)) && ($url = preg_replace ("/%%subscr_id%%/i", urlencode ($paypal["subscr_id"]), $url)))
272
+ if (($url = preg_replace ("/%%amount%%/i", urlencode ($paypal["mc_gross"]), $url)) && ($url = preg_replace ("/%%txn_id%%/i", urlencode ($paypal["txn_id"]), $url)))
273
  if (($url = preg_replace ("/%%item_number%%/i", urlencode ($paypal["item_number"]), $url)) && ($url = preg_replace ("/%%item_name%%/i", urlencode ($paypal["item_name"]), $url)))
274
  if (($url = preg_replace ("/%%first_name%%/i", urlencode ($paypal["first_name"]), $url)) && ($url = preg_replace ("/%%last_name%%/i", urlencode ($paypal["last_name"]), $url)))
275
  if (($url = preg_replace ("/%%full_name%%/i", urlencode (trim ($paypal["first_name"] . " " . $paypal["last_name"])), $url)))
276
  if (($url = preg_replace ("/%%payer_email%%/i", urlencode ($paypal["payer_email"]), $url)))
277
+ /**/
278
+ if (($url = trim ($url))) /* Make sure it is not empty. */
279
  ws_plugin__s2member_curlpsr ($url, "s2member=1");
280
  /**/
281
+ $paypal["s2member_log"][] = "Payment Notification URLs have been processed.";
282
  }
283
  }
284
+ /*
285
+ Subscription terminations.
286
+ */
287
+ else if ((preg_match ("/^subscr_eot$/i", $paypal["txn_type"]) || preg_match ("/^(refunded|reversed)$/i", $paypal["payment_status"])) && ($paypal["subscr_id"] || ($paypal["subscr_id"] = $paypal["parent_txn_id"])) && preg_match ("/^[1-4](\:|$)/", $paypal["item_number"]))
288
  {
289
  $paypal["s2member_log"][] = "s2Member txn_type identified as subscr_eot - or - payment_status (refunded|reversed).";
290
  /**/
291
+ list ($paypal["level"], $paypal["ccaps"]) = preg_split ("/\:/", $paypal["item_number"], 2);
292
+ /**/
293
  if ($q = $wpdb->get_row ("SELECT `user_id` FROM `" . $wpdb->usermeta . "` WHERE `meta_key` = 's2member_subscr_id' AND `meta_value` = '" . $wpdb->escape ($paypal["subscr_id"]) . "' LIMIT 1"))
294
  {
295
+ if ($user_id = $q->user_id) /* Demote to Free Subscriber, or delete the Member completely. */
296
  {
297
+ if ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["membership_eot_behavior"] === "demote")
298
+ {
299
+ $user = new WP_User ($user_id);
300
+ $user->set_role ("subscriber");
301
+ delete_usermeta ($user_id, "s2member_custom");
302
+ delete_usermeta ($user_id, "s2member_subscr_id");
303
+ /**/
304
+ foreach ($user->allcaps as $cap => $cap_enabled)
305
+ if (preg_match ("/^access_s2member_ccap_/", $cap))
306
+ $user->remove_cap ($ccap = $cap);
307
+ /**/
308
+ delete_usermeta ($user_id, "s2member_file_download_access_arc");
309
+ delete_usermeta ($user_id, "s2member_file_download_access_log");
310
+ /**/
311
+ $paypal["s2member_log"][] = "Member Level/Capabilities demoted to a Free Subscriber.";
312
+ /**/
313
+ if ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["eot_del_notification_urls"] && is_array ($cv = preg_split ("/\|/", $paypal["custom"])))
314
+ {
315
+ foreach (preg_split ("/[\r\n\t]+/", $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["eot_del_notification_urls"]) as $url) /* Handle eot notifications. */
316
+ /**/
317
+ if (($url = preg_replace ("/%%cv([0-9]+)%%/ei", 'urlencode(trim($cv[$1]))', $url)) && ($url = preg_replace ("/%%subscr_id%%/i", urlencode ($paypal["subscr_id"]), $url)))
318
+ if (($url = preg_replace ("/%%user_first_name%%/i", urlencode ($user->first_name), $url)) && ($url = preg_replace ("/%%user_last_name%%/i", urlencode ($user->last_name), $url)))
319
+ if (($url = preg_replace ("/%%user_full_name%%/i", urlencode (trim ($user->first_name . " " . $user->last_name)), $url)))
320
+ if (($url = preg_replace ("/%%user_email%%/i", urlencode ($user->user_email), $url)))
321
+ /**/
322
+ if (($url = trim ($url))) /* Make sure it is not empty. */
323
+ ws_plugin__s2member_curlpsr ($url, "s2member=1");
324
+ /**/
325
+ $paypal["s2member_log"][] = "EOT/Deletion Notification URLs have been processed.";
326
+ }
327
+ }
328
+ else if ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["membership_eot_behavior"] === "delete")
329
+ {
330
+ wp_delete_user ($user_id); /* Triggers: `ws_plugin__s2member_handle_user_deletions()` */
331
+ /* `ws_plugin__s2member_handle_user_deletions()` triggers `eot_del_notification_urls` */
332
+ /**/
333
+ $paypal["s2member_log"][] = "The Member's account has been deleted completely.";
334
+ /**/
335
+ $paypal["s2member_log"][] = "EOT/Deletion Notification URLs have been processed.";
336
+ }
337
  }
338
  else
339
  {
340
+ $paypal["s2member_log"][] = "Unable to (demote|delete) Member. Could not get the existing user_id from the DB. It's possible that it was already removed manually by a site administrator.";
341
  }
342
  /**/
343
  if (!preg_match ("/^subscr_eot$/i", $paypal["txn_type"]) && preg_match ("/^(refunded|reversed)$/i", $paypal["payment_status"]) && $paypal["parent_txn_id"])
345
  if ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["ref_rev_notification_urls"] && is_array ($cv = preg_split ("/\|/", $paypal["custom"])))
346
  {
347
  foreach (preg_split ("/[\r\n\t]+/", $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["ref_rev_notification_urls"]) as $url)
348
+ /**/
349
  if (($url = preg_replace ("/%%cv([0-9]+)%%/ei", 'urlencode(trim($cv[$1]))', $url)) && ($url = preg_replace ("/%%subscr_id%%/i", urlencode ($paypal["subscr_id"]), $url)))
350
+ if (($url = preg_replace ("/%%-amount%%/i", urlencode ($paypal["mc_gross"]), $url)) && ($url = preg_replace ("/%%parent_txn_id%%/i", urlencode ($paypal["parent_txn_id"]), $url)))
351
  if (($url = preg_replace ("/%%item_number%%/i", urlencode ($paypal["item_number"]), $url)) && ($url = preg_replace ("/%%item_name%%/i", urlencode ($paypal["item_name"]), $url)))
352
  if (($url = preg_replace ("/%%first_name%%/i", urlencode ($paypal["first_name"]), $url)) && ($url = preg_replace ("/%%last_name%%/i", urlencode ($paypal["last_name"]), $url)))
353
  if (($url = preg_replace ("/%%full_name%%/i", urlencode (trim ($paypal["first_name"] . " " . $paypal["last_name"])), $url)))
354
  if (($url = preg_replace ("/%%payer_email%%/i", urlencode ($paypal["payer_email"]), $url)))
355
+ /**/
356
+ if (($url = trim ($url))) /* Make sure it is not empty. */
357
  ws_plugin__s2member_curlpsr ($url, "s2member=1");
358
  /**/
359
+ $paypal["s2member_log"][] = "Refund/Reversal Notification URLs have been processed.";
360
  }
361
  }
362
  }
363
  else
364
  {
365
+ $paypal["s2member_log"][] = "Unable to (demote|delete) Member. Could not find existing subscription in the DB. It's possible that it was already removed manually by a site administrator.";
366
  }
367
  }
368
  else
369
  {
370
+ $paypal["s2member_log"][] = "Properly ignoring this IPN request. The txn_type does not require any action on the part of s2Member.";
371
  }
372
  }
373
  else
374
  {
375
+ $paypal["s2member_log"][] = "Unable to verify _SERVER[HTTP_HOST]. Possibly caused by a fraudulent request. If this error continues, please check the `custom` value in your Button Code. It MUST start with your domain name.";
376
  }
377
  }
378
  else
379
  {
380
+ $paypal["s2member_log"][] = "Unable to verify POST vars. Possibly caused by a fraudulent request. If this error continues, please run IPN tests against your server from a PayPal® Sandbox account. They provide special diagnostic tools that may assist you.";
381
  }
382
  /**/
383
  if ($_GET["s2member_paypal_proxy"]) /* For proxy identification. */
includes/functions/paypal-register.inc.php DELETED
@@ -1,40 +0,0 @@
1
- <?php
2
- /*
3
- Copyright: © 2009 WebSharks, Inc. ( coded in the USA )
4
- <mailto:support@websharks-inc.com> <http://www.websharks-inc.com/>
5
-
6
- Released under the terms of the GNU General Public License.
7
- You should have received a copy of the GNU General Public License,
8
- along with this software. In the main directory, see: /licensing/
9
- If not, see: <http://www.gnu.org/licenses/>.
10
- */
11
- /*
12
- Direct access denial.
13
- */
14
- if (realpath (__FILE__) === realpath ($_SERVER["SCRIPT_FILENAME"]))
15
- exit;
16
- /*
17
- Handles paypal registration links.
18
- Attach to: add_action("init");
19
- */
20
- function ws_plugin__s2member_paypal_register ()
21
- {
22
- if ($_GET["s2member_paypal_register"])
23
- {
24
- if (is_array ($registered = preg_split ("/\:\.\:\|\:\.\:/", ws_plugin__s2member_xdecrypt ($_GET["s2member_paypal_register"]))))
25
- {
26
- if (count ($registered) === 4 && $registered[0] === "subscr_id_custom_item_number" && $registered[1] && $registered[2] && $registered[3])
27
- {
28
- setcookie ("s2member_subscr_id", $registered[1], time () + 31556926, "/");
29
- setcookie ("s2member_custom", $registered[2], time () + 31556926, "/");
30
- setcookie ("s2member_level", $registered[3], time () + 31556926, "/");
31
- /**/
32
- echo '<script type="text/javascript">' . "\n";
33
- echo "window.location = '" . esc_js (add_query_arg ("action", "register", wp_login_url ())) . "';";
34
- echo '</script>' . "\n";
35
- }
36
- }
37
- exit;
38
- }
39
- }
40
- ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
includes/functions/paypal-return.inc.php CHANGED
@@ -34,12 +34,43 @@ function ws_plugin__s2member_paypal_return ()
34
  { /* The business address validation was removed from this routine, because PayPal® always fills that with the primary
35
  email address. In cases where an alternate PayPal® address is being paid, validation is not possible. */
36
  $paypal["s2member_log"][] = "s2Member originating domain ( _SERVER[HTTP_HOST] ) validated.";
37
- /**/
38
- if (preg_match ("/^(web_accept|subscr_signup|subscr_payment)$/i", $paypal["txn_type"]) && ($paypal["subscr_id"] || ($paypal["subscr_id"] = $paypal["txn_id"])) && preg_match ("/^[1-4]$/", $paypal["item_number"]))
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
39
  { /* With Auto-Return/PDT, PayPal will send subscr_payment instead of subscr_signup to the return URL.
40
  So we need to look for (web_accept|subscr_signup|subscr_payment), and treat them as the same. */
41
  $paypal["s2member_log"][] = "s2Member txn_type identified as (web_accept|subscr_signup|subscr_payment).";
42
  /**/
 
 
 
 
43
  if (preg_match ("/(updat|upgrad)/i", $paypal["option_name1"]) && $paypal["option_selection1"]) /* Advanced subscription update modifications. */
44
  /* This advanced method is required whenever a subscription that is already completed, or was never setup to recur in the first place needs to be modified. PayPal® will not allow the
45
  modify=2 parameter to be used in those scenarios, because technically there is nothing to update. The only thing to be updated is the existing account. */
@@ -53,19 +84,28 @@ function ws_plugin__s2member_paypal_return ()
53
  if ($user_id = $q->user_id) /* Got it! */
54
  {
55
  $user = new WP_User ($user_id);
56
- $user->set_role ("s2member_level" . $paypal["item_number"]);
57
  update_usermeta ($user_id, "s2member_subscr_id", $paypal["subscr_id"]);
58
  update_usermeta ($user_id, "s2member_custom", $paypal["custom"]);
 
 
 
 
 
 
 
 
 
59
  delete_usermeta ($user_id, "s2member_file_download_access_arc");
60
  delete_usermeta ($user_id, "s2member_file_download_access_log");
61
  /**/
62
- $paypal["s2member_log"][] = "s2Member level updated w/ advanced update routines.";
63
  /**/
64
  echo '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">' . "\n";
65
  echo '<html xmlns="http://www.w3.org/1999/xhtml" ', language_attributes (), '>' . "\n";
66
  echo '<head profile="http://gmpg.org/xfn/11">' . "\n";
67
  echo '<meta http-equiv="Content-Type" content="' . get_bloginfo ("html_type") . '; charset=' . get_bloginfo ("charset") . '" />' . "\n";
68
- echo '<script type="text/javascript">' . "\n"; /* Onload allows any pixel codes to finish loading. */
69
  echo "window.onload = function(){ " . "\n"; /* After everything has finished loading, we alert and then redirect. */
70
  echo "alert('Thank You! Your membership has been updated to:\\n\\n" . esc_js ($paypal["item_name"]) . "\\n\\nYou\\'ll need to log back in now.');" . "\n";
71
  echo "window.location = '" . wp_login_url () . "'; };" . "\n";
@@ -74,58 +114,71 @@ function ws_plugin__s2member_paypal_return ()
74
  /**/
75
  echo '<body style="background:#' . $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["login_reg_background_color"] . ' url(' . $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["login_reg_background_image"] . ');">' . "\n";
76
  /**/
77
- echo '<!-- Pixel Tracking codes from the s2Member plugin for WordPress. -->' . "\n";
78
  /**/
79
- if (($code = trim ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["signup_pixel_tracking_codes"])) && is_array ($cv = preg_split ("/\|/", $paypal["custom"])))
80
  {
81
  if (preg_match ("/^subscr_signup$/i", $paypal["txn_type"]))
82
- $initial = (isset ($paypal["amount1"]) && preg_match ("/^[1-9]/", $paypal["period1"])) ? $paypal["amount1"] : $paypal["amount3"];
83
  /* The initial amount will only be $0 if a trial was offered. If no trial was offered, they were charged a regular rate. */
84
  else if (preg_match ("/^(web_accept|subscr_payment)$/i", $paypal["txn_type"])) /* PDT w/Auto-Return sends subscr_payment. */
85
- $initial = $paypal["payment_gross"]; /* Here, the initial payment is provided clearly as the payment gross. */
86
  /**/
87
- if (($code = preg_replace ("/%%cv([0-9]+)%%/ei", 'urlencode(trim($cv[$1]))', $code)) && ($code = preg_replace ("/%%subscr_id%%/i", urlencode ($paypal["subscr_id"]), $code)))
88
- if (($code = preg_replace ("/%%initial%%/i", urlencode ($initial), $code))) /* Adv calculations here. We have to support both sets of variables, subscr_signup & subscr_payment. */
89
- if (($code = preg_replace ("/%%item_number%%/i", urlencode ($paypal["item_number"]), $code)) && ($code = preg_replace ("/%%item_name%%/i", urlencode ($paypal["item_name"]), $code)))
90
- if (($code = preg_replace ("/%%first_name%%/i", urlencode ($paypal["first_name"]), $code)) && ($code = preg_replace ("/%%last_name%%/i", urlencode ($paypal["last_name"]), $code)))
91
- if (($code = preg_replace ("/%%full_name%%/i", urlencode (trim ($paypal["first_name"] . " " . $paypal["last_name"])), $code)))
92
- if (($code = preg_replace ("/%%payer_email%%/i", urlencode ($paypal["payer_email"]), $code)))
93
- if (($code = trim ($code))) /* Make sure it is not empty now. */
94
- echo $code . "\n"; /* Everything here must finish loading. */
95
- /**/
96
- $paypal["s2member_log"][] = "Signup Pixel Tracking codes have been processed.";
 
 
 
 
 
 
 
 
 
97
  }
98
- echo '<!-- Pixel Tracking codes from the s2Member plugin for WordPress. -->' . "\n";
99
  /**/
100
- $paypal["s2member_log"][] = "Redirecting user to login page.";
 
 
101
  /**/
102
  echo '</body>' . "\n";
103
  echo '</html>';
104
  }
105
  else
106
  {
107
- $paypal["s2member_log"][] = "Unable to get user_id from the DB.";
108
  /**/
109
  echo '<script type="text/javascript">' . "\n";
110
- echo "alert('Thank you very much... please click OK!');" . "\n";
111
  echo "window.location = '" . esc_js (wp_login_url ()) . "';";
112
  echo '</script>' . "\n";
113
  /**/
114
- $paypal["s2member_log"][] = "Redirecting user to login page.";
115
  }
116
  }
117
  else
118
  {
119
- $paypal["s2member_log"][] = "Unable to find subscription/subscriber in the DB.";
120
  /**/
121
  echo '<script type="text/javascript">' . "\n";
122
- echo "alert('Thank you very much... please click OK!');" . "\n";
123
  echo "window.location = '" . esc_js (wp_login_url ()) . "';";
124
  echo '</script>' . "\n";
125
  /**/
126
- $paypal["s2member_log"][] = "Redirecting user to login page.";
127
  }
128
  }
 
 
 
129
  else /* Else this is a normal subscription signup, we are not updating anything for a past subscription. */
130
  {
131
  $paypal["s2member_log"][] = "s2Member txn_type identified as (web_accept|subscr_signup|subscr_payment) w/o update vars.";
@@ -140,124 +193,150 @@ function ws_plugin__s2member_paypal_return ()
140
  echo '<html xmlns="http://www.w3.org/1999/xhtml" ', language_attributes (), '>' . "\n";
141
  echo '<head profile="http://gmpg.org/xfn/11">' . "\n";
142
  echo '<meta http-equiv="Content-Type" content="' . get_bloginfo ("html_type") . '; charset=' . get_bloginfo ("charset") . '" />' . "\n";
143
- echo '<script type="text/javascript">' . "\n"; /* Onload allows any pixel codes to finish loading. */
144
  echo "window.onload = function(){ " . "\n"; /* After everything has finished loading, we alert and then redirect. */
145
- echo "alert('Thank You! Your membership has been approved.\\nThe next step is to Register a Username.\\n\\nPlease click OK to Register now.');" . "\n";/**/
146
  echo "window.location = '" . esc_js (add_query_arg ("action", "register", wp_login_url ())) . "'; };" . "\n";
147
  echo '</script>' . "\n";
148
  echo '</head>' . "\n";
149
  /**/
150
  echo '<body style="background:#' . $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["login_reg_background_color"] . ' url(' . $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["login_reg_background_image"] . ');">' . "\n";
151
  /**/
152
- echo '<!-- Pixel Tracking codes from the s2Member plugin for WordPress. -->' . "\n";
153
  /**/
154
- if (($code = trim ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["signup_pixel_tracking_codes"])) && is_array ($cv = preg_split ("/\|/", $paypal["custom"])))
155
  {
156
  if (preg_match ("/^subscr_signup$/i", $paypal["txn_type"]))
157
- $initial = (isset ($paypal["amount1"]) && preg_match ("/^[1-9]/", $paypal["period1"])) ? $paypal["amount1"] : $paypal["amount3"];
158
  /* The initial amount will only be $0 if a trial was offered. If no trial was offered, they were charged a regular rate. */
159
  else if (preg_match ("/^(web_accept|subscr_payment)$/i", $paypal["txn_type"])) /* PDT w/Auto-Return sends subscr_payment. */
160
- $initial = $paypal["payment_gross"]; /* Here, the initial payment is provided clearly as the payment gross. */
161
- /**/
162
- if (($code = preg_replace ("/%%cv([0-9]+)%%/ei", 'urlencode(trim($cv[$1]))', $code)) && ($code = preg_replace ("/%%subscr_id%%/i", urlencode ($paypal["subscr_id"]), $code)))
163
- if (($code = preg_replace ("/%%initial%%/i", urlencode ($initial), $code))) /* Adv calculations here. We have to support both sets of variables, subscr_signup & subscr_payment. */
164
- if (($code = preg_replace ("/%%item_number%%/i", urlencode ($paypal["item_number"]), $code)) && ($code = preg_replace ("/%%item_name%%/i", urlencode ($paypal["item_name"]), $code)))
165
- if (($code = preg_replace ("/%%first_name%%/i", urlencode ($paypal["first_name"]), $code)) && ($code = preg_replace ("/%%last_name%%/i", urlencode ($paypal["last_name"]), $code)))
166
- if (($code = preg_replace ("/%%full_name%%/i", urlencode (trim ($paypal["first_name"] . " " . $paypal["last_name"])), $code)))
167
- if (($code = preg_replace ("/%%payer_email%%/i", urlencode ($paypal["payer_email"]), $code)))
168
- if (($code = trim ($code))) /* Make sure it is not empty now. */
169
- echo $code . "\n"; /* Everything here must finish loading. */
170
  /**/
171
- $paypal["s2member_log"][] = "Signup Pixel Tracking codes have been processed.";
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
172
  }
173
- echo '<!-- Pixel Tracking codes from the s2Member plugin for WordPress. -->' . "\n";
174
  /**/
175
- $paypal["s2member_log"][] = "Redirecting user to registration page.";
 
 
176
  /**/
177
  echo '</body>' . "\n";
178
  echo '</html>';
179
  }
180
  }
181
- /**/
182
- else if (preg_match ("/^subscr_modify$/i", $paypal["txn_type"]) && $paypal["subscr_id"] && preg_match ("/^[1-4]$/", $paypal["item_number"]))
 
 
183
  {
184
  $paypal["s2member_log"][] = "s2Member txn_type identified as subscr_modify.";
185
  /**/
 
 
186
  if ($q = $wpdb->get_row ("SELECT `user_id` FROM `" . $wpdb->usermeta . "` WHERE `meta_key` = 's2member_subscr_id' AND `meta_value` = '" . $wpdb->escape ($paypal["subscr_id"]) . "' LIMIT 1"))
187
  {
188
  if ($user_id = $q->user_id) /* Got it! */
189
  {
190
  $user = new WP_User ($user_id);
191
- $user->set_role ("s2member_level" . $paypal["item_number"]);
 
192
  update_usermeta ($user_id, "s2member_custom", $paypal["custom"]);
193
  /**/
194
- $paypal["s2member_log"][] = "s2Member level updated on subscription modification.";
 
 
 
 
 
 
 
 
 
 
 
195
  /**/
196
  echo '<script type="text/javascript">' . "\n";
197
  echo "alert('Thank You! Your membership has been updated to:\\n\\n" . esc_js ($paypal["item_name"]) . "\\n\\nYou\\'ll need to log back in now.');" . "\n";
198
  echo "window.location = '" . esc_js (wp_login_url ()) . "';";
199
  echo '</script>' . "\n";
200
  /**/
201
- $paypal["s2member_log"][] = "Redirecting user to login page.";
202
  }
203
  else
204
  {
205
- $paypal["s2member_log"][] = "Unable to get user_id from the DB.";
206
  /**/
207
  echo '<script type="text/javascript">' . "\n";
208
- echo "alert('Thank you very much... please click OK!');" . "\n";
209
  echo "window.location = '" . esc_js (wp_login_url ()) . "';";
210
  echo '</script>' . "\n";
211
  /**/
212
- $paypal["s2member_log"][] = "Redirecting user to login page.";
213
  }
214
  }
215
  else
216
  {
217
- $paypal["s2member_log"][] = "Unable to find subscription in the DB.";
218
  /**/
219
  echo '<script type="text/javascript">' . "\n";
220
- echo "alert('Thank you very much... please click OK!');" . "\n";
221
  echo "window.location = '" . esc_js (wp_login_url ()) . "';";
222
  echo '</script>' . "\n";
223
  /**/
224
- $paypal["s2member_log"][] = "Redirecting user to login page.";
225
  }
226
  }
227
  else
228
  {
229
- $paypal["s2member_log"][] = "The txn_type does not require any action on the part of s2Member.";
230
  /**/
231
  echo '<script type="text/javascript">' . "\n";
232
- echo "alert('Thank you very much... please click OK!');" . "\n";
233
  echo "window.location = '" . esc_js (wp_login_url ()) . "';";
234
  echo '</script>' . "\n";
235
  /**/
236
- $paypal["s2member_log"][] = "Redirecting user to login page.";
237
  }
238
  }
239
  else
240
  {
241
- $paypal["s2member_log"][] = "Unable to verify _SERVER[HTTP_HOST].";
242
  /**/
243
  echo '<script type="text/javascript">' . "\n";
244
- echo "alert('Thank you very much... please click OK!');" . "\n";
245
  echo "window.location = '" . esc_js (wp_login_url ()) . "';";
246
  echo '</script>' . "\n";
247
  /**/
248
- $paypal["s2member_log"][] = "Redirecting user to login page.";
249
  }
250
  }
251
  else
252
  {
253
- $paypal["s2member_log"][] = "Unable to verify POST vars.";
254
  /**/
255
  echo '<script type="text/javascript">' . "\n";
256
- echo "alert('Thank you very much... please click OK!');" . "\n";
257
  echo "window.location = '" . esc_js (wp_login_url ()) . "';";
258
  echo '</script>' . "\n";
259
  /**/
260
- $paypal["s2member_log"][] = "Redirecting user to login page.";
261
  }
262
  /**/
263
  if ($_GET["s2member_paypal_proxy"]) /* For proxy identification. */
34
  { /* The business address validation was removed from this routine, because PayPal® always fills that with the primary
35
  email address. In cases where an alternate PayPal® address is being paid, validation is not possible. */
36
  $paypal["s2member_log"][] = "s2Member originating domain ( _SERVER[HTTP_HOST] ) validated.";
37
+ /*
38
+ Single-Page Access.
39
+ */
40
+ if (preg_match ("/^web_accept$/i", $paypal["txn_type"]) && $paypal["txn_id"] && preg_match ("/^sp\:[0-9]+$/", $paypal["item_number"]))
41
+ {
42
+ $paypal["s2member_log"][] = "s2Member txn_type identified as (web_accept) for Single-Page access.";
43
+ /**/
44
+ list (, $paypal["page"]) = preg_split ("/\:/", $paypal["item_number"], 2);
45
+ /**/
46
+ if (($sp_access_url = ws_plugin__s2member_sp_access_link_gen ($paypal["page"], false)))
47
+ {
48
+ header ("Location: " . $sp_access_url);
49
+ }
50
+ else /* Otherwise, the page ID must have been invalid. Or it's possible that the Page was deleted. */
51
+ {
52
+ $paypal["s2member_log"][] = "Unable to generate Single-Page Access Link.";
53
+ /**/
54
+ echo '<script type="text/javascript">' . "\n";
55
+ echo "alert('ERROR: Unable to generate Access Link. Please contact Support for assistance.');" . "\n";
56
+ echo "window.location = '" . esc_js (get_bloginfo ("url")) . "';";
57
+ echo '</script>' . "\n";
58
+ /**/
59
+ $paypal["s2member_log"][] = "Redirecting Customer to the Home Page, due to an error that occurred.";
60
+ }
61
+ }
62
+ /*
63
+ New subscriptions. Possibly containing advanced updated vars ( option_name1, option_selection1 ); which allow account modifications.
64
+ */
65
+ else if (preg_match ("/^(web_accept|subscr_signup|subscr_payment)$/i", $paypal["txn_type"]) && ($paypal["subscr_id"] || ($paypal["subscr_id"] = $paypal["txn_id"])) && preg_match ("/^[1-4](\:|$)/", $paypal["item_number"]))
66
  { /* With Auto-Return/PDT, PayPal will send subscr_payment instead of subscr_signup to the return URL.
67
  So we need to look for (web_accept|subscr_signup|subscr_payment), and treat them as the same. */
68
  $paypal["s2member_log"][] = "s2Member txn_type identified as (web_accept|subscr_signup|subscr_payment).";
69
  /**/
70
+ list ($paypal["level"], $paypal["ccaps"]) = preg_split ("/\:/", $paypal["item_number"], 2);
71
+ /*
72
+ New subscription with advanced update vars ( option_name1, option_selection1 ).
73
+ */
74
  if (preg_match ("/(updat|upgrad)/i", $paypal["option_name1"]) && $paypal["option_selection1"]) /* Advanced subscription update modifications. */
75
  /* This advanced method is required whenever a subscription that is already completed, or was never setup to recur in the first place needs to be modified. PayPal® will not allow the
76
  modify=2 parameter to be used in those scenarios, because technically there is nothing to update. The only thing to be updated is the existing account. */
84
  if ($user_id = $q->user_id) /* Got it! */
85
  {
86
  $user = new WP_User ($user_id);
87
+ $user->set_role ("s2member_level" . $paypal["level"]);
88
  update_usermeta ($user_id, "s2member_subscr_id", $paypal["subscr_id"]);
89
  update_usermeta ($user_id, "s2member_custom", $paypal["custom"]);
90
+ /**/
91
+ foreach ($user->allcaps as $cap => $cap_enabled)
92
+ if (preg_match ("/^access_s2member_ccap_/", $cap))
93
+ $user->remove_cap ($ccap = $cap);
94
+ /**/
95
+ foreach (preg_split ("/[\r\n\t\s;,]+/", $paypal["ccaps"]) as $ccap)
96
+ if (strlen ($ccap)) /* Don't add empty capabilities. */
97
+ $user->add_cap ("access_s2member_ccap_" . trim (strtolower ($ccap)));
98
+ /**/
99
  delete_usermeta ($user_id, "s2member_file_download_access_arc");
100
  delete_usermeta ($user_id, "s2member_file_download_access_log");
101
  /**/
102
+ $paypal["s2member_log"][] = "s2Member Level/Capabilities updated w/ advanced update routines.";
103
  /**/
104
  echo '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">' . "\n";
105
  echo '<html xmlns="http://www.w3.org/1999/xhtml" ', language_attributes (), '>' . "\n";
106
  echo '<head profile="http://gmpg.org/xfn/11">' . "\n";
107
  echo '<meta http-equiv="Content-Type" content="' . get_bloginfo ("html_type") . '; charset=' . get_bloginfo ("charset") . '" />' . "\n";
108
+ echo '<script type="text/javascript">' . "\n"; /* Onload allows any tracking codes to finish loading. */
109
  echo "window.onload = function(){ " . "\n"; /* After everything has finished loading, we alert and then redirect. */
110
  echo "alert('Thank You! Your membership has been updated to:\\n\\n" . esc_js ($paypal["item_name"]) . "\\n\\nYou\\'ll need to log back in now.');" . "\n";
111
  echo "window.location = '" . wp_login_url () . "'; };" . "\n";
114
  /**/
115
  echo '<body style="background:#' . $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["login_reg_background_color"] . ' url(' . $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["login_reg_background_image"] . ');">' . "\n";
116
  /**/
117
+ echo '<!-- Tracking codes from the s2Member plugin for WordPress. -->' . "\n";
118
  /**/
119
+ if (($code = trim ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["signup_tracking_codes"])) && is_array ($cv = preg_split ("/\|/", $paypal["custom"])))
120
  {
121
  if (preg_match ("/^subscr_signup$/i", $paypal["txn_type"]))
122
+ $initial = (isset ($paypal["mc_amount1"]) && preg_match ("/^[1-9]/", $paypal["period1"])) ? $paypal["mc_amount1"] : $paypal["mc_amount3"];
123
  /* The initial amount will only be $0 if a trial was offered. If no trial was offered, they were charged a regular rate. */
124
  else if (preg_match ("/^(web_accept|subscr_payment)$/i", $paypal["txn_type"])) /* PDT w/Auto-Return sends subscr_payment. */
125
+ $initial = $paypal["mc_gross"]; /* Here, the initial payment is provided clearly as the payment gross. */
126
  /**/
127
+ if (($code = preg_replace ("/%%cv([0-9]+)%%/ei", 'trim($cv[$1])', $code)) && ($code = preg_replace ("/%%subscr_id%%/i", $paypal["subscr_id"], $code)))
128
+ if (($code = preg_replace ("/%%initial%%/i", $initial, $code))) /* Adv calculations here. We have to support both sets of variables, subscr_signup & subscr_payment. */
129
+ if (($code = preg_replace ("/%%item_number%%/i", $paypal["item_number"], $code)) && ($code = preg_replace ("/%%item_name%%/i", $paypal["item_name"], $code)))
130
+ if (($code = preg_replace ("/%%first_name%%/i", $paypal["first_name"], $code)) && ($code = preg_replace ("/%%last_name%%/i", $paypal["last_name"], $code)))
131
+ if (($code = preg_replace ("/%%full_name%%/i", trim ($paypal["first_name"] . " " . $paypal["last_name"]), $code)))
132
+ if (($code = preg_replace ("/%%payer_email%%/i", $paypal["payer_email"], $code)))
133
+ /**/
134
+ if (($code = trim ($code))) /* Make sure it is not empty. */
135
+ /**/
136
+ if ($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["is_wpmu"])
137
+ {
138
+ echo $code . "\n"; /* No PHP allowed here. */
139
+ $paypal["s2member_log"][] = "Signup Tracking codes have been processed.";
140
+ }
141
+ else /* Otherwise, it's safe to allow PHP code. */
142
+ {
143
+ eval ("?>" . $code);
144
+ $paypal["s2member_log"][] = "Signup Tracking codes have been evaluated.";
145
+ }
146
  }
 
147
  /**/
148
+ echo '<!-- Tracking codes from the s2Member plugin for WordPress. -->' . "\n";
149
+ /**/
150
+ $paypal["s2member_log"][] = "Success! Redirecting Customer to the Login Page. They need to log back in after this modification.";
151
  /**/
152
  echo '</body>' . "\n";
153
  echo '</html>';
154
  }
155
  else
156
  {
157
+ $paypal["s2member_log"][] = "Unable to modify subscription. Could not get the existing user_id from the DB. Please check the on0 and os0 variables in your Button Code.";
158
  /**/
159
  echo '<script type="text/javascript">' . "\n";
160
+ echo "alert('ERROR: Unable to modify subscription. Please contact Support for assistance.\\n\\nCould not get the existing user_id from the DB.');" . "\n";
161
  echo "window.location = '" . esc_js (wp_login_url ()) . "';";
162
  echo '</script>' . "\n";
163
  /**/
164
+ $paypal["s2member_log"][] = "Redirecting Customer to the Login Page, due to an error that occurred.";
165
  }
166
  }
167
  else
168
  {
169
+ $paypal["s2member_log"][] = "Unable to modify subscription. Could not find existing subscription in the DB. Please check the on0 and os0 variables in your Button Code.";
170
  /**/
171
  echo '<script type="text/javascript">' . "\n";
172
+ echo "alert('ERROR: Unable to modify subscription. Please contact Support for assistance.\\n\\nCould not find existing subscription in the DB.');" . "\n";
173
  echo "window.location = '" . esc_js (wp_login_url ()) . "';";
174
  echo '</script>' . "\n";
175
  /**/
176
+ $paypal["s2member_log"][] = "Redirecting Customer to the Login Page, due to an error that occurred.";
177
  }
178
  }
179
+ /*
180
+ New subscription. Normal subscription signup, we are not updating anything for a past subscription.
181
+ */
182
  else /* Else this is a normal subscription signup, we are not updating anything for a past subscription. */
183
  {
184
  $paypal["s2member_log"][] = "s2Member txn_type identified as (web_accept|subscr_signup|subscr_payment) w/o update vars.";
193
  echo '<html xmlns="http://www.w3.org/1999/xhtml" ', language_attributes (), '>' . "\n";
194
  echo '<head profile="http://gmpg.org/xfn/11">' . "\n";
195
  echo '<meta http-equiv="Content-Type" content="' . get_bloginfo ("html_type") . '; charset=' . get_bloginfo ("charset") . '" />' . "\n";
196
+ echo '<script type="text/javascript">' . "\n"; /* Onload allows any tracking codes to finish loading. */
197
  echo "window.onload = function(){ " . "\n"; /* After everything has finished loading, we alert and then redirect. */
198
+ echo "alert('Thank You! Your account has been approved.\\nThe next step is to Register a Username.\\n\\nPlease click OK to Register now.');" . "\n";/**/
199
  echo "window.location = '" . esc_js (add_query_arg ("action", "register", wp_login_url ())) . "'; };" . "\n";
200
  echo '</script>' . "\n";
201
  echo '</head>' . "\n";
202
  /**/
203
  echo '<body style="background:#' . $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["login_reg_background_color"] . ' url(' . $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["login_reg_background_image"] . ');">' . "\n";
204
  /**/
205
+ echo '<!-- Tracking codes from the s2Member plugin for WordPress. -->' . "\n";
206
  /**/
207
+ if (($code = trim ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["signup_tracking_codes"])) && is_array ($cv = preg_split ("/\|/", $paypal["custom"])))
208
  {
209
  if (preg_match ("/^subscr_signup$/i", $paypal["txn_type"]))
210
+ $initial = (isset ($paypal["mc_amount1"]) && preg_match ("/^[1-9]/", $paypal["period1"])) ? $paypal["mc_amount1"] : $paypal["mc_amount3"];
211
  /* The initial amount will only be $0 if a trial was offered. If no trial was offered, they were charged a regular rate. */
212
  else if (preg_match ("/^(web_accept|subscr_payment)$/i", $paypal["txn_type"])) /* PDT w/Auto-Return sends subscr_payment. */
213
+ $initial = $paypal["mc_gross"]; /* Here, the initial payment is provided clearly as the payment gross. */
 
 
 
 
 
 
 
 
 
214
  /**/
215
+ if (($code = preg_replace ("/%%cv([0-9]+)%%/ei", 'trim($cv[$1])', $code)) && ($code = preg_replace ("/%%subscr_id%%/i", $paypal["subscr_id"], $code)))
216
+ if (($code = preg_replace ("/%%initial%%/i", $initial, $code))) /* Adv calculations here. We have to support both sets of variables, subscr_signup & subscr_payment. */
217
+ if (($code = preg_replace ("/%%item_number%%/i", $paypal["item_number"], $code)) && ($code = preg_replace ("/%%item_name%%/i", $paypal["item_name"], $code)))
218
+ if (($code = preg_replace ("/%%first_name%%/i", $paypal["first_name"], $code)) && ($code = preg_replace ("/%%last_name%%/i", $paypal["last_name"], $code)))
219
+ if (($code = preg_replace ("/%%full_name%%/i", trim ($paypal["first_name"] . " " . $paypal["last_name"]), $code)))
220
+ if (($code = preg_replace ("/%%payer_email%%/i", $paypal["payer_email"], $code)))
221
+ /**/
222
+ if (($code = trim ($code))) /* Make sure it is not empty. */
223
+ /**/
224
+ if ($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["is_wpmu"])
225
+ {
226
+ echo $code . "\n"; /* No PHP allowed here. */
227
+ $paypal["s2member_log"][] = "Signup Tracking codes have been processed.";
228
+ }
229
+ else /* Otherwise, it's safe to allow PHP code. */
230
+ {
231
+ eval ("?>" . $code);
232
+ $paypal["s2member_log"][] = "Signup Tracking codes have been evaluated.";
233
+ }
234
  }
 
235
  /**/
236
+ echo '<!-- Tracking codes from the s2Member plugin for WordPress. -->' . "\n";
237
+ /**/
238
+ $paypal["s2member_log"][] = "Success! Redirecting Customer to Registration Page. They need to register a Username now.";
239
  /**/
240
  echo '</body>' . "\n";
241
  echo '</html>';
242
  }
243
  }
244
+ /*
245
+ Subscription modifications.
246
+ */
247
+ else if (preg_match ("/^subscr_modify$/i", $paypal["txn_type"]) && $paypal["subscr_id"] && preg_match ("/^[1-4](\:|$)/", $paypal["item_number"]))
248
  {
249
  $paypal["s2member_log"][] = "s2Member txn_type identified as subscr_modify.";
250
  /**/
251
+ list ($paypal["level"], $paypal["ccaps"]) = preg_split ("/\:/", $paypal["item_number"], 2);
252
+ /**/
253
  if ($q = $wpdb->get_row ("SELECT `user_id` FROM `" . $wpdb->usermeta . "` WHERE `meta_key` = 's2member_subscr_id' AND `meta_value` = '" . $wpdb->escape ($paypal["subscr_id"]) . "' LIMIT 1"))
254
  {
255
  if ($user_id = $q->user_id) /* Got it! */
256
  {
257
  $user = new WP_User ($user_id);
258
+ $user->set_role ("s2member_level" . $paypal["level"]);
259
+ update_usermeta ($user_id, "s2member_subscr_id", $paypal["subscr_id"]);
260
  update_usermeta ($user_id, "s2member_custom", $paypal["custom"]);
261
  /**/
262
+ foreach ($user->allcaps as $cap => $cap_enabled)
263
+ if (preg_match ("/^access_s2member_ccap_/", $cap))
264
+ $user->remove_cap ($ccap = $cap);
265
+ /**/
266
+ foreach (preg_split ("/[\r\n\t\s;,]+/", $paypal["ccaps"]) as $ccap)
267
+ if (strlen ($ccap)) /* Don't add empty capabilities. */
268
+ $user->add_cap ("access_s2member_ccap_" . trim (strtolower ($ccap)));
269
+ /**/
270
+ delete_usermeta ($user_id, "s2member_file_download_access_arc");
271
+ delete_usermeta ($user_id, "s2member_file_download_access_log");
272
+ /**/
273
+ $paypal["s2member_log"][] = "s2Member Level/Capabilities updated on subscription modification.";
274
  /**/
275
  echo '<script type="text/javascript">' . "\n";
276
  echo "alert('Thank You! Your membership has been updated to:\\n\\n" . esc_js ($paypal["item_name"]) . "\\n\\nYou\\'ll need to log back in now.');" . "\n";
277
  echo "window.location = '" . esc_js (wp_login_url ()) . "';";
278
  echo '</script>' . "\n";
279
  /**/
280
+ $paypal["s2member_log"][] = "Success! Redirecting Customer to the Login Page. They need to log back in after this modification.";
281
  }
282
  else
283
  {
284
+ $paypal["s2member_log"][] = "Unable to modify subscription. Could not get the existing user_id from the DB.";
285
  /**/
286
  echo '<script type="text/javascript">' . "\n";
287
+ echo "alert('ERROR: Unable to modify subscription. Please contact Support for assistance.\\n\\nCould not get the existing user_id from the DB.');" . "\n";
288
  echo "window.location = '" . esc_js (wp_login_url ()) . "';";
289
  echo '</script>' . "\n";
290
  /**/
291
+ $paypal["s2member_log"][] = "Redirecting Customer to the Login Page, due to an error that occurred.";
292
  }
293
  }
294
  else
295
  {
296
+ $paypal["s2member_log"][] = "Unable to modify subscription. Could not find existing subscription in the DB.";
297
  /**/
298
  echo '<script type="text/javascript">' . "\n";
299
+ echo "alert('ERROR: Unable to modify subscription. Please contact Support for assistance.\\n\\nCould not find existing subscription in the DB.');" . "\n";
300
  echo "window.location = '" . esc_js (wp_login_url ()) . "';";
301
  echo '</script>' . "\n";
302
  /**/
303
+ $paypal["s2member_log"][] = "Redirecting Customer to the Login Page, due to an error that occurred.";
304
  }
305
  }
306
  else
307
  {
308
+ $paypal["s2member_log"][] = "Unexpected txn_type. The PayPal® txn_type did not match a required action.";
309
  /**/
310
  echo '<script type="text/javascript">' . "\n";
311
+ echo "alert('ERROR: Unexpected txn_type. Please contact Support for assistance.\\n\\nThe PayPal® txn_type did not match a required action.');" . "\n";
312
  echo "window.location = '" . esc_js (wp_login_url ()) . "';";
313
  echo '</script>' . "\n";
314
  /**/
315
+ $paypal["s2member_log"][] = "Redirecting Customer to the Login Page, due to an error that occurred.";
316
  }
317
  }
318
  else
319
  {
320
+ $paypal["s2member_log"][] = "Unable to verify _SERVER[HTTP_HOST]. Please check the `custom` value in your Button Code. It MUST start with your domain name.";
321
  /**/
322
  echo '<script type="text/javascript">' . "\n";
323
+ echo "alert('ERROR: Unable to verify _SERVER[HTTP_HOST]. Please contact Support for assistance.\\n\\nIf you are the site owner, please check the `custom` value in your Button Code. It MUST start with your domain name.');" . "\n";
324
  echo "window.location = '" . esc_js (wp_login_url ()) . "';";
325
  echo '</script>' . "\n";
326
  /**/
327
+ $paypal["s2member_log"][] = "Redirecting Customer to the Login Page, due to an error that occurred.";
328
  }
329
  }
330
  else
331
  {
332
+ $paypal["s2member_log"][] = "Unable to verify POST vars. This is most likely related to an invalid PayPal® configuration. Please check: s2Member -> PayPal® Options -> PDT/Auto-Return.";
333
  /**/
334
  echo '<script type="text/javascript">' . "\n";
335
+ echo "alert('ERROR: Unable to verify POST vars. Please contact Support for assistance.\\n\\nThis is most likely related to an invalid PayPal® configuration. If you are the site owner, please check: s2Member -> PayPal® Options -> PDT/Auto-Return.');" . "\n";
336
  echo "window.location = '" . esc_js (wp_login_url ()) . "';";
337
  echo '</script>' . "\n";
338
  /**/
339
+ $paypal["s2member_log"][] = "Redirecting Customer to the Login Page, due to an error that occurred.";
340
  }
341
  /**/
342
  if ($_GET["s2member_paypal_proxy"]) /* For proxy identification. */
includes/functions/register-access.inc.php CHANGED
@@ -33,7 +33,7 @@ function ws_plugin__s2member_check_register_access ($users_can_register = FALSE)
33
  {
34
  return ($users_can_register = "1");
35
  }
36
- else if ($pagenow !== "options-general.php" && $_COOKIE["s2member_subscr_id"] && $_COOKIE["s2member_custom"] && preg_match ("/^[1-4]$/", $_COOKIE["s2member_level"]))
37
  {
38
  global $wpdb; /* Global database object reference. */
39
  /**/
@@ -117,28 +117,134 @@ function ws_plugin__s2member_custom_registration_fields ()
117
  return;
118
  }
119
  /*
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
120
  Function for configuring new users.
121
  Attach to: add_action("user_register");
122
  Attach to: add_action("bp_core_signup_user");
123
  */
124
  function ws_plugin__s2member_configure_user_registration ($user_id = FALSE)
125
  {
 
126
  static $processed; /* Prevents duplicate processing when attached to multiple hooks in support of plugins like BuddyPress. */
127
  /**/
128
  if (!$processed && $user_id && is_array ($_POST = stripslashes_deep ($_POST)) && is_object ($user = new WP_User ($user_id)) && ($processed = true))
129
  {
130
  ws_plugin__s2member_email_config (); /* Configures From: header that will be used in new user notifications. */
131
  /**/
132
- if ($_COOKIE["s2member_subscr_id"] && $_COOKIE["s2member_custom"] && preg_match ("/^[1-4]$/", $_COOKIE["s2member_level"]))
 
133
  {
134
- global $wpdb; /* Global database object required for this routine. We need to check the uniqueness of their s2member_subscr_id. */
135
  /**/
136
  if (!$usermeta = $wpdb->get_row ("SELECT `user_id` FROM `" . $wpdb->usermeta . "` WHERE `meta_key` = 's2member_subscr_id' AND `meta_value` = '" . $wpdb->escape ($_COOKIE["s2member_subscr_id"]) . "' LIMIT 1"))
137
  {
138
- $user->set_role ("s2member_level" . $_COOKIE["s2member_level"]);
 
 
 
 
 
139
  /**/
140
  update_usermeta ($user_id, "s2member_subscr_id", $_COOKIE["s2member_subscr_id"]);
141
  update_usermeta ($user_id, "s2member_custom", $_COOKIE["s2member_custom"]);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
142
  }
143
  /**/
144
  setcookie ("s2member_subscr_id", "", time () + 31556926, "/");
@@ -146,13 +252,100 @@ function ws_plugin__s2member_configure_user_registration ($user_id = FALSE)
146
  setcookie ("s2member_level", "", time () + 31556926, "/");
147
  }
148
  /**/
149
- if (!defined ("BP_VERSION")) /* Custom fields are not compatible when running together with BuddyPress. */
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
150
  {
151
- if ($first_name = trim ($_POST["ws_plugin__s2member_custom_reg_field_first_name"]))
152
  update_usermeta ($user_id, "first_name", $first_name) . /* And display name. */
153
  wp_update_user (array ("ID" => $user_id, "display_name" => $first_name));
154
  /**/
155
- if ($last_name = trim ($_POST["ws_plugin__s2member_custom_reg_field_last_name"]))
156
  update_usermeta ($user_id, "last_name", $last_name);
157
  /**/
158
  foreach (preg_split ("/[\r\n\t,;]+/", $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["custom_reg_fields"]) as $field)
@@ -160,7 +353,8 @@ function ws_plugin__s2member_configure_user_registration ($user_id = FALSE)
160
  if ($field = trim ($field, "* \t\n\r\0\x0B")) /* Don't process empty fields. */
161
  {
162
  $field = preg_replace ("/[^a-z0-9]/i", "_", strtolower ($field));
163
- $fields[$field] = trim ($_POST["ws_plugin__s2member_custom_reg_field_" . $field]);
 
164
  }
165
  }
166
  /**/
33
  {
34
  return ($users_can_register = "1");
35
  }
36
+ else if ($pagenow !== "options-general.php" && $_COOKIE["s2member_subscr_id"] && $_COOKIE["s2member_custom"] && preg_match ("/^[1-4](\:|$)/", $_COOKIE["s2member_level"]))
37
  {
38
  global $wpdb; /* Global database object reference. */
39
  /**/
117
  return;
118
  }
119
  /*
120
+ Generates registration links.
121
+ */
122
+ function ws_plugin__s2member_register_link_gen ($subscr_id = FALSE, $custom = FALSE, $item_number = FALSE, $shrink = TRUE)
123
+ {
124
+ if ($subscr_id && $custom && $item_number) /* Must have all of these. */
125
+ {
126
+ $register = ws_plugin__s2member_xencrypt ("subscr_id_custom_item_number:.:|:.:" . $subscr_id . ":.:|:.:" . $custom . ":.:|:.:" . $item_number);
127
+ $register_link = ws_plugin__s2member_append_query_var (get_bloginfo ("url") . "/", "s2member_register=" . urlencode ($register));
128
+ /**/
129
+ if ($shrink && ($tinyurl = @file_get_contents ("http://tinyurl.com/api-create.php?url=" . rawurlencode ($register_link))))
130
+ return $tinyurl; /* tinyURL is easier to work with, but fails if allow_url_fopen = no. */
131
+ else /* Else use the long one. */
132
+ return $register_link;
133
+ }
134
+ /**/
135
+ return false;
136
+ }
137
+ /*
138
+ Handles registration links.
139
+ Attach to: add_action("init");
140
+ $_GET["s2member_paypal_register"] deprecated in v2.8.6.
141
+ */
142
+ function ws_plugin__s2member_register ()
143
+ {
144
+ if ($_GET["s2member_register"] || ($_GET["s2member_register"] = $_GET["s2member_paypal_register"]))
145
+ {
146
+ if (is_array ($register = preg_split ("/\:\.\:\|\:\.\:/", ws_plugin__s2member_xdecrypt ($_GET["s2member_register"]))))
147
+ {
148
+ if (count ($register) === 4 && $register[0] === "subscr_id_custom_item_number" && $register[1] && $register[2] && $register[3])
149
+ {
150
+ setcookie ("s2member_subscr_id", $register[1], time () + 31556926, "/");
151
+ setcookie ("s2member_custom", $register[2], time () + 31556926, "/");
152
+ setcookie ("s2member_level", $register[3], time () + 31556926, "/");
153
+ /**/
154
+ echo '<script type="text/javascript">' . "\n";
155
+ echo "window.location = '" . esc_js (add_query_arg ("action", "register", wp_login_url ())) . "';";
156
+ echo '</script>' . "\n";
157
+ }
158
+ }
159
+ exit;
160
+ }
161
+ }
162
+ /*
163
  Function for configuring new users.
164
  Attach to: add_action("user_register");
165
  Attach to: add_action("bp_core_signup_user");
166
  */
167
  function ws_plugin__s2member_configure_user_registration ($user_id = FALSE)
168
  {
169
+ global $wpdb; /* Global database object may be required for this routine. */
170
  static $processed; /* Prevents duplicate processing when attached to multiple hooks in support of plugins like BuddyPress. */
171
  /**/
172
  if (!$processed && $user_id && is_array ($_POST = stripslashes_deep ($_POST)) && is_object ($user = new WP_User ($user_id)) && ($processed = true))
173
  {
174
  ws_plugin__s2member_email_config (); /* Configures From: header that will be used in new user notifications. */
175
  /**/
176
+ if (!is_admin () /* Only run this particular routine whenever a Member is registering themselves. */
177
+ && $_COOKIE["s2member_subscr_id"] && $_COOKIE["s2member_custom"] && preg_match ("/^[1-4](\:|$)/", $_COOKIE["s2member_level"]))
178
  {
179
+ list ($level, $ccaps) = preg_split ("/\:/", $_COOKIE["s2member_level"], 2); /* Supports colon separated level:custom_capability,custom_capability. */
180
  /**/
181
  if (!$usermeta = $wpdb->get_row ("SELECT `user_id` FROM `" . $wpdb->usermeta . "` WHERE `meta_key` = 's2member_subscr_id' AND `meta_value` = '" . $wpdb->escape ($_COOKIE["s2member_subscr_id"]) . "' LIMIT 1"))
182
  {
183
+ $user->set_role ("s2member_level" . $level);
184
+ /**/
185
+ if ($ccaps) /* Add custom capabilities. */
186
+ foreach (preg_split ("/[\r\n\t\s;,]+/", $ccaps) as $ccap)
187
+ if (strlen ($ccap)) /* Don't add empty capabilities. */
188
+ $user->add_cap ("access_s2member_ccap_" . trim (strtolower ($ccap)));
189
  /**/
190
  update_usermeta ($user_id, "s2member_subscr_id", $_COOKIE["s2member_subscr_id"]);
191
  update_usermeta ($user_id, "s2member_custom", $_COOKIE["s2member_custom"]);
192
+ /**/
193
+ if (($mailchimp_api_key = $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["mailchimp_api_key"]) && ($mailchimp_list_ids = $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["level" . $level . "_mailchimp_list_ids"]))
194
+ {
195
+ if (!class_exists ("NC_MCAPI"))
196
+ include_once dirname (dirname (__FILE__)) . "/mailchimp/nc-mcapi.inc.php";
197
+ /**/
198
+ $MCAPI = new NC_MCAPI ($mailchimp_api_key); /* MailChimp® API class. */
199
+ /**/
200
+ $email = $user->user_email;
201
+ $login = $user->user_login;
202
+ $fname = ($user->first_name) ? $user->first_name : trim ($_POST["ws_plugin__s2member_custom_reg_field_first_name"]);
203
+ $lname = ($user->last_name) ? $user->last_name : trim ($_POST["ws_plugin__s2member_custom_reg_field_last_name"]);
204
+ /**/
205
+ foreach (preg_split ("/[\r\n\t,;]+/", $mailchimp_list_ids) as $mailchimp_list_id)
206
+ $MCAPI->listSubscribe ($mailchimp_list_id, $email, array ("FNAME" => $fname, "LNAME" => $lname, "OPTINIP" => $_SERVER["REMOTE_ADDR"]));
207
+ }
208
+ /**/
209
+ if ($aweber_list_ids = $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["level" . $level . "_aweber_list_ids"])
210
+ {
211
+ $email = $user->user_email;
212
+ $login = $user->user_login;
213
+ $fname = ($user->first_name) ? $user->first_name : trim ($_POST["ws_plugin__s2member_custom_reg_field_first_name"]);
214
+ $lname = ($user->last_name) ? $user->last_name : trim ($_POST["ws_plugin__s2member_custom_reg_field_last_name"]);
215
+ /**/
216
+ foreach (preg_split ("/[\r\n\t,;]+/", $aweber_list_ids) as $aweber_list_id)
217
+ @mail ($aweber_list_id . "@aweber.com", "s2Member Subscription Request",/**/
218
+ "s2Member Subscription Request\ns2Member w/ PayPal Email ID\nBuyer: " . $fname . " " . $lname . "\n - end.",/**/
219
+ "From: \"" . preg_replace ("/\"/", "", $fname . " " . $lname) . "\" <" . $email . ">\r\nContent-Type: text/plain; charset=utf-8");
220
+ }
221
+ /**/
222
+ if ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["registration_notification_urls"])
223
+ {
224
+ $email = $user->user_email;
225
+ $login = $user->user_login;
226
+ $fname = ($user->first_name) ? $user->first_name : trim ($_POST["ws_plugin__s2member_custom_reg_field_first_name"]);
227
+ $lname = ($user->last_name) ? $user->last_name : trim ($_POST["ws_plugin__s2member_custom_reg_field_last_name"]);
228
+ /**/
229
+ if (function_exists ("ws_plugin__s2member_generate_password"))
230
+ if (!defined ("BP_VERSION") && $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["custom_reg_password"])
231
+ if (wp_verify_nonce (trim (stripslashes ($_POST["ws_plugin__s2member_registration"])), "ws-plugin--s2member-registration"))
232
+ if ($pass = trim (stripslashes ($_POST["ws_plugin__s2member_custom_reg_field_user_pass"])))
233
+ $pass = $pass;
234
+ /**/
235
+ if (is_array ($cv = preg_split ("/\|/", $_COOKIE["s2member_custom"])))
236
+ foreach (preg_split ("/[\r\n\t]+/", $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["registration_notification_urls"]) as $url)
237
+ if (($url = preg_replace ("/%%cv([0-9]+)%%/ei", 'urlencode(trim($cv[$1]))', $url)))
238
+ if (($url = preg_replace ("/%%level%%/i", urlencode ($level), $url)))
239
+ if (($url = preg_replace ("/%%user_first_name%%/i", urlencode ($fname), $url)))
240
+ if (($url = preg_replace ("/%%user_last_name%%/i", urlencode ($lname), $url)))
241
+ if (($url = preg_replace ("/%%user_full_name%%/i", urlencode (trim ($fname . " " . $lname)), $url)))
242
+ if (($url = preg_replace ("/%%user_email%%/i", urlencode ($email), $url)))
243
+ if (($url = preg_replace ("/%%user_login%%/i", urlencode ($login), $url)))
244
+ if (($url = preg_replace ("/%%user_pass%%/i", urlencode ($pass), $url)))
245
+ if (($url = trim ($url))) /* Make sure it is not empty now. */
246
+ ws_plugin__s2member_curlpsr ($url, "s2member=1");
247
+ }
248
  }
249
  /**/
250
  setcookie ("s2member_subscr_id", "", time () + 31556926, "/");
252
  setcookie ("s2member_level", "", time () + 31556926, "/");
253
  }
254
  /**/
255
+ else if (is_admin () && preg_match ("/wp-admin\/user-new\.php/", $_POST["_wp_http_referer"]) && preg_match ("/^(subscriber|s2member_level[1-4])$/", $_POST["role"]))
256
+ {
257
+ if ($_POST["role"] === "subscriber" && ($mailchimp_api_key = $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["mailchimp_api_key"]) && ($mailchimp_list_ids = $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["level0_mailchimp_list_ids"]))
258
+ {
259
+ if (!class_exists ("NC_MCAPI"))
260
+ include_once dirname (dirname (__FILE__)) . "/mailchimp/nc-mcapi.inc.php";
261
+ /**/
262
+ $MCAPI = new NC_MCAPI ($mailchimp_api_key); /* MailChimp® API class. */
263
+ /**/
264
+ $email = $user->user_email;
265
+ $login = $user->user_login;
266
+ $fname = ($user->first_name) ? $user->first_name : trim ($_POST["ws_plugin__s2member_custom_reg_field_first_name"]);
267
+ $lname = ($user->last_name) ? $user->last_name : trim ($_POST["ws_plugin__s2member_custom_reg_field_last_name"]);
268
+ /**/
269
+ foreach (preg_split ("/[\r\n\t,;]+/", $mailchimp_list_ids) as $mailchimp_list_id)
270
+ $MCAPI->listSubscribe ($mailchimp_list_id, $email, array ("FNAME" => $fname, "LNAME" => $lname, "OPTINIP" => ""));
271
+ }
272
+ /**/
273
+ else if (($level = preg_replace ("/[^1-4]/", "", $_POST["role"])) && ($mailchimp_api_key = $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["mailchimp_api_key"]) && ($mailchimp_list_ids = $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["level" . $level . "_mailchimp_list_ids"]))
274
+ {
275
+ if (!class_exists ("NC_MCAPI"))
276
+ include_once dirname (dirname (__FILE__)) . "/mailchimp/nc-mcapi.inc.php";
277
+ /**/
278
+ $MCAPI = new NC_MCAPI ($mailchimp_api_key); /* MailChimp® API class. */
279
+ /**/
280
+ $email = $user->user_email;
281
+ $login = $user->user_login;
282
+ $fname = ($user->first_name) ? $user->first_name : trim ($_POST["ws_plugin__s2member_custom_reg_field_first_name"]);
283
+ $lname = ($user->last_name) ? $user->last_name : trim ($_POST["ws_plugin__s2member_custom_reg_field_last_name"]);
284
+ /**/
285
+ foreach (preg_split ("/[\r\n\t,;]+/", $mailchimp_list_ids) as $mailchimp_list_id)
286
+ $MCAPI->listSubscribe ($mailchimp_list_id, $email, array ("FNAME" => $fname, "LNAME" => $lname, "OPTINIP" => ""));
287
+ }
288
+ /**/
289
+ if ($_POST["role"] === "subscriber" && ($aweber_list_ids = $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["level0_aweber_list_ids"]))
290
+ {
291
+ $email = $user->user_email;
292
+ $login = $user->user_login;
293
+ $fname = ($user->first_name) ? $user->first_name : trim ($_POST["ws_plugin__s2member_custom_reg_field_first_name"]);
294
+ $lname = ($user->last_name) ? $user->last_name : trim ($_POST["ws_plugin__s2member_custom_reg_field_last_name"]);
295
+ /**/
296
+ foreach (preg_split ("/[\r\n\t,;]+/", $aweber_list_ids) as $aweber_list_id)
297
+ @mail ($aweber_list_id . "@aweber.com", "s2Member Subscription Request",/**/
298
+ "s2Member Subscription Request\ns2Member w/ PayPal Email ID\nBuyer: " . $fname . " " . $lname . "\n - end.",/**/
299
+ "From: \"" . preg_replace ("/\"/", "", $fname . " " . $lname) . "\" <" . $email . ">\r\nContent-Type: text/plain; charset=utf-8");
300
+ }
301
+ /**/
302
+ else if (($level = preg_replace ("/[^1-4]/", "", $_POST["role"])) && ($aweber_list_ids = $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["level" . $level . "_aweber_list_ids"]))
303
+ {
304
+ $email = $user->user_email;
305
+ $login = $user->user_login;
306
+ $fname = ($user->first_name) ? $user->first_name : trim ($_POST["ws_plugin__s2member_custom_reg_field_first_name"]);
307
+ $lname = ($user->last_name) ? $user->last_name : trim ($_POST["ws_plugin__s2member_custom_reg_field_last_name"]);
308
+ /**/
309
+ foreach (preg_split ("/[\r\n\t,;]+/", $aweber_list_ids) as $aweber_list_id)
310
+ @mail ($aweber_list_id . "@aweber.com", "s2Member Subscription Request",/**/
311
+ "s2Member Subscription Request\ns2Member w/ PayPal Email ID\nBuyer: " . $fname . " " . $lname . "\n - end.",/**/
312
+ "From: \"" . preg_replace ("/\"/", "", $fname . " " . $lname) . "\" <" . $email . ">\r\nContent-Type: text/plain; charset=utf-8");
313
+ }
314
+ /**/
315
+ if (($_POST["role"] === "subscriber" || ($level = preg_replace ("/[^1-4]/", "", $_POST["role"])))/**/
316
+ && $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["registration_notification_urls"])
317
+ {
318
+ $email = $user->user_email;
319
+ $login = $user->user_login;
320
+ $level = ($_POST["role"] === "subscriber") ? "0" : $level;
321
+ $fname = ($user->first_name) ? $user->first_name : trim ($_POST["ws_plugin__s2member_custom_reg_field_first_name"]);
322
+ $lname = ($user->last_name) ? $user->last_name : trim ($_POST["ws_plugin__s2member_custom_reg_field_last_name"]);
323
+ /**/
324
+ if ($pass = trim (stripslashes ($_POST["pass1"])))
325
+ $pass = $pass; /* From the `Users -> Add New` form.
326
+ /**/
327
+ if (is_array ($cv = preg_split ("/\|/", $_COOKIE["s2member_custom"])))
328
+ foreach (preg_split ("/[\r\n\t]+/", $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["registration_notification_urls"]) as $url)
329
+ if (($url = preg_replace ("/%%cv([0-9]+)%%/ei", 'urlencode(trim($cv[$1]))', $url)))
330
+ if (($url = preg_replace ("/%%level%%/i", urlencode ($level), $url)))
331
+ if (($url = preg_replace ("/%%user_first_name%%/i", urlencode ($fname), $url)))
332
+ if (($url = preg_replace ("/%%user_last_name%%/i", urlencode ($lname), $url)))
333
+ if (($url = preg_replace ("/%%user_full_name%%/i", urlencode (trim ($fname . " " . $lname)), $url)))
334
+ if (($url = preg_replace ("/%%user_email%%/i", urlencode ($email), $url)))
335
+ if (($url = preg_replace ("/%%user_login%%/i", urlencode ($login), $url)))
336
+ if (($url = preg_replace ("/%%user_pass%%/i", urlencode ($pass), $url)))
337
+ if (($url = trim ($url))) /* Make sure it is not empty now. */
338
+ ws_plugin__s2member_curlpsr ($url, "s2member=1");
339
+ }
340
+ }
341
+ /**/
342
+ if (!is_admin () && !defined ("BP_VERSION")) /* This processes Custom Fields. */
343
  {
344
+ if (!$user->first_name && ($first_name = trim ($_POST["ws_plugin__s2member_custom_reg_field_first_name"])))
345
  update_usermeta ($user_id, "first_name", $first_name) . /* And display name. */
346
  wp_update_user (array ("ID" => $user_id, "display_name" => $first_name));
347
  /**/
348
+ if (!$user->last_name && ($last_name = trim ($_POST["ws_plugin__s2member_custom_reg_field_last_name"])))
349
  update_usermeta ($user_id, "last_name", $last_name);
350
  /**/
351
  foreach (preg_split ("/[\r\n\t,;]+/", $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["custom_reg_fields"]) as $field)
353
  if ($field = trim ($field, "* \t\n\r\0\x0B")) /* Don't process empty fields. */
354
  {
355
  $field = preg_replace ("/[^a-z0-9]/i", "_", strtolower ($field));
356
+ if (strlen ($_POST["ws_plugin__s2member_custom_reg_field_" . $field]))
357
+ $fields[$field] = trim ($_POST["ws_plugin__s2member_custom_reg_field_" . $field]);
358
  }
359
  }
360
  /**/
includes/functions/shortcodes.inc.php CHANGED
@@ -15,44 +15,85 @@ if (realpath (__FILE__) === realpath ($_SERVER["SCRIPT_FILENAME"]))
15
  exit;
16
  /*
17
  Function that handles the Shortcode for [s2Member-PayPal-Button /].
18
- [s2Member-PayPal-Button level="1" ps="paypal" cc="USD" on0="" os0="" modify="0" custom="www.domain.com" tp="0" tt="D" ra="0.01" rp="1" rt="M" rr="1" /]
 
 
 
 
 
 
 
 
 
 
19
  Attach to: add_shortcode("s2Member-PayPal-Button");
20
  */
21
  function ws_plugin__s2member_paypal_button ($attr = FALSE, $content = FALSE, $shortcode = FALSE)
22
  {
23
- $sc = shortcode_atts (array ("level" => "1", "ps" => "paypal", "cc" => "USD", "on0" => "", "os0" => "", "modify" => "0", "custom" => $_SERVER["HTTP_HOST"], "tp" => "0", "tt" => "D", "ra" => "0.01", "rp" => "1", "rt" => "M", "rr" => "1"), $attr);
24
- /**/
25
- $code = trim (file_get_contents (dirname (dirname (__FILE__)) . "/menu-pages/button.html"));
26
- $code = preg_replace ("/%%endpoint%%/", (($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["paypal_sandbox"]) ? "www.sandbox.paypal.com" : "www.paypal.com"), $code);
27
- $code = preg_replace ("/%%paypal_business%%/", $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["paypal_business"], $code);
28
- $code = preg_replace ("/%%level_label%%/", $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["level" . $sc["level"] . "_label"], $code);
29
- $code = preg_replace ("/%%cancel_return%%/", get_bloginfo ("url"), $code);
30
- $code = preg_replace ("/%%notify_url%%/", get_bloginfo ("url") . "/?s2member_paypal_notify=1", $code);
31
- $code = preg_replace ("/%%return%%/", get_bloginfo ("url") . "/?s2member_paypal_return=1", $code);
32
- $code = preg_replace ("/%%domain%%/", strtolower ($_SERVER["HTTP_HOST"]), $code);
33
- $code = preg_replace ("/%%level%%/", $sc["level"], $code);
34
  /**/
35
- $code = preg_replace ('/ \<\!--(\<input type\="hidden" name\="(amount|modify|src|sra|a1|p1|t1|a3|p3|t3)" value\="(.*?)" \/\>)--\>/', " $1", $code);
36
- $code = ($sc["on0"] || $sc["os0"]) ? preg_replace ('/ \<\!--(\<input type\="hidden" name\="(on0|os0)" value\="(.*?)" \/\>)--\>/', " $1", $code) : $code;
37
- $code = ($sc["tp"] <= 0) ? preg_replace ('/ (\<input type\="hidden" name\="(a1|p1|t1)" value\="(.*?)" \/\>)/', " <!--$1-->", $code) : $code;
38
- $code = ($sc["rt"] === "L") ? preg_replace ('/ (\<input type\="hidden" name\="cmd" value\=")(.*?)(" \/\>)/', " $1_xclick$3", $code) : $code;
39
- $code = ($sc["rt"] === "L") ? preg_replace ('/ (\<input type\="hidden" name\="(modify|src|sra|a1|p1|t1|a3|p3|t3)" value\="(.*?)" \/\>)/', " <!--$1-->", $code) : $code;
40
- $code = ($sc["rt"] !== "L") ? preg_replace ('/ (\<input type\="hidden" name\="cmd" value\=")(.*?)(" \/\>)/', " $1_xclick-subscriptions$3", $code) : $code;
41
- $code = ($sc["rt"] !== "L") ? preg_replace ('/ (\<input type\="hidden" name\="amount" value\="(.*?)" \/\>)/', " <!--$1-->", $code) : $code;
42
  /**/
43
- $code = preg_replace ('/ name\="page_style" value\="(.*?)"/', ' name="page_style" value="' . $sc["ps"] . '"', $code);
44
- $code = preg_replace ('/ name\="currency_code" value\="(.*?)"/', ' name="currency_code" value="' . $sc["cc"] . '"', $code);
45
- $code = preg_replace ('/ name\="on0" value\="(.*?)"/', ' name="on0" value="' . $sc["on0"] . '"', $code);
46
- $code = preg_replace ('/ name\="os0" value\="(.*?)"/', ' name="os0" value="' . $sc["os0"] . '"', $code);
47
- $code = preg_replace ('/ name\="modify" value\="(.*?)"/', ' name="modify" value="' . $sc["modify"] . '"', $code);
48
- $code = preg_replace ('/ name\="custom" value\="(.*?)"/', ' name="custom" value="' . $sc["custom"] . '"', $code);
49
- $code = preg_replace ('/ name\="amount" value\="(.*?)"/', ' name="amount" value="' . $sc["ra"] . '"', $code);
50
- $code = preg_replace ('/ name\="src" value\="(.*?)"/', ' name="src" value="' . $sc["rr"] . '"', $code);
51
- $code = preg_replace ('/ name\="p1" value\="(.*?)"/', ' name="p1" value="' . $sc["tp"] . '"', $code);
52
- $code = preg_replace ('/ name\="t1" value\="(.*?)"/', ' name="t1" value="' . $sc["tt"] . '"', $code);
53
- $code = preg_replace ('/ name\="a3" value\="(.*?)"/', ' name="a3" value="' . $sc["ra"] . '"', $code);
54
- $code = preg_replace ('/ name\="p3" value\="(.*?)"/', ' name="p3" value="' . $sc["rp"] . '"', $code);
55
- $code = preg_replace ('/ name\="t3" value\="(.*?)"/', ' name="t3" value="' . $sc["rt"] . '"', $code);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
56
  /**/
57
  return $code; /* The finished PayPal® Button. */
58
  }
15
  exit;
16
  /*
17
  Function that handles the Shortcode for [s2Member-PayPal-Button /].
18
+
19
+ [s2Member-PayPal-Button level="1" ccaps="" desc="" ps="paypal" cc="USD" custom="www.domain.com" tp="0" tt="D" ra="0.01" rp="1" rt="M" rr="1" /]
20
+ [s2Member-PayPal-Button page="0" desc="Single-Page Access" ps="paypal" cc="USD" custom="www.domain.com" ra="0.01" sp="1" /]
21
+
22
+ The desc attribute is only required for Single-Page buttons, optional for others.
23
+ The page attribute is only used for Single-Page buttons.
24
+
25
+ PayPal® Modification Buttons are identified by mb="1".
26
+ PayPal® Cancellation Buttons are identified by cb="1".
27
+ PayPal® Single-Page Buttons are identified by sp="1".
28
+
29
  Attach to: add_shortcode("s2Member-PayPal-Button");
30
  */
31
  function ws_plugin__s2member_paypal_button ($attr = FALSE, $content = FALSE, $shortcode = FALSE)
32
  {
33
+ $sc = shortcode_atts (array ("page" => "0", "level" => "1", "ccaps" => "", "desc" => "", "ps" => "paypal", "cc" => "USD", "custom" => $_SERVER["HTTP_HOST"], "tp" => "0", "tt" => "D", "ra" => "0.01", "rp" => "1", "rt" => "M", "rr" => "1", "mb" => "0", "cb" => "0", "sp" => "0"), $attr);
 
 
 
 
 
 
 
 
 
 
34
  /**/
35
+ if ($sc["cb"]) /* This is a special routine for Cancellation Buttons. Cancellation Buttons use a different template. */
36
+ {
37
+ $code = trim (file_get_contents (dirname (dirname (__FILE__)) . "/menu-pages/c-button.html"));
38
+ $code = preg_replace ("/%%endpoint%%/", (($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["paypal_sandbox"]) ? "www.sandbox.paypal.com" : "www.paypal.com"), $code);
39
+ $code = preg_replace ("/%%paypal_business%%/", $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["paypal_business"], $code);
40
+ }
 
41
  /**/
42
+ else if ($sc["sp"]) /* This is a special routine for Single-Page Buttons. Single-Page Buttons use a different template. */
43
+ {
44
+ $code = trim (file_get_contents (dirname (dirname (__FILE__)) . "/menu-pages/sp-button.html"));
45
+ $code = preg_replace ("/%%endpoint%%/", (($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["paypal_sandbox"]) ? "www.sandbox.paypal.com" : "www.paypal.com"), $code);
46
+ $code = preg_replace ("/%%paypal_business%%/", $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["paypal_business"], $code);
47
+ $code = preg_replace ("/%%cancel_return%%/", get_bloginfo ("url"), $code);
48
+ $code = preg_replace ("/%%notify_url%%/", get_bloginfo ("url") . "/?s2member_paypal_notify=1", $code);
49
+ $code = preg_replace ("/%%return%%/", get_bloginfo ("url") . "/?s2member_paypal_return=1", $code);
50
+ $code = preg_replace ("/%%domain%%/", strtolower ($_SERVER["HTTP_HOST"]), $code);
51
+ /**/
52
+ $code = preg_replace ('/ name\="item_name" value\="(.*?)"/', ' name="item_name" value="' . $sc["desc"] . '"', $code);
53
+ $code = preg_replace ('/ name\="item_number" value\="(.*?)"/', ' name="item_number" value="sp:' . $sc["page"] . '"', $code);
54
+ $code = preg_replace ('/ name\="page_style" value\="(.*?)"/', ' name="page_style" value="' . $sc["ps"] . '"', $code);
55
+ $code = preg_replace ('/ name\="currency_code" value\="(.*?)"/', ' name="currency_code" value="' . $sc["cc"] . '"', $code);
56
+ $code = preg_replace ('/ name\="custom" value\="(.*?)"/', ' name="custom" value="' . $sc["custom"] . '"', $code);
57
+ $code = preg_replace ('/ name\="amount" value\="(.*?)"/', ' name="amount" value="' . $sc["ra"] . '"', $code);
58
+ }
59
+ else /* Otherwise, we'll process this Button normally, using the Membership routines. Also handles Modification Buttons. */
60
+ {
61
+ $sc["desc"] = (!$sc["desc"]) ? $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["level" . $sc["level"] . "_label"] : $sc["desc"];
62
+ $sc["level_ccaps"] = ($sc["ccaps"]) ? $sc["level"] . ":" . $sc["ccaps"] : $sc["level"];
63
+ /**/
64
+ $code = trim (file_get_contents (dirname (dirname (__FILE__)) . "/menu-pages/button.html"));
65
+ $code = preg_replace ("/%%endpoint%%/", (($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["paypal_sandbox"]) ? "www.sandbox.paypal.com" : "www.paypal.com"), $code);
66
+ $code = preg_replace ("/%%paypal_business%%/", $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["paypal_business"], $code);
67
+ $code = preg_replace ("/%%level_label%%/", $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["level" . $sc["level"] . "_label"], $code);
68
+ $code = preg_replace ("/%%cancel_return%%/", get_bloginfo ("url"), $code);
69
+ $code = preg_replace ("/%%notify_url%%/", get_bloginfo ("url") . "/?s2member_paypal_notify=1", $code);
70
+ $code = preg_replace ("/%%return%%/", get_bloginfo ("url") . "/?s2member_paypal_return=1", $code);
71
+ $code = preg_replace ("/%%domain%%/", strtolower ($_SERVER["HTTP_HOST"]), $code);
72
+ $code = preg_replace ("/%%level%%/", $sc["level"], $code);
73
+ /**/
74
+ $code = preg_replace ('/ \<\!--(\<input type\="hidden" name\="(amount|src|sra|a1|p1|t1|a3|p3|t3)" value\="(.*?)" \/\>)--\>/', " $1", $code);
75
+ $code = ($sc["tp"] <= 0) ? preg_replace ('/ (\<input type\="hidden" name\="(a1|p1|t1)" value\="(.*?)" \/\>)/', " <!--$1-->", $code) : $code;
76
+ $code = ($sc["rt"] === "L") ? preg_replace ('/ (\<input type\="hidden" name\="cmd" value\=")(.*?)(" \/\>)/', " $1_xclick$3", $code) : $code;
77
+ $code = ($sc["rt"] === "L") ? preg_replace ('/ (\<input type\="hidden" name\="(src|sra|a1|p1|t1|a3|p3|t3)" value\="(.*?)" \/\>)/', " <!--$1-->", $code) : $code;
78
+ $code = ($sc["rt"] !== "L") ? preg_replace ('/ (\<input type\="hidden" name\="cmd" value\=")(.*?)(" \/\>)/', " $1_xclick-subscriptions$3", $code) : $code;
79
+ $code = ($sc["rt"] !== "L") ? preg_replace ('/ (\<input type\="hidden" name\="amount" value\="(.*?)" \/\>)/', " <!--$1-->", $code) : $code;
80
+ /**/
81
+ $code = preg_replace ('/ name\="item_name" value\="(.*?)"/', ' name="item_name" value="' . $sc["desc"] . '"', $code);
82
+ $code = preg_replace ('/ name\="item_number" value\="(.*?)"/', ' name="item_number" value="' . $sc["level_ccaps"] . '"', $code);
83
+ $code = preg_replace ('/ name\="page_style" value\="(.*?)"/', ' name="page_style" value="' . $sc["ps"] . '"', $code);
84
+ $code = preg_replace ('/ name\="currency_code" value\="(.*?)"/', ' name="currency_code" value="' . $sc["cc"] . '"', $code);
85
+ $code = preg_replace ('/ name\="custom" value\="(.*?)"/', ' name="custom" value="' . $sc["custom"] . '"', $code);
86
+ $code = preg_replace ('/ name\="on0" value\="(.*?)"/', ' name="on0" value="' . S2MEMBER_CURRENT_USER_VALUE_FOR_PP_ON0 . '"', $code);
87
+ $code = preg_replace ('/ name\="os0" value\="(.*?)"/', ' name="os0" value="' . S2MEMBER_CURRENT_USER_VALUE_FOR_PP_OS0 . '"', $code);
88
+ $code = preg_replace ('/ name\="modify" value\="(.*?)"/', ' name="modify" value="1"', $code);
89
+ $code = preg_replace ('/ name\="amount" value\="(.*?)"/', ' name="amount" value="' . $sc["ra"] . '"', $code);
90
+ $code = preg_replace ('/ name\="src" value\="(.*?)"/', ' name="src" value="' . $sc["rr"] . '"', $code);
91
+ $code = preg_replace ('/ name\="p1" value\="(.*?)"/', ' name="p1" value="' . $sc["tp"] . '"', $code);
92
+ $code = preg_replace ('/ name\="t1" value\="(.*?)"/', ' name="t1" value="' . $sc["tt"] . '"', $code);
93
+ $code = preg_replace ('/ name\="a3" value\="(.*?)"/', ' name="a3" value="' . $sc["ra"] . '"', $code);
94
+ $code = preg_replace ('/ name\="p3" value\="(.*?)"/', ' name="p3" value="' . $sc["rp"] . '"', $code);
95
+ $code = preg_replace ('/ name\="t3" value\="(.*?)"/', ' name="t3" value="' . $sc["rt"] . '"', $code);
96
+ }
97
  /**/
98
  return $code; /* The finished PayPal® Button. */
99
  }
includes/functions/sp-access.inc.php ADDED
@@ -0,0 +1,73 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /*
3
+ Copyright: © 2009 WebSharks, Inc. ( coded in the USA )
4
+ <mailto:support@websharks-inc.com> <http://www.websharks-inc.com/>
5
+
6
+ Released under the terms of the GNU General Public License.
7
+ You should have received a copy of the GNU General Public License,
8
+ along with this software. In the main directory, see: /licensing/
9
+ If not, see: <http://www.gnu.org/licenses/>.
10
+ */
11
+ /*
12
+ Direct access denial.
13
+ */
14
+ if (realpath (__FILE__) === realpath ($_SERVER["SCRIPT_FILENAME"]))
15
+ exit;
16
+ /*
17
+ Generates Single-Page Access links.
18
+ */
19
+ function ws_plugin__s2member_sp_access_link_gen ($page_ID = FALSE, $shrink = TRUE)
20
+ {
21
+ if ($page_ID) /* Must have a page ID in order to create an access link. */
22
+ {
23
+ $sp_access = ws_plugin__s2member_xencrypt ("sp:.:|:.:" . $page_ID . ":.:|:.:" . strtotime ("now"));
24
+ $sp_access_link = ws_plugin__s2member_append_query_var (get_page_link ($page_ID), "s2member_sp_access=" . urlencode ($sp_access));
25
+ /**/
26
+ if ($shrink && ($tinyurl = @file_get_contents ("http://tinyurl.com/api-create.php?url=" . rawurlencode ($sp_access_link))))
27
+ return $tinyurl; /* tinyURL is easier to work with, but fails if allow_url_fopen = no. */
28
+ else /* Else use the long one. */
29
+ return $sp_access_link;
30
+ }
31
+ /**/
32
+ return false;
33
+ }
34
+ /*
35
+ Generates Single-Page Access links via ajax tools.
36
+ Attach to: add_action("wp_ajax_s2member_sp_access_link");
37
+ */
38
+ function ws_plugin__s2member_sp_access_link ()
39
+ {
40
+ if (current_user_can ("edit_plugins")) /* Check priveledges as well. */
41
+ if (($nonce = $_POST["s2member_sp_access_link"]) && wp_verify_nonce ($nonce, "ws-plugin--s2member-sp-access-link"))
42
+ echo ws_plugin__s2member_sp_access_link_gen ($_POST["s2member_sp_access_link_page"]);
43
+ /**/
44
+ exit;
45
+ }
46
+ /*
47
+ Handles Single-Page Access authentication.
48
+ */
49
+ function ws_plugin__s2member_sp_access ($page_ID = FALSE)
50
+ {
51
+ if (current_user_can ("edit_posts"))
52
+ return true; /* Edit access. */
53
+ /**/
54
+ else if ($_GET["s2member_sp_access"] && $page_ID)
55
+ {
56
+ if (is_array ($sp_access = preg_split ("/\:\.\:\|\:\.\:/", ws_plugin__s2member_xdecrypt ($_GET["s2member_sp_access"]))))
57
+ {
58
+ if (count ($sp_access) === 3 && $sp_access[0] === "sp" && $sp_access[1] == $page_ID && $sp_access[2] >= strtotime ("-72 hours"))
59
+ {
60
+ if ($sp_access[2] <= strtotime ("now")) /* Prevent arbitrarily long times from hacking in. */
61
+ return true; /* Looks good! Single-Page Access granted. */
62
+ }
63
+ }
64
+ /**/
65
+ echo '<strong>Your Link Expired:</strong><br />Please contact Support if you need assistance.';
66
+ /**/
67
+ exit; /* $_GET["s2member_sp_access"] has expired, or is invalid. */
68
+ }
69
+ /**/
70
+ else /* No access. */
71
+ return false;
72
+ }
73
+ ?>
includes/functions/user-deletions.inc.php CHANGED
@@ -19,18 +19,19 @@ Attach to: add_action("delete_user");
19
  */
20
  function ws_plugin__s2member_handle_user_deletions ($user_id = FALSE)
21
  {
22
- $userdata = get_userdata ($user_id);
23
  $paypal["custom"] = get_usermeta ($user_id, "s2member_custom");
24
  $paypal["subscr_id"] = get_usermeta ($user_id, "s2member_subscr_id");
25
  /**/
26
- if ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["eot_del_notification_urls"] && is_object ($userdata) && $paypal["subscr_id"] && $paypal["custom"] && is_array ($cv = preg_split ("/\|/", $paypal["custom"])))
27
  {
28
  foreach (preg_split ("/[\r\n\t]+/", $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["eot_del_notification_urls"]) as $url) /* Handle eot notifications on user deletion. */
29
  if (($url = preg_replace ("/%%cv([0-9]+)%%/ei", 'urlencode(trim($cv[$1]))', $url)) && ($url = preg_replace ("/%%subscr_id%%/i", urlencode ($paypal["subscr_id"]), $url)))
30
- if (($url = preg_replace ("/%%user_first_name%%/i", urlencode ($userdata->first_name), $url)) && ($url = preg_replace ("/%%user_last_name%%/i", urlencode ($userdata->last_name), $url)))
31
- if (($url = preg_replace ("/%%user_full_name%%/i", urlencode (trim ($userdata->first_name . " " . $userdata->last_name)), $url)))
32
- if (($url = preg_replace ("/%%user_email%%/i", urlencode ($userdata->user_email), $url)))
33
- if (($url = trim ($url))) /* Make sure it is not empty now. */
 
34
  ws_plugin__s2member_curlpsr ($url, "s2member=1");
35
  }
36
  /**/
19
  */
20
  function ws_plugin__s2member_handle_user_deletions ($user_id = FALSE)
21
  {
22
+ $user = new WP_User ($user_id);
23
  $paypal["custom"] = get_usermeta ($user_id, "s2member_custom");
24
  $paypal["subscr_id"] = get_usermeta ($user_id, "s2member_subscr_id");
25
  /**/
26
+ if ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["eot_del_notification_urls"] && is_object ($user) && $paypal["subscr_id"] && $paypal["custom"] && is_array ($cv = preg_split ("/\|/", $paypal["custom"])))
27
  {
28
  foreach (preg_split ("/[\r\n\t]+/", $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["eot_del_notification_urls"]) as $url) /* Handle eot notifications on user deletion. */
29
  if (($url = preg_replace ("/%%cv([0-9]+)%%/ei", 'urlencode(trim($cv[$1]))', $url)) && ($url = preg_replace ("/%%subscr_id%%/i", urlencode ($paypal["subscr_id"]), $url)))
30
+ if (($url = preg_replace ("/%%user_first_name%%/i", urlencode ($user->first_name), $url)) && ($url = preg_replace ("/%%user_last_name%%/i", urlencode ($user->last_name), $url)))
31
+ if (($url = preg_replace ("/%%user_full_name%%/i", urlencode (trim ($user->first_name . " " . $user->last_name)), $url)))
32
+ if (($url = preg_replace ("/%%user_email%%/i", urlencode ($user->user_email), $url)))
33
+ /**/
34
+ if (($url = trim ($url))) /* Make sure it is not empty. */
35
  ws_plugin__s2member_curlpsr ($url, "s2member=1");
36
  }
37
  /**/
includes/functions/users-list.inc.php CHANGED
@@ -21,6 +21,7 @@ function ws_plugin__s2member_users_list_cols ($cols = FALSE)
21
  {
22
  $cols["s2member_registration_time"] = "Registered On"; /* Date they signed up. */
23
  $cols["s2member_subscr_id"] = "PayPal® Subscr. ID"; /* Special field that is always applied. */
 
24
  /**/
25
  if (!defined ("BP_VERSION")) /* Custom fields are not compatible when running together with BuddyPress. */
26
  {
@@ -42,18 +43,28 @@ Attach to: add_filter ("manage_users_custom_column");
42
  function ws_plugin__s2member_users_list_display_cols ($_ = FALSE, $col = FALSE, $user_id = FALSE)
43
  {
44
  global $user_object; /* The user_row() function already has this. */
 
45
  static $fields, $fields_4_user_id; /* Used to conserve resources. */
46
  /**/
47
  if ((!isset ($fields) || $fields_4_user_id !== $user_id) && ($fields_4_user_id = $user_id))
48
  $fields = get_usermeta ($user_id, "s2member_custom_fields");
49
  /**/
50
  if ($col === "s2member_registration_time")
51
- return ($r = $user_object->user_registered) ? /* Displays date & time ( 2 lines ). */
52
  date ("D M j, Y", strtotime ($r)) . '<br />@exactly ' . date ("g:i a", strtotime ($r)) : "—";
53
  /**/
54
  else if ($col === "s2member_subscr_id")
55
  return ($r = get_usermeta ($user_id, "s2member_subscr_id")) ? esc_html ($r) : "—";
56
  /**/
 
 
 
 
 
 
 
 
 
57
  if ($fields[$col] && preg_match ("/^http(s?)\:/i", $fields[$col]))
58
  return '<a href="' . esc_attr ($fields[$col]) . '" target="_blank">' . esc_html (substr ($fields[$col], strpos ($fields[$col], ":") + 3, 25) . "...") . '</a>';
59
  /**/
@@ -68,15 +79,26 @@ function ws_plugin__s2member_users_list_edit_cols ($user = FALSE)
68
  {
69
  if (current_user_can ("edit_users")) /* Security check. */
70
  {
71
- echo '<h3>s2Member Profile Fields</h3>' . "\n";
 
 
72
  /**/
73
  echo '<table class="form-table">' . "\n";
74
  /**/
75
  echo '<tr>' . "\n";
76
- echo '<th><label>PayPal® Subscr. ID </label></th>' . "\n";
77
  echo '<td><input type="text" name="ws_plugin__s2member_profile_s2member_subscr_id" value="' . esc_attr (get_usermeta ($user->ID, "s2member_subscr_id")) . '" class="regular-text" /></td>' . "\n";
78
  echo '</tr>' . "\n";
79
  /**/
 
 
 
 
 
 
 
 
 
80
  if (!defined ("BP_VERSION")) /* Custom fields are not compatible when running together with BuddyPress. */
81
  {
82
  $fields = get_usermeta ($user->ID, "s2member_custom_fields");
@@ -95,6 +117,8 @@ function ws_plugin__s2member_users_list_edit_cols ($user = FALSE)
95
  }
96
  /**/
97
  echo '</table>' . "\n";
 
 
98
  }
99
  }
100
  /*
@@ -108,8 +132,17 @@ function ws_plugin__s2member_users_list_update_cols ($user_id = FALSE)
108
  {
109
  if (is_array ($_POST = stripslashes_deep ($_POST)) && !empty ($_POST))
110
  {
 
111
  update_usermeta ($user_id, "s2member_subscr_id", $_POST["ws_plugin__s2member_profile_s2member_subscr_id"]);
112
  /**/
 
 
 
 
 
 
 
 
113
  if (!defined ("BP_VERSION")) /* Custom fields are not compatible when running together with BuddyPress. */
114
  {
115
  foreach (preg_split ("/[\r\n\t,;]+/", $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["custom_reg_fields"]) as $field)
21
  {
22
  $cols["s2member_registration_time"] = "Registered On"; /* Date they signed up. */
23
  $cols["s2member_subscr_id"] = "PayPal® Subscr. ID"; /* Special field that is always applied. */
24
+ $cols["s2member_ccaps"] = "Custom Capabilities"; /* Special field that is always applied. */
25
  /**/
26
  if (!defined ("BP_VERSION")) /* Custom fields are not compatible when running together with BuddyPress. */
27
  {
43
  function ws_plugin__s2member_users_list_display_cols ($_ = FALSE, $col = FALSE, $user_id = FALSE)
44
  {
45
  global $user_object; /* The user_row() function already has this. */
46
+ $user = $user_object; /* Shorter reference to the user_object var. */
47
  static $fields, $fields_4_user_id; /* Used to conserve resources. */
48
  /**/
49
  if ((!isset ($fields) || $fields_4_user_id !== $user_id) && ($fields_4_user_id = $user_id))
50
  $fields = get_usermeta ($user_id, "s2member_custom_fields");
51
  /**/
52
  if ($col === "s2member_registration_time")
53
+ return ($r = $user->user_registered) ? /* Displays date & time ( 2 lines ). */
54
  date ("D M j, Y", strtotime ($r)) . '<br />@exactly ' . date ("g:i a", strtotime ($r)) : "—";
55
  /**/
56
  else if ($col === "s2member_subscr_id")
57
  return ($r = get_usermeta ($user_id, "s2member_subscr_id")) ? esc_html ($r) : "—";
58
  /**/
59
+ else if ($col === "s2member_ccaps") /* Custom Capabilities. */
60
+ {
61
+ foreach ($user->allcaps as $cap => $cap_enabled)
62
+ if (preg_match ("/^access_s2member_ccap_/", $cap))
63
+ $ccaps[] = preg_replace ("/^access_s2member_ccap_/", "", $cap);
64
+ /**/
65
+ return (!empty ($ccaps)) ? implode ("<br />", $ccaps) : "—";
66
+ }
67
+ /**/
68
  if ($fields[$col] && preg_match ("/^http(s?)\:/i", $fields[$col]))
69
  return '<a href="' . esc_attr ($fields[$col]) . '" target="_blank">' . esc_html (substr ($fields[$col], strpos ($fields[$col], ":") + 3, 25) . "...") . '</a>';
70
  /**/
79
  {
80
  if (current_user_can ("edit_users")) /* Security check. */
81
  {
82
+ echo '<div style="margin:25px 0 25px 0; height:1px; line-height:1px; background:#CCCCCC;"></div>' . "\n";
83
+ /**/
84
+ echo '<h3>s2Member Configuration &amp; Profile Fields</h3>' . "\n";
85
  /**/
86
  echo '<table class="form-table">' . "\n";
87
  /**/
88
  echo '<tr>' . "\n";
89
+ echo '<th><label>PayPal® Subscr. ID</label> <a href="#" onclick="alert(\'This will be filled automatically by s2Member, as needed.\\n\\nA PayPal® Subscr ID is only valid for paid Members. This field will always be empty for Free Subscribers, Administrators, Contributors, and Authors. This field is only editable for Customer Service purposes; just in case you ever need to update the PayPal® Subscr ID manually. You are not likely to need this, but s2Member makes it editable, just in case.\'); return false;">[?]</a></th>' . "\n";
90
  echo '<td><input type="text" name="ws_plugin__s2member_profile_s2member_subscr_id" value="' . esc_attr (get_usermeta ($user->ID, "s2member_subscr_id")) . '" class="regular-text" /></td>' . "\n";
91
  echo '</tr>' . "\n";
92
  /**/
93
+ foreach ($user->allcaps as $cap => $cap_enabled)
94
+ if (preg_match ("/^access_s2member_ccap_/", $cap))
95
+ $ccaps[] = preg_replace ("/^access_s2member_ccap_/", "", $cap);
96
+ /**/
97
+ echo '<tr>' . "\n";
98
+ echo '<th><label>Custom Capabilities</label> <a href="#" onclick="alert(\'Optional. This is VERY advanced. For full details, see:\\ns2Member -> API Scripting -> Custom Capabilities.\'); return false;">[?]</a></th>' . "\n";
99
+ echo '<td><input type="text" name="ws_plugin__s2member_profile_s2member_ccaps" value="' . esc_attr (((!empty ($ccaps)) ? implode (",", $ccaps) : "")) . '" class="regular-text" onkeyup="this.value = jQuery.trim (jQuery.trim (this.value).replace (/[ \-]/g, \'_\').replace (/[^A-Z_0-9,]/gi, \'\').toLowerCase ());"; /></td>' . "\n";
100
+ echo '</tr>' . "\n";
101
+ /**/
102
  if (!defined ("BP_VERSION")) /* Custom fields are not compatible when running together with BuddyPress. */
103
  {
104
  $fields = get_usermeta ($user->ID, "s2member_custom_fields");
117
  }
118
  /**/
119
  echo '</table>' . "\n";
120
+ /**/
121
+ echo '<div style="margin:25px 0 25px 0; height:1px; line-height:1px; background:#CCCCCC;"></div>' . "\n";
122
  }
123
  }
124
  /*
132
  {
133
  if (is_array ($_POST = stripslashes_deep ($_POST)) && !empty ($_POST))
134
  {
135
+ $user = new WP_User ($user_id);
136
  update_usermeta ($user_id, "s2member_subscr_id", $_POST["ws_plugin__s2member_profile_s2member_subscr_id"]);
137
  /**/
138
+ foreach ($user->allcaps as $cap => $cap_enabled)
139
+ if (preg_match ("/^access_s2member_ccap_/", $cap))
140
+ $user->remove_cap ($ccap = $cap);
141
+ /**/
142
+ foreach (preg_split ("/[\r\n\t\s;,]+/", $_POST["ws_plugin__s2member_profile_s2member_ccaps"]) as $ccap)
143
+ if (strlen ($ccap)) /* Don't add empty capabilities. */
144
+ $user->add_cap ("access_s2member_ccap_" . trim (strtolower ($ccap)));
145
+ /**/
146
  if (!defined ("BP_VERSION")) /* Custom fields are not compatible when running together with BuddyPress. */
147
  {
148
  foreach (preg_split ("/[\r\n\t,;]+/", $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["custom_reg_fields"]) as $field)
includes/functions/utilities.inc.php CHANGED
@@ -99,29 +99,29 @@ Curl operation for posting data and reading response.
99
  */
100
  function ws_plugin__s2member_curlpsr ($url = FALSE, $vars = FALSE)
101
  {
102
- if ($url && ($connection = curl_init ()))
103
  {
104
- curl_setopt ($connection, CURLOPT_URL, $url);
105
- curl_setopt ($connection, CURLOPT_POST, true);
106
- curl_setopt ($connection, CURLOPT_TIMEOUT, 20);
107
- curl_setopt ($connection, CURLOPT_CONNECTTIMEOUT, 20);
108
- curl_setopt ($connection, CURLOPT_FOLLOWLOCATION, false);
109
- curl_setopt ($connection, CURLOPT_MAXREDIRS, 0);
110
- curl_setopt ($connection, CURLOPT_HEADER, false);
111
- curl_setopt ($connection, CURLOPT_VERBOSE, true);
112
- curl_setopt ($connection, CURLOPT_ENCODING, "");
113
- curl_setopt ($connection, CURLOPT_SSL_VERIFYPEER, false);
114
- curl_setopt ($connection, CURLOPT_RETURNTRANSFER, true);
115
- curl_setopt ($connection, CURLOPT_FORBID_REUSE, true);
116
- curl_setopt ($connection, CURLOPT_FAILONERROR, true);
117
- curl_setopt ($connection, CURLOPT_POSTFIELDS, $vars);
118
  /**/
119
- $output = trim (curl_exec ($connection));
120
  /**/
121
- curl_close ($connection);
122
  }
123
  /**/
124
- return (strlen ($output)) ? $output : false;
125
  }
126
  /*
127
  Base32 encode ( base32 is case insensitive ).
@@ -197,4 +197,11 @@ function s2member_xdecrypt ($string = FALSE, $key = FALSE)
197
  {
198
  return ws_plugin__s2member_xdecrypt ($string, $key);
199
  }
 
 
 
 
 
 
 
200
  ?>
99
  */
100
  function ws_plugin__s2member_curlpsr ($url = FALSE, $vars = FALSE)
101
  {
102
+ if ($url && ($c = curl_init ()))
103
  {
104
+ curl_setopt ($c, CURLOPT_URL, $url);
105
+ curl_setopt ($c, CURLOPT_POST, true);
106
+ curl_setopt ($c, CURLOPT_TIMEOUT, 20);
107
+ curl_setopt ($c, CURLOPT_CONNECTTIMEOUT, 20);
108
+ curl_setopt ($c, CURLOPT_FOLLOWLOCATION, false);
109
+ curl_setopt ($c, CURLOPT_MAXREDIRS, 0);
110
+ curl_setopt ($c, CURLOPT_HEADER, false);
111
+ curl_setopt ($c, CURLOPT_VERBOSE, true);
112
+ curl_setopt ($c, CURLOPT_ENCODING, "");
113
+ curl_setopt ($c, CURLOPT_SSL_VERIFYPEER, false);
114
+ curl_setopt ($c, CURLOPT_RETURNTRANSFER, true);
115
+ curl_setopt ($c, CURLOPT_FORBID_REUSE, true);
116
+ curl_setopt ($c, CURLOPT_FAILONERROR, true);
117
+ curl_setopt ($c, CURLOPT_POSTFIELDS, $vars);
118
  /**/
119
+ $o = trim (curl_exec ($c));
120
  /**/
121
+ curl_close ($c);
122
  }
123
  /**/
124
+ return (strlen ($o)) ? $o : false;
125
  }
126
  /*
127
  Base32 encode ( base32 is case insensitive ).
197
  {
198
  return ws_plugin__s2member_xdecrypt ($string, $key);
199
  }
200
+ /*
201
+ Function escapes single quotes.
202
+ */
203
+ function ws_plugin__s2member_esc_sq ($string = FALSE)
204
+ {
205
+ return preg_replace ("/'/", "\'", $string);
206
+ }
207
  ?>
includes/hooks.inc.php CHANGED
@@ -18,12 +18,12 @@ Add the plugin actions/filters here.
18
  */
19
  add_action ("init", "ws_plugin__s2member_nocache");
20
  add_action ("init", "ws_plugin__s2member_constants");
 
21
  add_action ("init", "ws_plugin__s2member_js_w_globals");
22
  add_action ("init", "ws_plugin__s2member_menu_pages_js");
23
  add_action ("init", "ws_plugin__s2member_menu_pages_css");
24
  add_action ("init", "ws_plugin__s2member_paypal_return");
25
  add_action ("init", "ws_plugin__s2member_paypal_notify");
26
- add_action ("init", "ws_plugin__s2member_paypal_register");
27
  add_action ("init", "ws_plugin__s2member_check_file_download_access");
28
  add_action ("init", "ws_plugin__s2member_handle_profile_modifications");
29
  /**/
@@ -54,6 +54,7 @@ add_action ("admin_notices", "ws_plugin__s2member_admin_notices");
54
  add_action ("admin_menu", "ws_plugin__s2member_add_admin_options");
55
  add_action ("admin_print_scripts", "ws_plugin__s2member_add_admin_scripts");
56
  add_action ("admin_print_styles", "ws_plugin__s2member_add_admin_styles");
 
57
  /**/
58
  add_filter ("manage_users_columns", "ws_plugin__s2member_users_list_cols");
59
  add_filter ("manage_users_custom_column", "ws_plugin__s2member_users_list_display_cols", 10, 3);
18
  */
19
  add_action ("init", "ws_plugin__s2member_nocache");
20
  add_action ("init", "ws_plugin__s2member_constants");
21
+ add_action ("init", "ws_plugin__s2member_register");
22
  add_action ("init", "ws_plugin__s2member_js_w_globals");
23
  add_action ("init", "ws_plugin__s2member_menu_pages_js");
24
  add_action ("init", "ws_plugin__s2member_menu_pages_css");
25
  add_action ("init", "ws_plugin__s2member_paypal_return");
26
  add_action ("init", "ws_plugin__s2member_paypal_notify");
 
27
  add_action ("init", "ws_plugin__s2member_check_file_download_access");
28
  add_action ("init", "ws_plugin__s2member_handle_profile_modifications");
29
  /**/
54
  add_action ("admin_menu", "ws_plugin__s2member_add_admin_options");
55
  add_action ("admin_print_scripts", "ws_plugin__s2member_add_admin_scripts");
56
  add_action ("admin_print_styles", "ws_plugin__s2member_add_admin_styles");
57
+ add_action ("wp_ajax_s2member_sp_access_link", "ws_plugin__s2member_sp_access_link");
58
  /**/
59
  add_filter ("manage_users_columns", "ws_plugin__s2member_users_list_cols");
60
  add_filter ("manage_users_custom_column", "ws_plugin__s2member_users_list_display_cols", 10, 3);
includes/mailchimp/index.php ADDED
File without changes
includes/mailchimp/nc-mcapi.inc.php ADDED
@@ -0,0 +1,1814 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /*
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/>
9
+ */
10
+ class NC_MCAPI {
11
+ var $version = "1.2";
12
+ var $errorMessage;
13
+ var $errorCode;
14
+
15
+ /**
16
+ * Cache the information on the API location on the server
17
+ */
18
+ var $apiUrl;
19
+
20
+ /**
21
+ * Default to a 300 second timeout on server calls
22
+ */
23
+ var $timeout = 300;
24
+
25
+ /**
26
+ * Default to a 8K chunk size
27
+ */
28
+ var $chunkSize = 8192;
29
+
30
+ /**
31
+ * Cache the user api_key so we only have to log in once per client instantiation
32
+ */
33
+ var $api_key;
34
+
35
+ /**
36
+ * Cache the user api_key so we only have to log in once per client instantiation
37
+ */
38
+ var $secure = false;
39
+
40
+ /**
41
+ * Connect to the MailChimp API for a given list.
42
+ *
43
+ * @param string $apikey Your MailChimp apikey
44
+ * @param string $secure Whether or not this should use a secure connection
45
+ */
46
+ function NC_MCAPI($apikey, $secure = false) {
47
+ //do more "caching" of the uuid for those people that keep instantiating this...
48
+ $this->secure = $secure;
49
+ $this->apiUrl = parse_url("http://api.mailchimp.com/" . $this->version . "/?output=php");
50
+ if ( isset($GLOBALS["mc_api_key"]) && $GLOBALS["mc_api_key"] !="" ){
51
+ $this->api_key = $GLOBALS["mc_api_key"];
52
+ } else {
53
+ $this->api_key = $GLOBALS["mc_api_key"] = $apikey;
54
+ }
55
+ }
56
+ function setTimeout($seconds){
57
+ if (is_int($seconds)){
58
+ $this->timeout = $seconds;
59
+ return true;
60
+ }
61
+ }
62
+ function getTimeout(){
63
+ return $this->timeout;
64
+ }
65
+ function useSecure($val){
66
+ if ($val===true){
67
+ $this->secure = true;
68
+ } else {
69
+ $this->secure = false;
70
+ }
71
+ }
72
+
73
+ /**
74
+ * Unschedule a campaign that is scheduled to be sent in the future
75
+ *
76
+ * @section Campaign Related
77
+ * @example mcapi_campaignUnschedule.php
78
+ * @example xml-rpc_campaignUnschedule.php
79
+ *
80
+ * @param string $cid the id of the campaign to unschedule
81
+ * @return boolean true on success
82
+ */
83
+ function campaignUnschedule($cid) {
84
+ $params = array();
85
+ $params["cid"] = $cid;
86
+ return $this->callServer("campaignUnschedule", $params);
87
+ }
88
+
89
+ /**
90
+ * Schedule a campaign to be sent in the future
91
+ *
92
+ * @section Campaign Related
93
+ * @example mcapi_campaignSchedule.php
94
+ * @example xml-rpc_campaignSchedule.php
95
+ *
96
+ * @param string $cid the id of the campaign to schedule
97
+ * @param string $schedule_time the time to schedule the campaign. For A/B Split "schedule" campaigns, the time for Group A - in YYYY-MM-DD HH:II:SS format in <strong>GMT</strong>
98
+ * @param string $schedule_time_b optional -the time to schedule Group B of an A/B Split "schedule" campaign - in YYYY-MM-DD HH:II:SS format in <strong>GMT</strong>
99
+ * @return boolean true on success
100
+ */
101
+ function campaignSchedule($cid, $schedule_time, $schedule_time_b=NULL) {
102
+ $params = array();
103
+ $params["cid"] = $cid;
104
+ $params["schedule_time"] = $schedule_time;
105
+ $params["schedule_time_b"] = $schedule_time_b;
106
+ return $this->callServer("campaignSchedule", $params);
107
+ }
108
+
109
+ /**
110
+ * Resume sending an AutoResponder or RSS campaign
111
+ *
112
+ * @section Campaign Related
113
+ *
114
+ * @param string $cid the id of the campaign to pause
115
+ * @return boolean true on success
116
+ */
117
+ function campaignResume($cid) {
118
+ $params = array();
119
+ $params["cid"] = $cid;
120
+ return $this->callServer("campaignResume", $params);
121
+ }
122
+
123
+ /**
124
+ * Pause an AutoResponder orRSS campaign from sending
125
+ *
126
+ * @section Campaign Related
127
+ *
128
+ * @param string $cid the id of the campaign to pause
129
+ * @return boolean true on success
130
+ */
131
+ function campaignPause($cid) {
132
+ $params = array();
133
+ $params["cid"] = $cid;
134
+ return $this->callServer("campaignPause", $params);
135
+ }
136
+
137
+ /**
138
+ * Send a given campaign immediately
139
+ *
140
+ * @section Campaign Related
141
+ *
142
+ * @example mcapi_campaignSendNow.php
143
+ * @example xml-rpc_campaignSendNow.php
144
+ *
145
+ * @param string $cid the id of the campaign to resume
146
+ * @return boolean true on success
147
+ */
148
+ function campaignSendNow($cid) {
149
+ $params = array();
150
+ $params["cid"] = $cid;
151
+ return $this->callServer("campaignSendNow", $params);
152
+ }
153
+
154
+ /**
155
+ * Send a test of this campaign to the provided email address
156
+ *
157
+ * @section Campaign Related
158
+ *
159
+ * @example mcapi_campaignSendTest.php
160
+ * @example xml-rpc_campaignSendTest.php
161
+ *
162
+ * @param string $cid the id of the campaign to test
163
+ * @param array $test_emails an array of email address to receive the test message
164
+ * @param string $send_type optional by default (null) both formats are sent - "html" or "text" send just that format
165
+ * @return boolean true on success
166
+ */
167
+ function campaignSendTest($cid, $test_emails=array (
168
+ ), $send_type=NULL) {
169
+ $params = array();
170
+ $params["cid"] = $cid;
171
+ $params["test_emails"] = $test_emails;
172
+ $params["send_type"] = $send_type;
173
+ return $this->callServer("campaignSendTest", $params);
174
+ }
175
+
176
+ /**
177
+ * Retrieve all templates defined for your user account
178
+ *
179
+ * @section Campaign Related
180
+ * @example mcapi_campaignTemplates.php
181
+ * @example xml-rpc_campaignTemplates.php
182
+ *
183
+ * @return array An array of structs, one for each template (see Returned Fields for details)
184
+ * @returnf integer id Id of the template
185
+ * @returnf string name Name of the template
186
+ * @returnf string layout Layout of the template - "basic", "left_column", "right_column", or "postcard"
187
+ * @returnf string preview_image If we've generated it, the url of the preview image for the template
188
+ * @returnf array sections associative array of editable sections in the template that can accept custom HTML when sending a campaign
189
+ */
190
+ function campaignTemplates() {
191
+ $params = array();
192
+ return $this->callServer("campaignTemplates", $params);
193
+ }
194
+
195
+ /**
196
+ * Allows one to test their segmentation rules before creating a campaign using them
197
+ *
198
+ * @section Campaign Related
199
+ * @example mcapi_campaignSegmentTest.php
200
+ * @example xml-rpc_campaignSegmentTest.php
201
+ *
202
+ * @param string $list_id the list to test segmentation on - get lists using lists()
203
+ * @param array $options with 2 keys:
204
+ string "match" controls whether to use AND or OR when applying your options - expects "<strong>any</strong>" (for OR) or "<strong>all</strong>" (for AND)
205
+ array "conditions" - up to 10 different criteria to apply while segmenting. Each criteria row must contain 3 keys - "<strong>field</strong>", "<strong>op</strong>", and "<strong>value</strong>" - and possibly a fourth, "<strong>extra</strong>", based on these definitions:
206
+
207
+ Field = "<strong>date</strong>" : Select based on various dates we track
208
+ Valid Op(eration): <strong>eq</strong> (is) / <strong>gt</strong> (after) / <strong>lt</strong> (before)
209
+ Valid Values:
210
+ string last_campaign_sent uses the date of the last campaign sent
211
+ string campaign_id - uses the send date of the campaign that carriers the Id submitted - see campaigns()
212
+ string YYYY-MM-DD - any date in the form of YYYY-MM-DD - <em>note:</em> anything that appears to start with YYYY will be treated as a date
213
+
214
+ Field = "<strong>interests</strong>":
215
+ Valid Op(erations): <strong>one</strong> / <strong>none</strong> / <strong>all</strong>
216
+ Valid Values: a comma delimited of interest groups for the list - see listInterestGroups()
217
+
218
+ Field = "<strong>aim</strong>"
219
+ Valid Op(erations): <strong>open</strong> / <strong>noopen</strong> / <strong>click</strong> / <strong>noclick</strong>
220
+ Valid Values: "<strong>any</strong>" or a valid AIM-enabled Campaign that has been sent
221
+
222
+ Field = "<strong>rating</strong>" : allows matching based on list member ratings
223
+ Valid Op(erations): <strong>eq</strong> (=) / <strong>ne</strong> (!=) / <strong>gt</strong> (&gt;) / <strong>lt</strong> (&lt;)
224
+ Valid Values: a number between 0 and 5
225
+
226
+ Field = "<strong>ecomm_prod</strong>" or "<strong>ecomm_prod</strong>": allows matching product and category names from purchases
227
+ Valid Op(erations):
228
+ <strong>eq</strong> (=) / <strong>ne</strong> (!=) / <strong>gt</strong> (&gt;) / <strong>lt</strong> (&lt;) / <strong>like</strong> (like '%blah%') / <strong>nlike</strong> (not like '%blah%') / <strong>starts</strong> (like 'blah%') / <strong>ends</strong> (like '%blah')
229
+ Valid Values: any string
230
+
231
+ Field = "<strong>ecomm_spent_one</strong>" or "<strong>ecomm_spent_all</strong>" : allows matching purchase amounts on a single order or all orders
232
+ Valid Op(erations): <strong>gt</strong> (&gt;) / <strong>lt</strong> (&lt;)
233
+ Valid Values: a number
234
+
235
+ Field = "<strong>ecomm_date</strong>" : allow matching based on order dates
236
+ Valid Op(eration): <strong>eq</strong> (is) / <strong>gt</strong> (after) / <strong>lt</strong> (before)
237
+ Valid Values:
238
+ string YYYY-MM-DD - any date in the form of YYYY-MM-DD
239
+
240
+ Field = An <strong>Address</strong> Merge Var. Use <strong>Merge0-Merge30</strong> or the <strong>Custom Tag</strong> you've setup for your merge field - see listMergeVars(). Note, Address fields can still be used with the default operations below - this section is broken out solely to highlight the differences in using the geolocation routines.
241
+ Valid Op(erations): <strong>geoin</strong>
242
+ Valid Values: The number of miles an address should be within
243
+ Extra Value: The Zip Code to be used as the center point
244
+
245
+ Default Field = A Merge Var. Use <strong>Merge0-Merge30</strong> or the <strong>Custom Tag</strong> you've setup for your merge field - see listMergeVars()
246
+ Valid Op(erations):
247
+ <strong>eq</strong> (=) / <strong>ne</strong> (!=) / <strong>gt</strong> (&gt;) / <strong>lt</strong> (&lt;) / <strong>like</strong> (like '%blah%') / <strong>nlike</strong> (not like '%blah%') / <strong>starts</strong> (like 'blah%') / <strong>ends</strong> (like '%blah')
248
+ Valid Values: any string
249
+ * @return integer total The total number of subscribers matching your segmentation options
250
+ */
251
+ function campaignSegmentTest($list_id, $options) {
252
+ $params = array();
253
+ $params["list_id"] = $list_id;
254
+ $params["options"] = $options;
255
+ return $this->callServer("campaignSegmentTest", $params);
256
+ }
257
+
258
+ /**
259
+ * Create a new draft campaign to send
260
+ *
261
+ * @section Campaign Related
262
+ * @example mcapi_campaignCreate.php
263
+ * @example xml-rpc_campaignCreate.php
264
+ * @example xml-rpc_campaignCreateABSplit.php
265
+ * @example xml-rpc_campaignCreateRss.php
266
+ *
267
+ * @param string $type the Campaign Type to create - one of "regular", "plaintext", "absplit", "rss", "trans", "auto"
268
+ * @param array $options a hash of the standard options for this campaign :
269
+ string list_id the list to send this campaign to- get lists using lists()
270
+ string subject the subject line for your campaign message
271
+ string from_email the From: email address for your campaign message
272
+ string from_name the From: name for your campaign message (not an email address)
273
+ string to_email the To: name recipients will see (not email address)
274
+ integer template_id optional - use this template to generate the HTML content of the campaign
275
+ integer folder_id optional - automatically file the new campaign in the folder_id passed
276
+ array tracking optional - set which recipient actions will be tracked, as a struct of boolean values with the following keys: "opens", "html_clicks", and "text_clicks". By default, opens and HTML clicks will be tracked.
277
+ string title optional - an internal name to use for this campaign. By default, the campaign subject will be used.
278
+ boolean authenticate optional - set to true to enable SenderID, DomainKeys, and DKIM authentication, defaults to false.
279
+ array analytics optional - if provided, use a struct with "service type" as a key and the "service tag" as a value. For Google, this should be "google"=>"your_google_analytics_key_here". Note that only "google" is currently supported - a Google Analytics tags will be added to all links in the campaign with this string attached. Others may be added in the future
280
+ boolean auto_footer optional Whether or not we should auto-generate the footer for your content. Mostly useful for content from URLs or Imports
281
+ boolean inline_css optional Whether or not css should be automatically inlined when this campaign is sent, defaults to false.
282
+ boolean generate_text optional Whether of not to auto-generate your Text content from the HTML content. Note that this will be ignored if the Text part of the content passed is not empty, defaults to false.
283
+ boolean auto_tweet optional If set, this campaign will be auto-tweeted when it is sent - defaults to false. Note that if a Twitter account isn't linked, this will be silently ignored.
284
+
285
+ * @param array $content the content for this campaign - use a struct with the following keys:
286
+ "html" for pasted HTML content
287
+ "text" for the plain-text version
288
+ "url" to have us pull in content from a URL. Note, this will override any other content options - for lists with Email Format options, you'll need to turn on generate_text as well
289
+ "archive" to send a Base64 encoded archive file for us to import all media from. Note, this will override any other content options - for lists with Email Format options, you'll need to turn on generate_text as well
290
+ "archive_type" optional - only necessary for the "archive" option. Supported formats are: zip, tar.gz, tar.bz2, tar, tgz, tbz . If not included, we will default to zip
291
+
292
+
293
+ If you chose a template instead of pasting in your HTML content, then use "html_" followed by the template sections as keys - for example, use a key of "html_MAIN" to fill in the "MAIN" section of a template. Supported template sections include: "html_HEADER", "html_MAIN", "html_SIDECOLUMN", and "html_FOOTER"
294
+ * @param array $segment_opts optional - if you wish to do Segmentation with this campaign this array should contain: see campaignSegmentTest(). It's suggested that you test your options against campaignSegmentTest(). Also, "trans" campaigns <strong>do not</strong> support segmentation.
295
+ * @param array $type_opts optional -
296
+ For RSS Campaigns this, array should contain:
297
+ string url the URL to pull RSS content from - it will be verified and must exist
298
+ string schedule optional one of "daily", "weekly", "monthly" - defaults to "daily"
299
+ string schedule_hour optional an hour between 0 and 24 - default to 4 (4am <em>local time</em>) - applies to all schedule types
300
+ string schedule_weekday optional for "weekly" only, a number specifying the day of the week to send: 0 (Sunday) - 6 (Saturday) - defaults to 1 (Monday)
301
+ string schedule_monthday optional for "monthly" only, a number specifying the day of the month to send (1 - 28) or "last" for the last day of a given month. Defaults to the 1st day of the month
302
+
303
+ For A/B Split campaigns, this array should contain:
304
+ string split_test The values to segment based on. Currently, one of: "subject", "from_name", "schedule". NOTE, for "schedule", you will need to call campaignSchedule() separately!
305
+ string pick_winner How the winner will be picked, one of: "opens" (by the open_rate), "clicks" (by the click rate), "manual" (you pick manually)
306
+ integer wait_units optional the default time unit to wait before auto-selecting a winner - use "3600" for hours, "86400" for days. Defaults to 86400.
307
+ integer wait_time optional the number of units to wait before auto-selecting a winner - defaults to 1, so if not set, a winner will be selected after 1 Day.
308
+ integer split_size optional this is a percentage of what size the Campaign's List plus any segmentation options results in. "schedule" type forces 50%, all others default to 10%
309
+ string from_name_a optional sort of, required when split_test is "from_name"
310
+ string from_name_b optional sort of, required when split_test is "from_name"
311
+ string from_email_a optional sort of, required when split_test is "from_name"
312
+ string from_email_b optional sort of, required when split_test is "from_name"
313
+ string subject_a optional sort of, required when split_test is "subject"
314
+ string subject_b optional sort of, required when split_test is "subject"
315
+
316
+ For AutoResponder campaigns, this array should contain:
317
+ string offset-units one of "day", "week", "month", "year" - required
318
+ string offset-time the number of units, must be a number greater than 0 - required
319
+ string offset-dir either "before" or "after"
320
+ string event optional "signup" (default) to base this on double-optin signup, "date" or "annual" to base this on merge field in the list
321
+ string event-datemerge optional sort of, this is required if the event is "date" or "annual"
322
+
323
+ *
324
+ * @return string the ID for the created campaign
325
+ */
326
+ function campaignCreate($type, $options, $content, $segment_opts=NULL, $type_opts=NULL) {
327
+ $params = array();
328
+ $params["type"] = $type;
329
+ $params["options"] = $options;
330
+ $params["content"] = $content;
331
+ $params["segment_opts"] = $segment_opts;
332
+ $params["type_opts"] = $type_opts;
333
+ return $this->callServer("campaignCreate", $params);
334
+ }
335
+
336
+ /** Update just about any setting for a campaign that has <em>not</em> been sent. See campaignCreate() for details.
337
+ *
338
+ *
339
+ * Caveats:<br/><ul>
340
+ * <li>If you set list_id, all segmentation options will be deleted and must be re-added.</li>
341
+ * <li>If you set template_id, you need to follow that up by setting it's 'content'</li>
342
+ * <li>If you set segment_opts, you should have tested your options against campaignSegmentTest() as campaignUpdate() will not allow you to set a segment that includes no members.</li></ul>
343
+ * @section Campaign Related
344
+ *
345
+ * @example mcapi_campaignUpdate.php
346
+ * @example mcapi_campaignUpdateAB.php
347
+ * @example xml-rpc_campaignUpdate.php
348
+ * @example xml-rpc_campaignUpdateAB.php
349
+ *
350
+ * @param string $cid the Campaign Id to update
351
+ * @param string $name the parameter name ( see campaignCreate() ). For items in the <strong>options</strong> array, this will be that parameter's name (subject, from_email, etc.). Additional parameters will be that option name (content, segment_opts). "type_opts" will be the name of the type - rss, auto, trans, etc.
352
+ * @param mixed $value an appropriate value for the parameter ( see campaignCreate() ). For items in the <strong>options</strong> array, this will be that parameter's value. For additional parameters, this is the same value passed to them.
353
+ * @return boolean true if the update succeeds, otherwise an error will be thrown
354
+ */
355
+ function campaignUpdate($cid, $name, $value) {
356
+ $params = array();
357
+ $params["cid"] = $cid;
358
+ $params["name"] = $name;
359
+ $params["value"] = $value;
360
+ return $this->callServer("campaignUpdate", $params);
361
+ }
362
+
363
+ /** Replicate a campaign.
364
+ *
365
+ * @section Campaign Related
366
+ *
367
+ * @example mcapi_campaignReplicate.php
368
+ *
369
+ * @param string $cid the Campaign Id to replicate
370
+ * @return string the id of the replicated Campaign created, otherwise an error will be thrown
371
+ */
372
+ function campaignReplicate($cid) {
373
+ $params = array();
374
+ $params["cid"] = $cid;
375
+ return $this->callServer("campaignReplicate", $params);
376
+ }
377
+
378
+ /** Delete a campaign. Seriously, "poof, gone!" - be careful!
379
+ *
380
+ * @section Campaign Related
381
+ *
382
+ * @example mcapi_campaignDelete.php
383
+ *
384
+ * @param string $cid the Campaign Id to delete
385
+ * @return boolean true if the delete succeeds, otherwise an error will be thrown
386
+ */
387
+ function campaignDelete($cid) {
388
+ $params = array();
389
+ $params["cid"] = $cid;
390
+ return $this->callServer("campaignDelete", $params);
391
+ }
392
+
393
+ /**
394
+ * Get the list of campaigns and their details matching the specified filters
395
+ *
396
+ * @section Campaign Related
397
+ * @example mcapi_campaigns.php
398
+ * @example xml-rpc_campaigns.php
399
+ *
400
+ * @param array $filters a hash of filters to apply to this query - all are optional:
401
+ string campaign_id optional - return a single campaign using a know campaign_id
402
+ string list_id optional - the list to send this campaign to- get lists using lists()
403
+ integer folder_id optional - only show campaigns from this folder id - get folders using campaignFolders()
404
+ string status optional - return campaigns of a specific status - one of "save", "paused", "schedule", "sending"
405
+ string type optional - return campaigns of a specific type - one of "regular", "plaintext", "absplit", "rss", "trans", "auto"
406
+ string from_name optional - only show campaigns that have this "From Name"
407
+ string from_email optional - only show campaigns that have this "Reply-to Email"
408
+ string title optional - only show campaigns that have this title
409
+ string subject optional - only show campaigns that have this subject
410
+ string sendtime_start optional - only show campaigns that have been sent since this date/time (in GMT) - format is YYYY-MM-DD HH:mm:ss (24hr)
411
+ string sendtime_end optional - only show campaigns that have been sent before this date/time (in GMT) - format is YYYY-MM-DD HH:mm:ss (24hr)
412
+ boolean exact optional - flag for whether to filter on exact values when filtering, or search within content for filter values - defaults to true
413
+ * @param integer $start optional - control paging of campaigns, start results at this campaign #, defaults to 1st page of data (page 0)
414
+ * @param integer $limit optional - control paging of campaigns, number of campaigns to return with each call, defaults to 25 (max=1000)
415
+ * @return array list of campaigns and their associated information (see Returned Fields for description)
416
+ * @returnf string id Campaign Id (used for all other campaign functions)
417
+ * @returnf integer web_id The Campaign id used in our web app, allows you to create a link directly to it
418
+ * @returnf string title Title of the campaign
419
+ * @returnf string type The type of campaign this is (regular,plaintext,absplit,rss,inspection,trans,auto)
420
+ * @returnf date create_time Creation time for the campaign
421
+ * @returnf date send_time Send time for the campaign - also the scheduled time for scheduled campaigns.
422
+ * @returnf integer emails_sent Number of emails email was sent to
423
+ * @returnf string status Status of the given campaign (save,paused,schedule,sending,sent)
424
+ * @returnf string from_name From name of the given campaign
425
+ * @returnf string from_email Reply-to email of the given campaign
426
+ * @returnf string subject Subject of the given campaign
427
+ * @returnf string to_email Custom "To:" email string using merge variables
428
+ * @returnf string archive_url Archive link for the given campaign
429
+ * @returnf boolean inline_css Whether or not the campaigns content auto-css-lined
430
+ * @returnf string analytics Either "google" if enabled or "N" if disabled
431
+ * @returnf string analytcs_tag The name/tag the campaign's links were tagged with if analytics were enabled.
432
+ * @returnf boolean track_clicks_text Whether or not links in the text version of the campaign were tracked
433
+ * @returnf boolean track_clicks_html Whether or not links in the html version of the campaign were tracked
434
+ * @returnf boolean track_opens Whether or not opens for the campaign were tracked
435
+ * @returnf string segment_text a string marked-up with HTML explaining the segment used for the campaign in plain English
436
+ * @returnf array segment_opts the segment used for the campaign - can be passed to campaignSegmentTest() or campaignCreate()
437
+ */
438
+ function campaigns($filters=array (
439
+ ), $start=0, $limit=25) {
440
+ $params = array();
441
+ $params["filters"] = $filters;
442
+ $params["start"] = $start;
443
+ $params["limit"] = $limit;
444
+ return $this->callServer("campaigns", $params);
445
+ }
446
+
447
+ /**
448
+ * List all the folders for a user account
449
+ *
450
+ * @section Campaign Related
451
+ * @example mcapi_campaignFolders.php
452
+ * @example xml-rpc_campaignFolders.php
453
+ *
454
+ * @return array Array of folder structs (see Returned Fields for details)
455
+ * @returnf integer folder_id Folder Id for the given folder, this can be used in the campaigns() function to filter on.
456
+ * @returnf string name Name of the given folder
457
+ */
458
+ function campaignFolders() {
459
+ $params = array();
460
+ return $this->callServer("campaignFolders", $params);
461
+ }
462
+
463
+ /**
464
+ * Given a list and a campaign, get all the relevant campaign statistics (opens, bounces, clicks, etc.)
465
+ *
466
+ * @section Campaign Stats
467
+ *
468
+ * @example mcapi_campaignStats.php
469
+ * @example xml-rpc_campaignStats.php
470
+ *
471
+ * @param string $cid the campaign id to pull stats for (can be gathered using campaigns())
472
+ * @return array struct of the statistics for this campaign
473
+ * @returnf integer syntax_errors Number of email addresses in campaign that had syntactical errors.
474
+ * @returnf integer hard_bounces Number of email addresses in campaign that hard bounced.
475
+ * @returnf integer soft_bounces Number of email addresses in campaign that soft bounced.
476
+ * @returnf integer unsubscribes Number of email addresses in campaign that unsubscribed.
477
+ * @returnf integer abuse_reports Number of email addresses in campaign that reported campaign for abuse.
478
+ * @returnf integer forwards Number of times email was forwarded to a friend.
479
+ * @returnf integer forwards_opens Number of times a forwarded email was opened.
480
+ * @returnf integer opens Number of times the campaign was opened.
481
+ * @returnf date last_open Date of the last time the email was opened.
482
+ * @returnf integer unique_opens Number of people who opened the campaign.
483
+ * @returnf integer clicks Number of times a link in the campaign was clicked.
484
+ * @returnf integer unique_clicks Number of unique recipient/click pairs for the campaign.
485
+ * @returnf date last_click Date of the last time a link in the email was clicked.
486
+ * @returnf integer users_who_clicked Number of unique recipients who clicked on a link in the campaign.
487
+ * @returnf integer emails_sent Number of email addresses campaign was sent to.
488
+ */
489
+ function campaignStats($cid) {
490
+ $params = array();
491
+ $params["cid"] = $cid;
492
+ return $this->callServer("campaignStats", $params);
493
+ }
494
+
495
+ /**
496
+ * Get an array of the urls being tracked, and their click counts for a given campaign
497
+ *
498
+ * @section Campaign Stats
499
+ *
500
+ * @example mcapi_campaignClickStats.php
501
+ * @example xml-rpc_campaignClickStats.php
502
+ *
503
+ * @param string $cid the campaign id to pull stats for (can be gathered using campaigns())
504
+ * @return struct urls will be keys and contain their associated statistics:
505
+ * @returnf integer clicks Number of times the specific link was clicked
506
+ * @returnf integer unique Number of unique people who clicked on the specific link
507
+ */
508
+ function campaignClickStats($cid) {
509
+ $params = array();
510
+ $params["cid"] = $cid;
511
+ return $this->callServer("campaignClickStats", $params);
512
+ }
513
+
514
+ /**
515
+ * Get the top 5 performing email domains for this campaign. Users want more than 5 should use campaign campaignEmailStatsAIM()
516
+ * or campaignEmailStatsAIMAll() and generate any additional stats they require.
517
+ *
518
+ * @section Campaign Stats
519
+ *
520
+ * @example mcapi_campaignEmailDomainPerformance.php
521
+ *
522
+ * @param string $cid the campaign id to pull email domain performance for (can be gathered using campaigns())
523
+ * @return array domains email domains and their associated stats
524
+ * @returnf string domain Domain name or special "Other" to roll-up stats past 5 domains
525
+ * @returnf integer total_sent Total Email across all domains - this will be the same in every row
526
+ * @returnf integer emails Number of emails sent to this domain
527
+ * @returnf integer bounces Number of bounces
528
+ * @returnf integer opens Number of opens
529
+ * @returnf integer clicks Number of clicks
530
+ * @returnf integer unsubs Number of unsubs
531
+ * @returnf integer delivered Number of deliveries
532
+ * @returnf integer emails_pct Percentage of emails that went to this domain (whole number)
533
+ * @returnf integer bounces_pct Percentage of bounces from this domain (whole number)
534
+ * @returnf integer opens_pct Percentage of opens from this domain (whole number)
535
+ * @returnf integer clicks_pct Percentage of clicks from this domain (whole number)
536
+ * @returnf integer unsubs_pct Percentage of unsubs from this domain (whole number)
537
+ */
538
+ function campaignEmailDomainPerformance($cid) {
539
+ $params = array();
540
+ $params["cid"] = $cid;
541
+ return $this->callServer("campaignEmailDomainPerformance", $params);
542
+ }
543
+
544
+ /**
545
+ * Get all email addresses with Hard Bounces for a given campaign
546
+ *
547
+ * @section Campaign Stats
548
+ *
549
+ * @param string $cid the campaign id to pull bounces for (can be gathered using campaigns())
550
+ * @param integer $start optional for large data sets, the page number to start at - defaults to 1st page of data (page 0)
551
+ * @param integer $limit optional for large data sets, the number of results to return - defaults to 1000, upper limit set at 15000
552
+ * @return array Arrays of email addresses with Hard Bounces
553
+ */
554
+ function campaignHardBounces($cid, $start=0, $limit=1000) {
555
+ $params = array();
556
+ $params["cid"] = $cid;
557
+ $params["start"] = $start;
558
+ $params["limit"] = $limit;
559
+ return $this->callServer("campaignHardBounces", $params);
560
+ }
561
+
562
+ /**
563
+ * Get all email addresses with Soft Bounces for a given campaign
564
+ *
565
+ * @section Campaign Stats
566
+ *
567
+ * @param string $cid the campaign id to pull bounces for (can be gathered using campaigns())
568
+ * @param integer $start optional for large data sets, the page number to start at - defaults to 1st page of data (page 0)
569
+ * @param integer $limit optional for large data sets, the number of results to return - defaults to 1000, upper limit set at 15000
570
+ * @return array Arrays of email addresses with Soft Bounces
571
+ */
572
+ function campaignSoftBounces($cid, $start=0, $limit=1000) {
573
+ $params = array();
574
+ $params["cid"] = $cid;
575
+ $params["start"] = $start;
576
+ $params["limit"] = $limit;
577
+ return $this->callServer("campaignSoftBounces", $params);
578
+ }
579
+
580
+ /**
581
+ * Get all unsubscribed email addresses for a given campaign
582
+ *
583
+ * @section Campaign Stats
584
+ *
585
+ * @param string $cid the campaign id to pull bounces for (can be gathered using campaigns())
586
+ * @param integer $start optional for large data sets, the page number to start at - defaults to 1st page of data (page 0)
587
+ * @param integer $limit optional for large data sets, the number of results to return - defaults to 1000, upper limit set at 15000
588
+ * @return array list of email addresses that unsubscribed from this campaign
589
+ */
590
+ function campaignUnsubscribes($cid, $start=0, $limit=1000) {
591
+ $params = array();
592
+ $params["cid"] = $cid;
593
+ $params["start"] = $start;
594
+ $params["limit"] = $limit;
595
+ return $this->callServer("campaignUnsubscribes", $params);
596
+ }
597
+
598
+ /**
599
+ * Get all email addresses that complained about a given campaign
600
+ *
601
+ * @section Campaign Stats
602
+ *
603
+ * @example mcapi_campaignAbuseReports.php
604
+ *
605
+ * @param string $cid the campaign id to pull abuse reports for (can be gathered using campaigns())
606
+ * @param integer $start optional for large data sets, the page number to start at - defaults to 1st page of data (page 0)
607
+ * @param integer $limit optional for large data sets, the number of results to return - defaults to 500, upper limit set at 1000
608
+ * @param string $since optional pull only messages since this time - use YYYY-MM-DD HH:II:SS format in <strong>GMT</strong>
609
+ * @return array reports the abuse reports for this campaign
610
+ * @returnf string date date/time the abuse report was received and processed
611
+ * @returnf string email the email address that reported abuse
612
+ * @returnf string type an internal type generally specifying the orginating mail provider - may not be useful outside of filling report views
613
+ */
614
+ function campaignAbuseReports($cid, $since=NULL, $start=0, $limit=500) {
615
+ $params = array();
616
+ $params["cid"] = $cid;
617
+ $params["since"] = $since;
618
+ $params["start"] = $start;
619
+ $params["limit"] = $limit;
620
+ return $this->callServer("campaignAbuseReports", $params);
621
+ }
622
+
623
+ /**
624
+ * Retrieve the text presented in our app for how a campaign performed and any advice we may have for you - best
625
+ * suited for display in customized reports pages. Note: some messages will contain HTML - clean tags as necessary
626
+ *
627
+ * @section Campaign Stats
628
+ *
629
+ * @example mcapi_campaignAdvice.php
630
+ *
631
+ * @param string $cid the campaign id to pull advice text for (can be gathered using campaigns())
632
+ * @return array advice on the campaign's performance
633
+ * @returnf msg the advice message
634
+ * @returnf type the "type" of the message. one of: negative, positive, or neutral
635
+ */
636
+ function campaignAdvice($cid) {
637
+ $params = array();
638
+ $params["cid"] = $cid;
639
+ return $this->callServer("campaignAdvice", $params);
640
+ }
641
+
642
+ /**
643
+ * Retrieve the Google Analytics data we've collected for this campaign. Note, requires Google Analytics Add-on to be installed and configured.
644
+ *
645
+ * @section Campaign Stats
646
+ *
647
+ * @example mcapi_campaignAnalytics.php
648
+ *
649
+ * @param string $cid the campaign id to pull bounces for (can be gathered using campaigns())
650
+ * @return array analytics we've collected for the passed campaign.
651
+ * @returnf integer visits number of visits
652
+ * @returnf integer pages number of page views
653
+ * @returnf integer new_visits new visits recorded
654
+ * @returnf integer bounces vistors who "bounced" from your site
655
+ * @returnf double time_on_site
656
+ * @returnf integer goal_conversions number of goals converted
657
+ * @returnf double goal_value value of conversion in dollars
658
+ * @returnf double revenue revenue generated by campaign
659
+ * @returnf integer transactions number of transactions tracked
660
+ * @returnf integer ecomm_conversions number Ecommerce transactions tracked
661
+ * @returnf array goals an array containing goal names and number of conversions
662
+ */
663
+ function campaignAnalytics($cid) {
664
+ $params = array();
665
+ $params["cid"] = $cid;
666
+ return $this->callServer("campaignAnalytics", $params);
667
+ }
668
+
669
+ /**
670
+ * Retrieve the countries and number of opens tracked for each. Email address are not returned.
671
+ *
672
+ * @section Campaign Stats
673
+ *
674
+ *
675
+ * @param string $cid the campaign id to pull bounces for (can be gathered using campaigns())
676
+ * @return array countries an array of countries where opens occurred
677
+ * @returnf string code The ISO3166 2 digit country code
678
+ * @returnf string name A version of the country name, if we have it
679
+ * @returnf int opens The total number of opens that occurred in the country
680
+ * @returnf bool region_detail Whether or not a subsequent call to campaignGeoOpensByCountry() will return anything
681
+ */
682
+ function campaignGeoOpens($cid) {
683
+ $params = array();
684
+ $params["cid"] = $cid;
685
+ return $this->callServer("campaignGeoOpens", $params);
686
+ }
687
+
688
+ /**
689
+ * Retrieve the regions and number of opens tracked for a certain country. Email address are not returned.
690
+ *
691
+ * @section Campaign Stats
692
+ *
693
+ *
694
+ * @param string $cid the campaign id to pull bounces for (can be gathered using campaigns())
695
+ * @param string $code An ISO3166 2 digit country code
696
+ * @return array regions an array of regions within the provided country where opens occurred.
697
+ * @returnf string code An internal code for the region. When this is blank, it indicates we know the country, but not the region
698
+ * @returnf string name The name of the region, if we have one. For blank "code" values, this will be "Rest of Country"
699
+ * @returnf int opens The total number of opens that occurred in the country
700
+ */
701
+ function campaignGeoOpensForCountry($cid, $code) {
702
+ $params = array();
703
+ $params["cid"] = $cid;
704
+ $params["code"] = $code;
705
+ return $this->callServer("campaignGeoOpensForCountry", $params);
706
+ }
707
+
708
+ /**
709
+ * Retrieve the tracked eepurl mentions on Twitter
710
+ *
711
+ * @section Campaign Stats
712
+ *
713
+ *
714
+ * @param string $cid the campaign id to pull bounces for (can be gathered using campaigns())
715
+ * @return array stats an array containing tweets and retweets including the campaign's eepurl
716
+ * @returnf int tweets Total number of tweets seen
717
+ * @returnf string first_tweet date and time of the first tweet seen
718
+ * @returnf string last_tweet date and time of the last tweet seen
719
+ * @returnf int retweets Total number of retweets seen
720
+ * @returnf string first_retweet date and time of the first retweet seen
721
+ * @returnf string last_retweet date and time of the last retweet seen
722
+ * @returnf array statuses an array of statuses recorded inclduing the status, screen_name, status_id, and datetime fields plus an is_retweet flag
723
+ */
724
+ function campaignEepUrlStats($cid) {
725
+ $params = array();
726
+ $params["cid"] = $cid;
727
+ return $this->callServer("campaignEepUrlStats", $params);
728
+ }
729
+
730
+ /**
731
+ * Retrieve the full bounce messages for the given campaign. Note that this can return very large amounts
732
+ * of data depending on how large the campaign was and how much cruft the bounce provider returned. Also,
733
+ * message over 30 days old are subject to being removed
734
+ *
735
+ * @section Campaign Stats
736
+ *
737
+ * @example mcapi_campaignBounceMessages.php
738
+ *
739
+ * @param string $cid the campaign id to pull bounces for (can be gathered using campaigns())
740
+ * @param integer $start optional for large data sets, the page number to start at - defaults to 1st page of data (page 0)
741
+ * @param integer $limit optional for large data sets, the number of results to return - defaults to 25, upper limit set at 50
742
+ * @param string $since optional pull only messages since this time - use YYYY-MM-DD format in <strong>GMT</strong> (we only store the date, not the time)
743
+ * @return array bounces the full bounce messages for this campaign
744
+ * @returnf string date date/time the bounce was received and processed
745
+ * @returnf string email the email address that bounced
746
+ * @returnf string message the entire bounce message received
747
+ */
748
+ function campaignBounceMessages($cid, $start=0, $limit=25, $since=NULL) {
749
+ $params = array();
750
+ $params["cid"] = $cid;
751
+ $params["start"] = $start;
752
+ $params["limit"] = $limit;
753
+ $params["since"] = $since;
754
+ return $this->callServer("campaignBounceMessages", $params);
755
+ }
756
+
757
+ /**
758
+ * Retrieve the Ecommerce Orders tracked by campaignEcommAddOrder()
759
+ *
760
+ * @section Campaign Stats
761
+ *
762
+ * @param string $cid the campaign id to pull bounces for (can be gathered using campaigns())
763
+ * @param integer $start optional for large data sets, the page number to start at - defaults to 1st page of data (page 0)
764
+ * @param integer $limit optional for large data sets, the number of results to return - defaults to 100, upper limit set at 500
765
+ * @param string $since optional pull only messages since this time - use YYYY-MM-DD HH:II:SS format in <strong>GMT</strong>
766
+ * @return array orders the orders and their details that we've collected for this campaign
767
+ * @returnf store_id string the store id generated by the plugin used to uniquely identify a store
768
+ * @returnf store_name string the store name collected by the plugin - often the domain name
769
+ * @returnf order_id string the internal order id the store tracked this order by
770
+ * @returnf email string the email address that received this campaign and is associated with this order
771
+ * @returnf order_total double the order total
772
+ * @returnf tax_total double the total tax for the order (if collected)
773
+ * @returnf ship_total double the shipping total for the order (if collected)
774
+ * @returnf order_date string the date the order was tracked - from the store if possible, otherwise the GMT time we recieved it
775
+ * @returnf lines array containing detail of the order - product, category, quantity, item cost
776
+ */
777
+ function campaignEcommOrders($cid, $start=0, $limit=100, $since=NULL) {
778
+ $params = array();
779
+ $params["cid"] = $cid;
780
+ $params["start"] = $start;
781
+ $params["limit"] = $limit;
782
+ $params["since"] = $since;
783
+ return $this->callServer("campaignEcommOrders", $params);
784
+ }
785
+
786
+ /**
787
+ * Get the URL to a customized <a href="http://eepurl.com/gKmL" target="_blank">VIP Report</a> for the specified campaign and optionally send an email to someone with links to it. Note subsequent calls will overwrite anything already set for the same campign (eg, the password)
788
+ *
789
+ * @section Campaign Related
790
+ *
791
+ * @param string $cid the campaign id to share a report for (can be gathered using campaigns())
792
+ * @param array $opts optional various parameters which can be used to configure the shared report
793
+ string header_type optional - "text" or "image', defaults to "text'
794
+ string header_data optional - if "header_type" is text, the text to display. if "header_type" is "image" a valid URL to an image file. Note that images will be resized to be no more than 500x150. Defaults to the Accounts Company Name.
795
+ boolean secure optional - whether to require a password for the shared report. defaults to "true"
796
+ string password optional - if secure is true and a password is not included, we will generate one. It is always returned.
797
+ string to_email optional - optional, email address to share the report with - no value means an email will not be sent
798
+ array theme optional - an array containing either 3 or 6 character color code values for: "bg_color", "header_color", "current_tab", "current_tab_text", "normal_tab", "normal_tab_text", "hover_tab", "hover_tab_text"
799
+ string css_url optional - a link to an external CSS file to be included after our default CSS (http://vip-reports.net/css/vip.css) <strong>only if</strong> loaded via the "secure_url" - max 255 characters
800
+ * @return struct Struct containing details for the shared report
801
+ * @returnf string title The Title of the Campaign being shared
802
+ * @returnf string url The URL to the shared report
803
+ * @returnf string secure_url The URL to the shared report, including the password (good for loading in an IFRAME). For non-secure reports, this will not be returned
804
+ * @returnf string password If secured, the password for the report, otherwise this field will not be returned
805
+ */
806
+ function campaignShareReport($cid, $opts=array (
807
+ )) {
808
+ $params = array();
809
+ $params["cid"] = $cid;
810
+ $params["opts"] = $opts;
811
+ return $this->callServer("campaignShareReport", $params);
812
+ }
813
+
814
+ /**
815
+ * Get the content (both html and text) for a campaign either as it would appear in the campaign archive or as the raw, original content
816
+ *
817
+ * @section Campaign Related
818
+ *
819
+ * @param string $cid the campaign id to get content for (can be gathered using campaigns())
820
+ * @param bool $for_archive optional controls whether we return the Archive version (true) or the Raw version (false), defaults to true
821
+ * @return struct Struct containing all content for the campaign (see Returned Fields for details
822
+ * @returnf string html The HTML content used for the campgain with merge tags intact
823
+ * @returnf string text The Text content used for the campgain with merge tags intact
824
+ */
825
+ function campaignContent($cid, $for_archive=true) {
826
+ $params = array();
827
+ $params["cid"] = $cid;
828
+ $params["for_archive"] = $for_archive;
829
+ return $this->callServer("campaignContent", $params);
830
+ }
831
+
832
+ /**
833
+ * Retrieve the list of email addresses that opened a given campaign with how many times they opened - note: this AIM function is free and does
834
+ * not actually require the AIM module to be installed
835
+ *
836
+ * @section Campaign AIM
837
+ *
838
+ * @param string $cid the campaign id to get opens for (can be gathered using campaigns())
839
+ * @param integer $start optional for large data sets, the page number to start at - defaults to 1st page of data (page 0)
840
+ * @param integer $limit optional for large data sets, the number of results to return - defaults to 1000, upper limit set at 15000
841
+ * @return array Array of structs containing email addresses and open counts
842
+ * @returnf string email Email address that opened the campaign
843
+ * @returnf integer open_count Total number of times the campaign was opened by this email address
844
+ */
845
+ function campaignOpenedAIM($cid, $start=0, $limit=1000) {
846
+ $params = array();
847
+ $params["cid"] = $cid;
848
+ $params["start"] = $start;
849
+ $params["limit"] = $limit;
850
+ return $this->callServer("campaignOpenedAIM", $params);
851
+ }
852
+
853
+ /**
854
+ * Retrieve the list of email addresses that did not open a given campaign
855
+ *
856
+ * @section Campaign AIM
857
+ *
858
+ * @param string $cid the campaign id to get no opens for (can be gathered using campaigns())
859
+ * @param integer $start optional for large data sets, the page number to start at - defaults to 1st page of data (page 0)
860
+ * @param integer $limit optional for large data sets, the number of results to return - defaults to 1000, upper limit set at 15000
861
+ * @return array list of email addresses that did not open a campaign
862
+ */
863
+ function campaignNotOpenedAIM($cid, $start=0, $limit=1000) {
864
+ $params = array();
865
+ $params["cid"] = $cid;
866
+ $params["start"] = $start;
867
+ $params["limit"] = $limit;
868
+ return $this->callServer("campaignNotOpenedAIM", $params);
869
+ }
870
+
871
+ /**
872
+ * Return the list of email addresses that clicked on a given url, and how many times they clicked
873
+ *
874
+ * @section Campaign AIM
875
+ *
876
+ * @param string $cid the campaign id to get click stats for (can be gathered using campaigns())
877
+ * @param string $url the URL of the link that was clicked on
878
+ * @param integer $start optional for large data sets, the page number to start at - defaults to 1st page of data (page 0)
879
+ * @param integer $limit optional for large data sets, the number of results to return - defaults to 1000, upper limit set at 15000
880
+ * @return array Array of structs containing email addresses and click counts
881
+ * @returnf string email Email address that opened the campaign
882
+ * @returnf integer clicks Total number of times the URL was clicked on by this email address
883
+ */
884
+ function campaignClickDetailAIM($cid, $url, $start=0, $limit=1000) {
885
+ $params = array();
886
+ $params["cid"] = $cid;
887
+ $params["url"] = $url;
888
+ $params["start"] = $start;
889
+ $params["limit"] = $limit;
890
+ return $this->callServer("campaignClickDetailAIM", $params);
891
+ }
892
+
893
+ /**
894
+ * Given a campaign and email address, return the entire click and open history with timestamps, ordered by time
895
+ *
896
+ * @section Campaign AIM
897
+ *
898
+ * @param string $cid the campaign id to get stats for (can be gathered using campaigns())
899
+ * @param string $email_address the email address to check OR the email "id" returned from listMemberInfo, Webhooks, and Campaigns
900
+ * @return array Array of structs containing the actions (opens and clicks) that the email took, with timestamps
901
+ * @returnf string action The action taken (open or click)
902
+ * @returnf date timestamp Time the action occurred
903
+ * @returnf string url For clicks, the URL that was clicked
904
+ */
905
+ function campaignEmailStatsAIM($cid, $email_address) {
906
+ $params = array();
907
+ $params["cid"] = $cid;
908
+ $params["email_address"] = $email_address;
909
+ return $this->callServer("campaignEmailStatsAIM", $params);
910
+ }
911
+
912
+ /**
913
+ * Given a campaign and correct paging limits, return the entire click and open history with timestamps, ordered by time,
914
+ * for every user a campaign was delivered to.
915
+ *
916
+ * @section Campaign AIM
917
+ * @example mcapi_campaignEmailStatsAIMAll.php
918
+ *
919
+ * @param string $cid the campaign id to get stats for (can be gathered using campaigns())
920
+ * @param integer $start optional for large data sets, the page number to start at - defaults to 1st page of data (page 0)
921
+ * @param integer $limit optional for large data sets, the number of results to return - defaults to 100, upper limit set at 1000
922
+ * @return array Array of structs containing actions (opens and clicks) for each email, with timestamps
923
+ * @returnf string action The action taken (open or click)
924
+ * @returnf date timestamp Time the action occurred
925
+ * @returnf string url For clicks, the URL that was clicked
926
+ */
927
+ function campaignEmailStatsAIMAll($cid, $start=0, $limit=100) {
928
+ $params = array();
929
+ $params["cid"] = $cid;
930
+ $params["start"] = $start;
931
+ $params["limit"] = $limit;
932
+ return $this->callServer("campaignEmailStatsAIMAll", $params);
933
+ }
934
+
935
+ /**
936
+ * Attach Ecommerce Order Information to a Campaign. This will generall be used by ecommerce package plugins
937
+ * <a href="/plugins/ecomm360.phtml">that we provide</a> or by 3rd part system developers.
938
+ * @section Campaign Related
939
+ *
940
+ * @param array $order an array of information pertaining to the order that has completed. Use the following keys:
941
+ string id the Order Id
942
+ string campaign_id the Campaign Id to track this order with (see the "mc_cid" query string variable a campaign passes)
943
+ string email_id the Email Id of the subscriber we should attach this order to (see the "mc_eid" query string variable a campaign passes)
944
+ double total The Order Total (ie, the full amount the customer ends up paying)
945
+ string order_date optional the date of the order - if this is not provided, we will default the date to now
946
+ double shipping optional the total paid for Shipping Fees
947
+ double tax optional the total tax paid
948
+ string store_id a unique id for the store sending the order in
949
+ string store_name optional a "nice" name for the store - typically the base web address (ie, "store.mailchimp.com"). We will automatically update this if it changes (based on store_id)
950
+ string plugin_id the MailChimp assigned Plugin Id. Get yours by <a href="/api/register.php">registering here</a>
951
+ array items the individual line items for an order using these keys:
952
+ <div style="padding-left:30px"><table><tr><td colspan=*>
953
+ integer line_num optional the line number of the item on the order. We will generate these if they are not passed
954
+ integer product_id the store's internal Id for the product. Lines that do no contain this will be skipped
955
+ string product_name the product name for the product_id associated with this item. We will auto update these as they change (based on product_id)
956
+ integer category_id the store's internal Id for the (main) category associated with this product. Our testing has found this to be a "best guess" scenario
957
+ string category_name the category name for the category_id this product is in. Our testing has found this to be a "best guess" scenario. Our plugins walk the category heirarchy up and send "Root - SubCat1 - SubCat4", etc.
958
+ double qty the quantity of the item ordered
959
+ double cost the cost of a single item (ie, not the extended cost of the line)
960
+ </td></tr></table></div>
961
+ * @return bool true if the data is saved, otherwise an error is thrown.
962
+ */
963
+ function campaignEcommAddOrder($order) {
964
+ $params = array();
965
+ $params["order"] = $order;
966
+ return $this->callServer("campaignEcommAddOrder", $params);
967
+ }
968
+
969
+ /**
970
+ * Retrieve all of the lists defined for your user account
971
+ *
972
+ * @section List Related
973
+ * @example mcapi_lists.php
974
+ * @example xml-rpc_lists.php
975
+ *
976
+ * @return array list of your Lists and their associated information (see Returned Fields for description)
977
+ * @returnf string id The list id for this list. This will be used for all other list management functions.
978
+ * @returnf integer web_id The list id used in our web app, allows you to create a link directly to it
979
+ * @returnf string name The name of the list.
980
+ * @returnf date date_created The date that this list was created.
981
+ * @returnf integer member_count The number of active members in the given list.
982
+ * @returnf integer unsubscribe_count The number of members who have unsubscribed from the given list.
983
+ * @returnf integer cleaned_count The number of members cleaned from the given list.
984
+ * @returnf boolean email_type_option Whether or not the List supports multiple formats for emails or just HTML
985
+ * @returnf string default_from_name Default From Name for campaigns using this list
986
+ * @returnf string default_from_email Default From Email for campaigns using this list
987
+ * @returnf string default_subject Default Subject Line for campaigns using this list
988
+ * @returnf string default_language Default Language for this list's forms
989
+ * @returnf double list_rating An auto-generated activity score for the list (0 - 5)
990
+ * @returnf integer member_count The number of active members in the given list since the last campaign was sent
991
+ * @returnf integer unsubscribe_count The number of members who have unsubscribed from the given list since the last campaign was sent
992
+ * @returnf integer cleaned_count The number of members cleaned from the given list since the last campaign was sent
993
+ */
994
+ function lists() {
995
+ $params = array();
996
+ return $this->callServer("lists", $params);
997
+ }
998
+
999
+ /**
1000
+ * Get the list of merge tags for a given list, including their name, tag, and required setting
1001
+ *
1002
+ * @section List Related
1003
+ * @example xml-rpc_listMergeVars.php
1004
+ *
1005
+ * @param string $id the list id to connect to. Get by calling lists()
1006
+ * @return array list of merge tags for the list
1007
+ * @returnf string name Name of the merge field
1008
+ * @returnf char req Denotes whether the field is required (Y) or not (N)
1009
+ * @returnf string tag The merge tag that's used for forms and listSubscribe() and listUpdateMember()
1010
+ */
1011
+ function listMergeVars($id) {
1012
+ $params = array();
1013
+ $params["id"] = $id;
1014
+ return $this->callServer("listMergeVars", $params);
1015
+ }
1016
+
1017
+ /**
1018
+ * Add a new merge tag to a given list
1019
+ *
1020
+ * @section List Related
1021
+ * @example xml-rpc_listMergeVarAdd.php
1022
+ *
1023
+ * @param string $id the list id to connect to. Get by calling lists()
1024
+ * @param string $tag The merge tag to add, e.g. FNAME
1025
+ * @param string $name The long description of the tag being added, used for user displays
1026
+ * @param array $req optional Various options for this merge var. <em>note:</em> for historical purposes this can also take a "boolean"
1027
+ string field_type optional one of: text, number, radio, dropdownn, date, address, phone, url, imageurl - defaults to text
1028
+ boolean req optional indicates whether the field is required - defaults to false
1029
+ boolean public optional indicates whether the field is displayed in public - defaults to true
1030
+ boolean show optional indicates whether the field is displayed in the app's list member view - defaults to true
1031
+ string default_value optional the default value for the field. See listSubscribe() for formatting info. Defaults to blank
1032
+ array choices optional kind of - an array of strings to use as the choices for radio and dropdown type fields
1033
+
1034
+ * @return bool true if the request succeeds, otherwise an error will be thrown
1035
+ */
1036
+ function listMergeVarAdd($id, $tag, $name, $req=array (
1037
+ )) {
1038
+ $params = array();
1039
+ $params["id"] = $id;
1040
+ $params["tag"] = $tag;
1041
+ $params["name"] = $name;
1042
+ $params["req"] = $req;
1043
+ return $this->callServer("listMergeVarAdd", $params);
1044
+ }
1045
+
1046
+ /**
1047
+ * Update most parameters for a merge tag on a given list. You cannot currently change the merge type
1048
+ *
1049
+ * @section List Related
1050
+ *
1051
+ * @param string $id the list id to connect to. Get by calling lists()
1052
+ * @param string $tag The merge tag to update
1053
+ * @param array $options The options to change for a merge var. See listMergeVarAdd() for valid options
1054
+ * @return bool true if the request succeeds, otherwise an error will be thrown
1055
+ */
1056
+ function listMergeVarUpdate($id, $tag, $options) {
1057
+ $params = array();
1058
+ $params["id"] = $id;
1059
+ $params["tag"] = $tag;
1060
+ $params["options"] = $options;
1061
+ return $this->callServer("listMergeVarUpdate", $params);
1062
+ }
1063
+
1064
+ /**
1065
+ * Delete a merge tag from a given list and all its members. Seriously - the data is removed from all members as well!
1066
+ * Note that on large lists this method may seem a bit slower than calls you typically make.
1067
+ *
1068
+ * @section List Related
1069
+ * @example xml-rpc_listMergeVarDel.php
1070
+ *
1071
+ * @param string $id the list id to connect to. Get by calling lists()
1072
+ * @param string $tag The merge tag to delete
1073
+ * @return bool true if the request succeeds, otherwise an error will be thrown
1074
+ */
1075
+ function listMergeVarDel($id, $tag) {
1076
+ $params = array();
1077
+ $params["id"] = $id;
1078
+ $params["tag"] = $tag;
1079
+ return $this->callServer("listMergeVarDel", $params);
1080
+ }
1081
+
1082
+ /**
1083
+ * Get the list of interest groups for a given list, including the label and form information
1084
+ *
1085
+ * @section List Related
1086
+ * @example xml-rpc_listInterestGroups.php
1087
+ *
1088
+ * @param string $id the list id to connect to. Get by calling lists()
1089
+ * @return struct list of interest groups for the list
1090
+ * @returnf string name Name for the Interest groups
1091
+ * @returnf string form_field Gives the type of interest group: checkbox,radio,select
1092
+ * @returnf array groups Array of the group names
1093
+ */
1094
+ function listInterestGroups($id) {
1095
+ $params = array();
1096
+ $params["id"] = $id;
1097
+ return $this->callServer("listInterestGroups", $params);
1098
+ }
1099
+
1100
+ /** Add a single Interest Group - if interest groups for the List are not yet enabled, adding the first
1101
+ * group will automatically turn them on.
1102
+ *
1103
+ * @section List Related
1104
+ * @example xml-rpc_listInterestGroupAdd.php
1105
+ *
1106
+ * @param string $id the list id to connect to. Get by calling lists()
1107
+ * @param string $group_name the interest group to add
1108
+ * @return bool true if the request succeeds, otherwise an error will be thrown
1109
+ */
1110
+ function listInterestGroupAdd($id, $group_name) {
1111
+ $params = array();
1112
+ $params["id"] = $id;
1113
+ $params["group_name"] = $group_name;
1114
+ return $this->callServer("listInterestGroupAdd", $params);
1115
+ }
1116
+
1117
+ /** Delete a single Interest Group - if the last group for a list is deleted, this will also turn groups for the list off.
1118
+ *
1119
+ * @section List Related
1120
+ * @example xml-rpc_listInterestGroupDel.php
1121
+ *
1122
+ * @param string $id the list id to connect to. Get by calling lists()
1123
+ * @param string $group_name the interest group to delete
1124
+ * @return bool true if the request succeeds, otherwise an error will be thrown
1125
+ */
1126
+ function listInterestGroupDel($id, $group_name) {
1127
+ $params = array();
1128
+ $params["id"] = $id;
1129
+ $params["group_name"] = $group_name;
1130
+ return $this->callServer("listInterestGroupDel", $params);
1131
+ }
1132
+
1133
+ /** Change the name of an Interest Group
1134
+ *
1135
+ * @section List Related
1136
+ *
1137
+ * @param string $id the list id to connect to. Get by calling lists()
1138
+ * @param string $old_name the interest group name to be changed
1139
+ * @param string $new_name the new interest group name to be set
1140
+ * @return bool true if the request succeeds, otherwise an error will be thrown
1141
+ */
1142
+ function listInterestGroupUpdate($id, $old_name, $new_name) {
1143
+ $params = array();
1144
+ $params["id"] = $id;
1145
+ $params["old_name"] = $old_name;
1146
+ $params["new_name"] = $new_name;
1147
+ return $this->callServer("listInterestGroupUpdate", $params);
1148
+ }
1149
+
1150
+ /** Return the Webhooks configured for the given list
1151
+ *
1152
+ * @section List Related
1153
+ *
1154
+ * @param string $id the list id to connect to. Get by calling lists()
1155
+ * @return array list of webhooks
1156
+ * @returnf string url the URL for this Webhook
1157
+ * @returnf array actions the possible actions and whether they are enabled
1158
+ * @returnf array sources the possible sources and whether they are enabled
1159
+ */
1160
+ function listWebhooks($id) {
1161
+ $params = array();
1162
+ $params["id"] = $id;
1163
+ return $this->callServer("listWebhooks", $params);
1164
+ }
1165
+
1166
+ /** Add a new Webhook URL for the given list
1167
+ *
1168
+ * @section List Related
1169
+ *
1170
+ * @param string $id the list id to connect to. Get by calling lists()
1171
+ * @param string $url a valid URL for the Webhook - it will be validated. note that a url may only exist on a list once.
1172
+ * @param array $actions optional a hash of actions to fire this Webhook for
1173
+ boolean subscribe optional as subscribes occur, defaults to true
1174
+ boolean unsubscribe optional as subscribes occur, defaults to true
1175
+ boolean profile optional as profile updates occur, defaults to true
1176
+ boolean cleaned optional as emails are cleaned from the list, defaults to true
1177
+ boolean upemail optional when subscribers change their email address, defaults to true
1178
+ * @param array $sources optional a hash of sources to fire this Webhook for
1179
+ boolean user optional user/subscriber initiated actions, defaults to true
1180
+ boolean admin optional admin actions in our web app, defaults to true
1181
+ boolean api optional actions that happen via API calls, defaults to false
1182
+ * @return bool true if the call succeeds, otherwise an exception will be thrown
1183
+ */
1184
+ function listWebhookAdd($id, $url, $actions=array (
1185
+ ), $sources=array (
1186
+ )) {
1187
+ $params = array();
1188
+ $params["id"] = $id;
1189
+ $params["url"] = $url;
1190
+ $params["actions"] = $actions;
1191
+ $params["sources"] = $sources;
1192
+ return $this->callServer("listWebhookAdd", $params);
1193
+ }
1194
+
1195
+ /** Delete an existing Webhook URL from a given list
1196
+ *
1197
+ * @section List Related
1198
+ *
1199
+ * @param string $id the list id to connect to. Get by calling lists()
1200
+ * @param string $url the URL of a Webhook on this list
1201
+ * @return boolean true if the call succeeds, otherwise an exception will be thrown
1202
+ */
1203
+ function listWebhookDel($id, $url) {
1204
+ $params = array();
1205
+ $params["id"] = $id;
1206
+ $params["url"] = $url;
1207
+ return $this->callServer("listWebhookDel", $params);
1208
+ }
1209
+
1210
+ /**
1211
+ * Subscribe the provided email to a list. By default this sends a confirmation email - you will not see new members until the link contained in it is clicked!
1212
+ *
1213
+ * @section List Related
1214
+ *
1215
+ * @example mcapi_listSubscribe.php
1216
+ * @example xml-rpc_listSubscribe.php
1217
+ *
1218
+ * @param string $id the list id to connect to. Get by calling lists()
1219
+ * @param string $email_address the email address to subscribe
1220
+ * @param array $merge_vars array of merges for the email (FNAME, LNAME, etc.) (see examples below for handling "blank" arrays). Note that a merge field can only hold up to 255 characters. Also, there are a few "special" keys:
1221
+ string EMAIL set this to change the email address. This is only respected on calls using update_existing or when passed to listUpdateMember()
1222
+ string INTERESTS Set Interest Groups by passing a field named "INTERESTS" that contains a comma delimited list of Interest Groups to add. Commas in Interest Group names should be escaped with a backslash. ie, "," =&gt; "\,"
1223
+ string OPTINIP Set the Opt-in IP fields. <em>Abusing this may cause your account to be suspended.</em> We do validate this and it must not be a private IP address.
1224
+
1225
+ <strong>Handling Field Data Types</strong> - most fields you can just pass a string and all is well. For some, though, that is not the case...
1226
+ Field values should be formatted as follows:
1227
+ string address For the string version of an Address, the fields should be delimited by <strong>2</strong> spaces. Address 2 can be skipped. The Country should be a 2 character ISO-3166-1 code and will default to your default country if not set
1228
+ array address For the array version of an Address, the requirements for Address 2 and Country are the same as with the string version. Then simply pass us an array with the keys <strong>addr1</strong>, <strong>addr2</strong>, <strong>city</strong>, <strong>state</strong>, <strong>zip</strong>, <strong>country</strong> and appropriate values for each
1229
+
1230
+ string date use YYYY-MM-DD to be safe. Generally, though, anything strtotime() understands we'll understand - <a href="http://us2.php.net/strtotime" target="_blank">http://us2.php.net/strtotime</a>
1231
+ string dropdown can be a normal string - we <em>will</em> validate that the value is a valid option
1232
+ string image must be a valid, existing url. we <em>will</em> check its existence
1233
+ string multi_choice can be a normal string - we <em>will</em> validate that the value is a valid option
1234
+ double number pass in a valid number - anything else will turn in to zero (0). Note, this will be rounded to 2 decimal places
1235
+ string phone If your account has the US Phone numbers option set, this <em>must</em> be in the form of NPA-NXX-LINE (404-555-1212). If not, we assume an International number and will simply set the field with what ever number is passed in.
1236
+ string website This is a standard string, but we <em>will</em> verify that it looks like a valid URL
1237
+
1238
+
1239
+
1240
+ * @param string $email_type optional - email type preference for the email (html, text, or mobile defaults to html)
1241
+ * @param boolean $double_optin optional - flag to control whether a double opt-in confirmation message is sent, defaults to true. <em>Abusing this may cause your account to be suspended.</em>
1242
+ * @param boolean $update_existing optional - flag to control whether a existing subscribers should be updated instead of throwing and error
1243
+ * @param boolean $replace_interests - flag to determine whether we replace the interest groups with the groups provided, or we add the provided groups to the member's interest groups (optional, defaults to true)
1244
+ * @param boolean $send_welcome - if your double_optin is false and this is true, we will send your lists Welcome Email if this subscribe succeeds - this will *not* fire if we end up updating an existing subscriber. If double_optin is true, this has no effect. defaults to false.
1245
+
1246
+ * @return boolean true on success, false on failure. When using MCAPI.class.php, the value can be tested and error messages pulled from the MCAPI object (see below)
1247
+ */
1248
+ function listSubscribe($id, $email_address, $merge_vars, $email_type='html', $double_optin=true, $update_existing=false, $replace_interests=true, $send_welcome=false) {
1249
+ $params = array();
1250
+ $params["id"] = $id;
1251
+ $params["email_address"] = $email_address;
1252
+ $params["merge_vars"] = $merge_vars;
1253
+ $params["email_type"] = $email_type;
1254
+ $params["double_optin"] = $double_optin;
1255
+ $params["update_existing"] = $update_existing;
1256
+ $params["replace_interests"] = $replace_interests;
1257
+ $params["send_welcome"] = $send_welcome;
1258
+ return $this->callServer("listSubscribe", $params);
1259
+ }
1260
+
1261
+ /**
1262
+ * Unsubscribe the given email address from the list
1263
+ *
1264
+ * @section List Related
1265
+ * @example mcapi_listUnsubscribe.php
1266
+ * @example xml-rpc_listUnsubscribe.php
1267
+ *
1268
+ * @param string $id the list id to connect to. Get by calling lists()
1269
+ * @param string $email_address the email address to unsubscribe OR the email "id" returned from listMemberInfo, Webhooks, and Campaigns
1270
+ * @param boolean $delete_member flag to completely delete the member from your list instead of just unsubscribing, default to false
1271
+ * @param boolean $send_goodbye flag to send the goodbye email to the email address, defaults to true
1272
+ * @param boolean $send_notify flag to send the unsubscribe notification email to the address defined in the list email notification settings, defaults to true
1273
+ * @return boolean true on success, false on failure. When using MCAPI.class.php, the value can be tested and error messages pulled from the MCAPI object (see below)
1274
+ */
1275
+ function listUnsubscribe($id, $email_address, $delete_member=false, $send_goodbye=true, $send_notify=true) {
1276
+ $params = array();
1277
+ $params["id"] = $id;
1278
+ $params["email_address"] = $email_address;
1279
+ $params["delete_member"] = $delete_member;
1280
+ $params["send_goodbye"] = $send_goodbye;
1281
+ $params["send_notify"] = $send_notify;
1282
+ return $this->callServer("listUnsubscribe", $params);
1283
+ }
1284
+
1285
+ /**
1286
+ * Edit the email address, merge fields, and interest groups for a list member
1287
+ *
1288
+ * @section List Related
1289
+ * @example mcapi_listUpdateMember.php
1290
+ *
1291
+ * @param string $id the list id to connect to. Get by calling lists()
1292
+ * @param string $email_address the current email address of the member to update OR the "id" for the member returned from listMemberInfo, Webhooks, and Campaigns
1293
+ * @param array $merge_vars array of new field values to update the member with. See merge_vars in listSubscribe() for details.
1294
+ * @param string $email_type change the email type preference for the member ("html", "text", or "mobile"). Leave blank to keep the existing preference (optional)
1295
+ * @param boolean $replace_interests flag to determine whether we replace the interest groups with the updated groups provided, or we add the provided groups to the member's interest groups (optional, defaults to true)
1296
+ * @return boolean true on success, false on failure. When using MCAPI.class.php, the value can be tested and error messages pulled from the MCAPI object
1297
+ */
1298
+ function listUpdateMember($id, $email_address, $merge_vars, $email_type='', $replace_interests=true) {
1299
+ $params = array();
1300
+ $params["id"] = $id;
1301
+ $params["email_address"] = $email_address;
1302
+ $params["merge_vars"] = $merge_vars;
1303
+ $params["email_type"] = $email_type;
1304
+ $params["replace_interests"] = $replace_interests;
1305
+ return $this->callServer("listUpdateMember", $params);
1306
+ }
1307
+
1308
+ /**
1309
+ * Subscribe a batch of email addresses to a list at once. If you are using a serialized version of the API, we strongly suggest that you
1310
+ * only run this method as a POST request, and <em>not</em> a GET request.
1311
+ *
1312
+ * @section List Related
1313
+ *
1314
+ * @example mcapi_listBatchSubscribe.php
1315
+ * @example xml-rpc_listBatchSubscribe.php
1316
+ *
1317
+ * @param string $id the list id to connect to. Get by calling lists()
1318
+ * @param array $batch an array of structs for each address to import with two special keys: "EMAIL" for the email address, and "EMAIL_TYPE" for the email type option (html, text, or mobile)
1319
+ * @param boolean $double_optin flag to control whether to send an opt-in confirmation email - defaults to true
1320
+ * @param boolean $update_existing flag to control whether to update members that are already subscribed to the list or to return an error, defaults to false (return error)
1321
+ * @param boolean $replace_interests flag to determine whether we replace the interest groups with the updated groups provided, or we add the provided groups to the member's interest groups (optional, defaults to true)
1322
+ * @return struct Array of result counts and any errors that occurred
1323
+ * @returnf integer success_count Number of email addresses that were succesfully added/updated
1324
+ * @returnf integer error_count Number of email addresses that failed during addition/updating
1325
+ * @returnf array errors Array of error structs. Each error struct will contain "code", "message", and the full struct that failed
1326
+ */
1327
+ function listBatchSubscribe($id, $batch, $double_optin=true, $update_existing=false, $replace_interests=true) {
1328
+ $params = array();
1329
+ $params["id"] = $id;
1330
+ $params["batch"] = $batch;
1331
+ $params["double_optin"] = $double_optin;
1332
+ $params["update_existing"] = $update_existing;
1333
+ $params["replace_interests"] = $replace_interests;
1334
+ return $this->callServer("listBatchSubscribe", $params);
1335
+ }
1336
+
1337
+ /**
1338
+ * Unsubscribe a batch of email addresses to a list
1339
+ *
1340
+ * @section List Related
1341
+ * @example mcapi_listBatchUnsubscribe.php
1342
+ *
1343
+ * @param string $id the list id to connect to. Get by calling lists()
1344
+ * @param array $emails array of email addresses to unsubscribe
1345
+ * @param boolean $delete_member flag to completely delete the member from your list instead of just unsubscribing, default to false
1346
+ * @param boolean $send_goodbye flag to send the goodbye email to the email addresses, defaults to true
1347
+ * @param boolean $send_notify flag to send the unsubscribe notification email to the address defined in the list email notification settings, defaults to false
1348
+ * @return struct Array of result counts and any errors that occurred
1349
+ * @returnf integer success_count Number of email addresses that were succesfully added/updated
1350
+ * @returnf integer error_count Number of email addresses that failed during addition/updating
1351
+ * @returnf array errors Array of error structs. Each error struct will contain "code", "message", and "email"
1352
+ */
1353
+ function listBatchUnsubscribe($id, $emails, $delete_member=false, $send_goodbye=true, $send_notify=false) {
1354
+ $params = array();
1355
+ $params["id"] = $id;
1356
+ $params["emails"] = $emails;
1357
+ $params["delete_member"] = $delete_member;
1358
+ $params["send_goodbye"] = $send_goodbye;
1359
+ $params["send_notify"] = $send_notify;
1360
+ return $this->callServer("listBatchUnsubscribe", $params);
1361
+ }
1362
+
1363
+ /**
1364
+ * Get all of the list members for a list that are of a particular status
1365
+ *
1366
+ * @section List Related
1367
+ * @example mcapi_listMembers.php
1368
+ *
1369
+ * @param string $id the list id to connect to. Get by calling lists()
1370
+ * @param string $status the status to get members for - one of(subscribed, unsubscribed, cleaned, updated), defaults to subscribed
1371
+ * @param string $since optional pull all members whose status (subscribed/unsubscribed/cleaned) has changed or whose profile (updated) has changed since this date/time (in GMT) - format is YYYY-MM-DD HH:mm:ss (24hr)
1372
+ * @param integer $start optional for large data sets, the page number to start at - defaults to 1st page of data (page 0)
1373
+ * @param integer $limit optional for large data sets, the number of results to return - defaults to 100, upper limit set at 15000
1374
+ * @return array Array of list member structs (see Returned Fields for details)
1375
+ * @returnf string email Member email address
1376
+ * @returnf date timestamp timestamp of their associated status date (subscribed, unsubscribed, cleaned, or updated) in GMT
1377
+ */
1378
+ function listMembers($id, $status='subscribed', $since=NULL, $start=0, $limit=100) {
1379
+ $params = array();
1380
+ $params["id"] = $id;
1381
+ $params["status"] = $status;
1382
+ $params["since"] = $since;
1383
+ $params["start"] = $start;
1384
+ $params["limit"] = $limit;
1385
+ return $this->callServer("listMembers", $params);
1386
+ }
1387
+
1388
+ /**
1389
+ * Get all the information for a particular member of a list
1390
+ *
1391
+ * @section List Related
1392
+ * @example mcapi_listMemberInfo.php
1393
+ * @example xml-rpc_listMemberInfo.php
1394
+ *
1395
+ * @param string $id the list id to connect to. Get by calling lists()
1396
+ * @param string $email_address the member email address to get information for OR the "id" for the member returned from listMemberInfo, Webhooks, and Campaigns
1397
+ * @return array array of list member info (see Returned Fields for details)
1398
+ * @returnf string id The unique id for this email address on an account
1399
+ * @returnf string email The email address associated with this record
1400
+ * @returnf string email_type The type of emails this customer asked to get: html, text, or mobile
1401
+ * @returnf array merges An associative array of all the merge tags and the data for those tags for this email address. <em>Note</em>: Interest Groups are returned as comma delimited strings - if a group name contains a comma, it will be escaped with a backslash. ie, "," =&gt; "\,"
1402
+ * @returnf string status The subscription status for this email address, either subscribed, unsubscribed or cleaned
1403
+ * @returnf string ip_opt IP Address this address opted in from.
1404
+ * @returnf string ip_signup IP Address this address signed up from.
1405
+ * @returnf int member_rating the rating of the subscriber. This will be 1 - 5 as described <a href="http://eepurl.com/f-2P" target="_blank">here</a>
1406
+ * @returnf string campaign_id If the user is unsubscribed and they unsubscribed from a specific campaign, that campaign_id will be listed, otherwise this is not returned.
1407
+ * @returnf array lists An associative array of the other lists this member belongs to - the key is the list id and the value is their status in that list.
1408
+ * @returnf date timestamp The time this email address was added to the list
1409
+ */
1410
+ function listMemberInfo($id, $email_address) {
1411
+ $params = array();
1412
+ $params["id"] = $id;
1413
+ $params["email_address"] = $email_address;
1414
+ return $this->callServer("listMemberInfo", $params);
1415
+ }
1416
+
1417
+ /**
1418
+ * Get all email addresses that complained about a given campaign
1419
+ *
1420
+ * @section List Related
1421
+ *
1422
+ * @example mcapi_listAbuseReports.php
1423
+ *
1424
+ * @param string $id the list id to pull abuse reports for (can be gathered using lists())
1425
+ * @param integer $start optional for large data sets, the page number to start at - defaults to 1st page of data (page 0)
1426
+ * @param integer $limit optional for large data sets, the number of results to return - defaults to 500, upper limit set at 1000
1427
+ * @param string $since optional pull only messages since this time - use YYYY-MM-DD HH:II:SS format in <strong>GMT</strong>
1428
+ * @return array reports the abuse reports for this campaign
1429
+ * @returnf string date date/time the abuse report was received and processed
1430
+ * @returnf string email the email address that reported abuse
1431
+ * @returnf string campaign_id the unique id for the campaign that reporte was made against
1432
+ * @returnf string type an internal type generally specifying the orginating mail provider - may not be useful outside of filling report views
1433
+ */
1434
+ function listAbuseReports($id, $start=0, $limit=500, $since=NULL) {
1435
+ $params = array();
1436
+ $params["id"] = $id;
1437
+ $params["start"] = $start;
1438
+ $params["limit"] = $limit;
1439
+ $params["since"] = $since;
1440
+ return $this->callServer("listAbuseReports", $params);
1441
+ }
1442
+
1443
+ /**
1444
+ * Access the Growth History by Month for a given list.
1445
+ *
1446
+ * @section List Related
1447
+ *
1448
+ * @example mcapi_listGrowthHistory.php
1449
+ *
1450
+ * @param string $id the list id to connect to. Get by calling lists()
1451
+ * @return array array of months and growth
1452
+ * @returnf string month The Year and Month in question using YYYY-MM format
1453
+ * @returnf integer existing number of existing subscribers to start the month
1454
+ * @returnf integer imports number of subscribers imported during the month
1455
+ * @returnf integer optins number of subscribers who opted-in during the month
1456
+ */
1457
+ function listGrowthHistory($id) {
1458
+ $params = array();
1459
+ $params["id"] = $id;
1460
+ return $this->callServer("listGrowthHistory", $params);
1461
+ }
1462
+
1463
+ /**
1464
+ * <strong>DEPRECATED:</strong> Retrieve your User Unique Id and your Affiliate link to display/use for
1465
+ * <a href="/monkeyrewards/" target="_blank">Monkey Rewards</a>. While
1466
+ * we don't use the User Id for any API functions, it can be useful if building up URL strings for things such as the profile editor and sub/unsub links.
1467
+ *
1468
+ * @section Helper
1469
+ *
1470
+ * @deprecated See getAccountDetails() for replacement
1471
+ *
1472
+ * @example mcapi_getAffiliateInfo.php
1473
+ * @example xml-rpc_getAffiliateInfo.php
1474
+ *
1475
+ * @return array containing your Affilliate Id and full link.
1476
+ * @returnf string user_id Your User Unique Id.
1477
+ * @returnf string url Your Monkey Rewards link for our Affiliate program
1478
+ */
1479
+ function getAffiliateInfo() {
1480
+ $params = array();
1481
+ return $this->callServer("getAffiliateInfo", $params);
1482
+ }
1483
+
1484
+ /**
1485
+ * Retrieve lots of account information including payments made, plan info, some account stats, installed modules,
1486
+ * contact info, and more. No private information like Credit Card numbers is available.
1487
+ *
1488
+ * @section Helper
1489
+ *
1490
+ * @return array containing the details for the account tied to this API Key
1491
+ * @returnf string username The Account username
1492
+ * @returnf string user_id The Account user unique id (for building some links)
1493
+ * @returnf bool is_trial Whether the Account is in Trial mode (can only send campaigns to less than 100 emails)
1494
+ * @returnf string timezone The timezone for the Account - default is "US/Eastern"
1495
+ * @returnf string plan_type Plan Type - "monthly", "payasyougo", or "free"
1496
+ * @returnf int plan_low <em>only for Monthly plans</em> - the lower tier for list size
1497
+ * @returnf int plan_high <em>only for Monthly plans</em> - the upper tier for list size
1498
+ * @returnf datetime plan_start_date <em>only for Monthly plans</em> - the start date for a monthly plan
1499
+ * @returnf int emails_left <em>only for Free and Pay-as-you-go plans</em> emails credits left for the account
1500
+ * @returnf bool pending_monthly Whether the account is finishing Pay As You Go credits before switching to a Monthly plan
1501
+ * @returnf datetime first_payment date of first payment
1502
+ * @returnf datetime last_payment date of most recent payment
1503
+ * @returnf int times_logged_in total number of times the account has been logged into via the web
1504
+ * @returnf datetime last_login date/time of last login via the web
1505
+ * @returnf string affiliate_link Monkey Rewards link for our Affiliate program
1506
+ * @returnf array contact Contact details for the account, including: First & Last name, email, company name, address, phone, and url
1507
+ * @returnf array addons Addons installed in the account and the date they were installed.
1508
+ * @returnf array orders Order details for the account, include order_id, type, cost, date/time, and any credits applied to the order
1509
+ * @returnf array rewards Rewards details for the account including credits & inspections earned, number of referals, referal details, and rewards used
1510
+ */
1511
+ function getAccountDetails() {
1512
+ $params = array();
1513
+ return $this->callServer("getAccountDetails", $params);
1514
+ }
1515
+
1516
+ /**
1517
+ * Have HTML content auto-converted to a text-only format. You can send: plain HTML, an array of Template content, an existing Campaign Id, or an existing Template Id. Note that this will <b>not</b> save anything to or update any of your lists, campaigns, or templates.
1518
+ *
1519
+ * @section Helper
1520
+ * @example xml-rpc_generateText.php
1521
+ *
1522
+ * @param string $type The type of content to parse. Must be one of: "html", "template", "url", "cid" (Campaign Id), or "tid" (Template Id)
1523
+ * @param mixed $content The content to use. For "html" expects a single string value, "template" expects an array like you send to campaignCreate, "url" expects a valid & public URL to pull from, "cid" expects a valid Campaign Id, and "tid" expects a valid Template Id on your account.
1524
+ * @return string the content pass in converted to text.
1525
+ */
1526
+ function generateText($type, $content) {
1527
+ $params = array();
1528
+ $params["type"] = $type;
1529
+ $params["content"] = $content;
1530
+ return $this->callServer("generateText", $params);
1531
+ }
1532
+
1533
+ /**
1534
+ * Send your HTML content to have the CSS inlined and optionally remove the original styles.
1535
+ *
1536
+ * @section Helper
1537
+ * @example xml-rpc_inlineCss.php
1538
+ *
1539
+ * @param string $html Your HTML content
1540
+ * @param bool $strip_css optional Whether you want the CSS &lt;style&gt; tags stripped from the returned document. Defaults to false.
1541
+ * @return string Your HTML content with all CSS inlined, just like if we sent it.
1542
+ */
1543
+ function inlineCss($html, $strip_css=false) {
1544
+ $params = array();
1545
+ $params["html"] = $html;
1546
+ $params["strip_css"] = $strip_css;
1547
+ return $this->callServer("inlineCss", $params);
1548
+ }
1549
+
1550
+ /**
1551
+ * Create a new folder to file campaigns in
1552
+ *
1553
+ * @section Helper
1554
+ * @example mcapi_createFolder.php
1555
+ * @example xml-rpc_createFolder.php
1556
+ *
1557
+ * @param string $name a unique name for a folder
1558
+ * @return integer the folder_id of the newly created folder.
1559
+ */
1560
+ function createFolder($name) {
1561
+ $params = array();
1562
+ $params["name"] = $name;
1563
+ return $this->callServer("createFolder", $params);
1564
+ }
1565
+
1566
+ /**
1567
+ * Import Ecommerce Order Information to be used for Segmentatio. This will generall be used by ecommerce package plugins
1568
+ * <a href="/plugins/ecomm360.phtml">that we provide</a> or by 3rd part system developers.
1569
+ * @section Helper
1570
+ *
1571
+ * @param array $order an array of information pertaining to the order that has completed. Use the following keys:
1572
+ string id the Order Id
1573
+ string email_id optional (kind of) the Email Id of the subscriber we should attach this order to (see the "mc_eid" query string variable a campaign passes) - either this or <strong>email</strong> is required. If both are provided, email_id takes precedence
1574
+ string email optional (kind of) the Email Address we should attach this order to - either this or <strong>email_id</strong> is required. If both are provided, email_id takes precedence
1575
+ double total The Order Total (ie, the full amount the customer ends up paying)
1576
+ string order_date optional the date of the order - if this is not provided, we will default the date to now
1577
+ double shipping optional the total paid for Shipping Fees
1578
+ double tax optional the total tax paid
1579
+ string store_id a unique id for the store sending the order in
1580
+ string store_name optional a "nice" name for the store - typically the base web address (ie, "store.mailchimp.com"). We will automatically update this if it changes (based on store_id)
1581
+ string plugin_id the MailChimp assigned Plugin Id. Get yours by <a href="/api/register.php">registering here</a>
1582
+ string campaign_id optional the Campaign Id to track this order with (see the "mc_cid" query string variable a campaign passes)
1583
+ array items the individual line items for an order using these keys:
1584
+ <div style="padding-left:30px"><table><tr><td colspan=*>
1585
+ integer line_num optional the line number of the item on the order. We will generate these if they are not passed
1586
+ integer product_id the store's internal Id for the product. Lines that do no contain this will be skipped
1587
+ string product_name the product name for the product_id associated with this item. We will auto update these as they change (based on product_id)
1588
+ integer category_id the store's internal Id for the (main) category associated with this product. Our testing has found this to be a "best guess" scenario
1589
+ string category_name the category name for the category_id this product is in. Our testing has found this to be a "best guess" scenario. Our plugins walk the category heirarchy up and send "Root - SubCat1 - SubCat4", etc.
1590
+ double qty the quantity of the item ordered
1591
+ double cost the cost of a single item (ie, not the extended cost of the line)
1592
+ </td></tr></table></div>
1593
+ * @return bool true if the data is saved, otherwise an error is thrown.
1594
+ */
1595
+ function ecommAddOrder($order) {
1596
+ $params = array();
1597
+ $params["order"] = $order;
1598
+ return $this->callServer("ecommAddOrder", $params);
1599
+ }
1600
+
1601
+ /**
1602
+ * Retrieve all List Ids a member is subscribed to.
1603
+ *
1604
+ * @section Helper
1605
+ *
1606
+ * @param string $email_address the email address to unsubscribe OR the email "id" returned from listMemberInfo, Webhooks, and Campaigns
1607
+ * @return array An array of list_ids the member is subscribed to.
1608
+ */
1609
+ function listsForEmail($email_address) {
1610
+ $params = array();
1611
+ $params["email_address"] = $email_address;
1612
+ return $this->callServer("listsForEmail", $params);
1613
+ }
1614
+
1615
+ /**
1616
+ * Return the current Chimp Chatter messages for an account.
1617
+ *
1618
+ * @section Helper
1619
+ *
1620
+ * @return array An array of chatter messages and properties
1621
+ * @returnf string message The chatter message
1622
+ * @returnf string type The type of the message - one of scheduled, sent, inspection, subscribes, unsubscribes, low_credits, absplit, best_opens, best_clicks, or abuse
1623
+ * @returnf string list_id the list_id a message relates to, if applicable
1624
+ * @returnf string campaign_id the list_id a message relates to, if applicable
1625
+ * @returnf string update_time The date/time the message was last updated
1626
+ */
1627
+ function chimpChatter() {
1628
+ $params = array();
1629
+ return $this->callServer("chimpChatter", $params);
1630
+ }
1631
+
1632
+ /**
1633
+ * Retrieve a list of all MailChimp API Keys for this User
1634
+ *
1635
+ * @section Security Related
1636
+ * @example xml-rpc_apikeyAdd.php
1637
+ * @example mcapi_apikeyAdd.php
1638
+ *
1639
+ * @param string $username Your MailChimp user name
1640
+ * @param string $password Your MailChimp password
1641
+ * @param boolean $expired optional - whether or not to include expired keys, defaults to false
1642
+ * @return array an array of API keys including:
1643
+ * @returnf string apikey The api key that can be used
1644
+ * @returnf string created_at The date the key was created
1645
+ * @returnf string expired_at The date the key was expired
1646
+ */
1647
+ function apikeys($username, $password, $expired=false) {
1648
+ $params = array();
1649
+ $params["username"] = $username;
1650
+ $params["password"] = $password;
1651
+ $params["expired"] = $expired;
1652
+ return $this->callServer("apikeys", $params);
1653
+ }
1654
+
1655
+ /**
1656
+ * Add an API Key to your account. We will generate a new key for you and return it.
1657
+ *
1658
+ * @section Security Related
1659
+ * @example xml-rpc_apikeyAdd.php
1660
+ *
1661
+ * @param string $username Your MailChimp user name
1662
+ * @param string $password Your MailChimp password
1663
+ * @return string a new API Key that can be immediately used.
1664
+ */
1665
+ function apikeyAdd($username, $password) {
1666
+ $params = array();
1667
+ $params["username"] = $username;
1668
+ $params["password"] = $password;
1669
+ return $this->callServer("apikeyAdd", $params);
1670
+ }
1671
+
1672
+ /**
1673
+ * Expire a Specific API Key. Note that if you expire all of your keys, just visit <a href="http://admin.mailchimp.com/account/api" target="_blank">your API dashboard</a>
1674
+ * to create a new one. If you are trying to shut off access to your account for an old developer, change your
1675
+ * MailChimp password, then expire all of the keys they had access to. Note that this takes effect immediately, so make
1676
+ * sure you replace the keys in any working application before expiring them! Consider yourself warned...
1677
+ *
1678
+ * @section Security Related
1679
+ * @example mcapi_apikeyExpire.php
1680
+ * @example xml-rpc_apikeyExpire.php
1681
+ *
1682
+ * @param string $username Your MailChimp user name
1683
+ * @param string $password Your MailChimp password
1684
+ * @return boolean true if it worked, otherwise an error is thrown.
1685
+ */
1686
+ function apikeyExpire($username, $password) {
1687
+ $params = array();
1688
+ $params["username"] = $username;
1689
+ $params["password"] = $password;
1690
+ return $this->callServer("apikeyExpire", $params);
1691
+ }
1692
+
1693
+ /**
1694
+ * "Ping" the MailChimp API - a simple method you can call that will return a constant value as long as everything is good. Note
1695
+ * than unlike most all of our methods, we don't throw an Exception if we are having issues. You will simply receive a different
1696
+ * string back that will explain our view on what is going on.
1697
+ *
1698
+ * @section Helper
1699
+ * @example xml-rpc_ping.php
1700
+ *
1701
+ * @return string returns "Everything's Chimpy!" if everything is chimpy, otherwise returns an error message
1702
+ */
1703
+ function ping() {
1704
+ $params = array();
1705
+ return $this->callServer("ping", $params);
1706
+ }
1707
+
1708
+ /**
1709
+ * Internal function - proxy method for certain XML-RPC calls | DO NOT CALL
1710
+ * @param mixed Method to call, with any parameters to pass along
1711
+ * @return mixed the result of the call
1712
+ */
1713
+ function callMethod() {
1714
+ $params = array();
1715
+ return $this->callServer("callMethod", $params);
1716
+ }
1717
+
1718
+ /**
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
+ */
1794
+ function httpBuildQuery($params, $key=null) {
1795
+ $ret = array();
1796
+
1797
+ foreach((array) $params as $name => $val) {
1798
+ $name = urlencode($name);
1799
+ if($key !== null) {
1800
+ $name = $key . "[" . $name . "]";
1801
+ }
1802
+
1803
+ if(is_array($val) || is_object($val)) {
1804
+ $ret[] = $this->httpBuildQuery($val, $name);
1805
+ } elseif($val !== null) {
1806
+ $ret[] = $name . "=" . urlencode($val);
1807
+ }
1808
+ }
1809
+
1810
+ return implode("&", $ret);
1811
+ }
1812
+ }
1813
+
1814
+ ?>
includes/menu-pages/api-ops.inc.php CHANGED
@@ -36,7 +36,7 @@ echo '<div class="ws-menu-page-group" title="Signup Notifications">' . "\n";
36
  /**/
37
  echo '<div class="ws-menu-page-section ws-plugin--s2member-signup-notifications-section">' . "\n";
38
  echo '<h3>Signup Notification URLs ( optional )</h3>' . "\n";
39
- echo '<p>If you use affiliate software, or have back-office routines that need to be notified whenever a new subscription is created, you\'ll want to read this section. This is marked `Signup`, because the URLs that you list below will be notified each time a user signs up. Depending on your fee structure, this may include a first initial payment that establishes their subscription. This notification will only be triggered once for each user. Signup notifications are sent just after a user signs up successfully through PayPal®, regardless of whether any money has actually been received. In other words, this notification is triggered anytime a user signs up, even if you provided them with a free trial. Please note, this feature is not to be confused with the PayPal® IPN service. PayPal® IPN integration is already built into s2Member and remains active at all times. These Signup Notifications are an added layer of functionality, and they are completely optional; used primarily in affiliate program integration &amp; other back-office routines.</p>' . "\n";
40
  /**/
41
  echo '<table class="form-table">' . "\n";
42
  echo '<tbody>' . "\n";
@@ -54,26 +54,77 @@ 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-scenes, 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 ( 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 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";
61
- echo '<li><code>%%initial%% = The initial fee charged during signup, in USD. If you offered a free trial, this will be 0.</code> [ <a href="#" onclick="alert(\'If no initial period was offered or required, this initial amount will be equal to the %%regular%% rate. In other words, this will always represent the amount of money the customer spent whenever they signed up, no matter what.\\n\\nIf a user signs up under the terms of a free trial period, this will be 0. So be careful using this value with 3rd party affiliate integrations because a $0 sale amount could cause havoc. If you have a lot of trouble, try using the %%regular%% amount, or use the `Payment` notifications instead of the `Signup` notifications.\'); return false;">?</a> ]</li>' . "\n";
62
- echo '<li><code>%%regular%% = The regular amount of the subscription in USD. This dollar value is always > 0, no matter what.</code> [ <a href="#" onclick="alert(\'This is how much the subscription costs after an initial period expires. The %%regular%% rate is always > 0. If you did not offer an initial period, %%initial%% and %%regular%% will be equal to the same thing.\'); return false;">?</a> ]</li>' . "\n";
63
- echo '<li><code>%%recurring%% = This is the amount in USD that will be charged on a recurring basis, or 0 if non-recurring.</code> [ <a href="#" onclick="alert(\'If recurring payments have not been required, this will be equal to 0. That being said, %%regular%% &amp; %%recurring%% are usually the same value. This variable can be used in two different ways. You can use it to determine what the regular recurring rate is, or to determine whether the subscription will recur or not. If it is going to recur, %%recurring%% will be > 0.\\n\\nThe only time this is NOT equal to the %%regular%% rate, is when recurring payments are not required; and only a one-time regular rate applies. If you have trouble, try using the %%regular%% amount, or use the `Payment` notifications instead of the `Signup` notifications.\'); return false;">?</a> ]</li>' . "\n";
64
- echo '<li><code>%%first_name%% = The first name of the customer who purchased the membership subscription through PayPal®.</code></li>' . "\n";
65
- echo '<li><code>%%last_name%% = The last name of the customer who purchased the membership subscription through PayPal®.</code></li>' . "\n";
66
- echo '<li><code>%%full_name%% = The full name ( first & last ) of the customer who purchased the membership subscription.</code></li>' . "\n";
67
- echo '<li><code>%%payer_email%% = The email address of the customer who purchased the membership subscription through PayPal®.</code></li>' . "\n";
68
- echo '<li><code>%%item_number%% = The item number ( in other words, the membership level: 1, 2, 3 or 4 ) that the subscription is for.</code></li>' . "\n";
69
- echo '<li><code>%%item_name%% = The item name ( in other words, the associated membership level label that briefly describes the item number ).</code></li>' . "\n";
70
  echo '<li><code>%%initial_term%% = This is the term length of the initial period. This will be a numeric value, followed by a space, then a single letter.</code> [ <a href="#" onclick="alert(\'Here are some examples:\\n\\n%%initial_term%% = 1 D ( this means 1 Day )\\n%%initial_term%% = 1 M ( this means 1 Month )\\n%%initial_term%% = 1 Y ( this means 1 Year )\\n\\nThe initial period never recurs, so this only lasts for the term length specified, then it is over. If no initial period was even offered, the value of %%initial_term%% will just be: 0 D, meaning zero days.\'); return false;">?</a> ]</li>' . "\n";
71
- echo '<li><code>%%regular_term%% = This is the term length of the regular period. This will be a numeric value, followed by a space, then a single letter.</code> [ <a href="#" onclick="alert(\'Here are some examples:\\n\\n%%regular_term%% = 1 D ( this means 1 Day )\\n%%regular_term%% = 1 M ( this means 1 Month )\\n%%regular_term%% = 1 Y ( this means 1 Year )\\n%%regular_term%% = 1 L ( this means 1 Lifetime )\\n\\nThe regular term is usually recurring. So the regular term value represents the period ( or duration ) of each recurring period. If %%recurring%% = 0, then the regular term only applies once, because it is not recurring. So if it is not recurring, the value of %%regular_term%% simply represents how long their membership priviledges are going to last after the %%initial_term%% has expired, if there was an initial term. The value of this variable ( %%regular_term%% ) will never be empty, it will always be at least: 1 D, meaning 1 day. No exceptions.\'); return false;">?</a> ]</li>' . "\n";
72
  echo '</ul>' . "\n";
73
  echo '<strong>Custom replacement codes can also be inserted using these instructions:</strong>' . "\n";
74
  echo '<ul>' . "\n";
75
- echo '<li><code>%%cv0%% = The domain of your site, which is passed through to PayPal® using the `custom` field in your PayPal® button code.</code></li>' . "\n";
76
- echo '<li><code>%%cv1%% = If you need to track additional custom variables, you can pipe delimit them into the `custom` field of your button code like this: &lt;input type="hidden" name="custom" value="' . $_SERVER["HTTP_HOST"] . '|cv1|cv2|cv3" /&gt;. You can have an unlimited number of custom variables that track IP addresses, affiliate IDs, etc. In some cases you may need to use PHP code to insert a value into the custom field dynamically. Obviously this is for advanced webmasters, but the functionality has been made available for those who need it.</li>' . "\n";
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
77
  echo '</ul>' . "\n";
78
  echo '<strong>This example uses cv1 to track a user\'s IP address:</strong><br />' . "\n";
79
  echo '<em>( The IP address can be referenced in your notification URL using %%cv1%% )</em><br />' . "\n";
@@ -91,7 +142,7 @@ echo '<div class="ws-menu-page-group" title="Payment Notifications">' . "\n";
91
  /**/
92
  echo '<div class="ws-menu-page-section ws-plugin--s2member-payment-notifications-section">' . "\n";
93
  echo '<h3>Payment Notification URLs ( optional )</h3>' . "\n";
94
- echo '<p>If you use affiliate software, or have back-office routines that need to be notified whenever payment transactions take place, and/or for recurring payments, you\'ll want to read this section. This is marked `Payment`, because the URLs that you list below will be notified each time an actual payment occurs. Depending on your fee structure, this may include a first initial payment that establishes a subscription. But more importantly, this will be triggered on all future payments that are received for the lifetime of the subscription. So unlike the `Signup` notification, `Payment` notifications take place whenever actual payments are received, instead of just once after signup is completed. If a payment is required during signup ( e.g. no free trial is being offered ), a signup notification will be triggered, and a payment notification will ALSO be triggered. In other words, a payment notification occurs anytime funds are received, no matter what. Please note, this feature is not to be confused with the PayPal® IPN service. PayPal® IPN integration is already built into s2Member and remains active at all times. These Payment Notifications are an added layer of functionality, and they are completely optional; used primarily in affiliate program integration &amp; other back-office routines.</p>' . "\n";
95
  /**/
96
  echo '<table class="form-table">' . "\n";
97
  echo '<tbody>' . "\n";
@@ -109,23 +160,23 @@ 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_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";
112
- echo 'Payment notifications take place silently behind-the-scenes, using a cURL connection. Each URL will be notified every time an initial and/or recurring payment occurs.<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>%%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 ( 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 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";
116
  echo '<li><code>%%txn_id%% = The PayPal® unique Transaction ID, which is always unique for each payment received.</code></li>' . "\n";
117
- echo '<li><code>%%amount%% = The amount of the payment in USD. Most affiliate programs calculate commissions from this.</code></li>' . "\n";
118
- echo '<li><code>%%first_name%% = The first name of the customer who purchased the membership subscription through PayPal®.</code></li>' . "\n";
119
- echo '<li><code>%%last_name%% = The last name of the customer who purchased the membership subscription through PayPal®.</code></li>' . "\n";
120
- echo '<li><code>%%full_name%% = The full name ( first & last ) of the customer who purchased the membership subscription.</code></li>' . "\n";
121
- echo '<li><code>%%payer_email%% = The email address of the customer who purchased the membership subscription through PayPal®.</code></li>' . "\n";
122
- echo '<li><code>%%item_number%% = The item number ( in other words, the membership level: 1, 2, 3 or 4 ) that the payment is for.</code></li>' . "\n";
123
- echo '<li><code>%%item_name%% = The item name ( in other words, the associated membership level label that briefly describes the item number ).</code></li>' . "\n";
124
  echo '</ul>' . "\n";
125
  echo '<strong>Custom replacement codes can also be inserted using these instructions:</strong>' . "\n";
126
  echo '<ul>' . "\n";
127
- echo '<li><code>%%cv0%% = The domain of your site, which is passed through to PayPal® using the `custom` field in your PayPal® button code.</code></li>' . "\n";
128
- echo '<li><code>%%cv1%% = If you need to track additional custom variables, you can pipe delimit them into the `custom` field of your button code like this: &lt;input type="hidden" name="custom" value="' . $_SERVER["HTTP_HOST"] . '|cv1|cv2|cv3" /&gt;. You can have an unlimited number of custom variables that track IP addresses, affiliate IDs, etc. In some cases you may need to use PHP code to insert a value into the custom field dynamically. Obviously this is for advanced webmasters, but the functionality has been made available for those who need it.</li>' . "\n";
129
  echo '</ul>' . "\n";
130
  echo '<strong>This example uses cv1 to track a user\'s IP address:</strong><br />' . "\n";
131
  echo '<em>( The IP address can be referenced in your notification URL using %%cv1%% )</em><br />' . "\n";
@@ -143,9 +194,9 @@ echo '<div class="ws-menu-page-group" title="EOT/Deletion Notifications">' . "\n
143
  /**/
144
  echo '<div class="ws-menu-page-section ws-plugin--s2member-eot-deletion-notifications-section">' . "\n";
145
  echo '<h3>EOT/Deletion Notification URLs ( optional )</h3>' . "\n";
146
- echo '<p>If you use affiliate software, or have back-office routines that need to be notified whenever subscriptions have ended, or when an account is deleted from the system otherwise, you\'ll want to read this section. This is marked `EOT/Deletion`, because the URLs that you list below will be notified in both cases. EOT = End Of Term. An EOT is triggered anytime you cancel or refund a subscription via PayPal®, or if a user cancels their own subscription through PayPal®, fails to make payments, etc. In other words, anytime a subscription reaches the end of its term because you issue a refund, a chargeback occurs, a cancellation occurs or failed payments force PayPal® to end their subscription, this is triggered.</p>' . "\n";
147
- echo '<p>EOTs are not necessarily triggered immediately after a cancellation takes place though. For example, 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 your site for another 15 days, and then on Feb 1st, the time they paid for has completely elapsed and that is when their account is automatically deleted from the system and an EOT notification is triggered. That being said, there are cases when an EOT is triggered immediately. For instance, if too many of their subscription payments fail at PayPal® ( more than 2 in a row ), an EOT will be issued immediately, also resulting in the automatic deletion of their account. If you log into your PayPal® account and issue a refund to an unhappy customer, their account will be automatically deleted, and an EOT is triggered immediately.</p>' . "\n";
148
- echo '<p>Manual Deletions are the other case in which these notifications will be triggered. If you delete an account manually from within your WordPress® Dashboard, your affiliate software will be notified automatically through this notification. So the two events are EOT and/or manual Deletion. Please note, this feature is not to be confused with the PayPal® IPN service. PayPal® IPN integration is already built into s2Member and remains active at all times. These EOT/Deletion Notifications are an added layer of functionality, and they are completely optional; used primarily in affiliate program integration &amp; other back-office routines.</p>' . "\n";
149
  /**/
150
  echo '<table class="form-table">' . "\n";
151
  echo '<tbody>' . "\n";
@@ -163,19 +214,19 @@ echo '<tr>' . "\n";
163
  echo '<td>' . "\n";
164
  echo 'You can input multiple notification URLs by inserting one per line.<br />' . "\n";
165
  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";
166
- echo 'EOT/Deletion notifications take place silently behind-the-scenes, using a cURL connection. Each URL will be notified every time a subscription reaches the end of its term or is deleted otherwise.<br /><br />' . "\n";
167
  echo '<strong>You can also use these special replacement codes if you need them:</strong>' . "\n";
168
  echo '<ul>' . "\n";
169
  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 ( 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 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";
170
- echo '<li><code>%%user_first_name%% = The first name listed on their user account. This might be different than what is on file at PayPal®.</code></li>' . "\n";
171
- echo '<li><code>%%user_last_name%% = The last name listed on their user account. This might be different than what is on file at PayPal®.</code></li>' . "\n";
172
- echo '<li><code>%%user_full_name%% = The full name listed on their user account. This might be different than what is on file at PayPal®.</code></li>' . "\n";
173
- echo '<li><code>%%user_email%% = The email address associated with their user account. This might be different than what is on file at PayPal®.</code></li>' . "\n";
174
  echo '</ul>' . "\n";
175
  echo '<strong>Custom replacement codes can also be inserted using these instructions:</strong>' . "\n";
176
  echo '<ul>' . "\n";
177
- echo '<li><code>%%cv0%% = The domain of your site, which is passed through to PayPal® using the `custom` field in your PayPal® button code.</code></li>' . "\n";
178
- echo '<li><code>%%cv1%% = If you need to track additional custom variables, you can pipe delimit them into the `custom` field of your button code like this: &lt;input type="hidden" name="custom" value="' . $_SERVER["HTTP_HOST"] . '|cv1|cv2|cv3" /&gt;. You can have an unlimited number of custom variables that track IP addresses, affiliate IDs, etc. In some cases you may need to use PHP code to insert a value into the custom field dynamically. Obviously this is for advanced webmasters, but the functionality has been made available for those who need it.</li>' . "\n";
179
  echo '</ul>' . "\n";
180
  echo '<strong>This example uses cv1 to track a user\'s IP address:</strong><br />' . "\n";
181
  echo '<em>( The IP address can be referenced in your notification URL using %%cv1%% )</em><br />' . "\n";
@@ -193,8 +244,8 @@ echo '<div class="ws-menu-page-group" title="Refund/Reversal Notifications">' .
193
  /**/
194
  echo '<div class="ws-menu-page-section ws-plugin--s2member-refund-reversal-notifications-section">' . "\n";
195
  echo '<h3>Refund/Reversal Notification URLs ( optional )</h3>' . "\n";
196
- echo '<p>If you use affiliate software, or have back-office routines that need to be notified whenever subscriptions have been refunded or reversed ( e.g. charged back to you ), you\'ll want to read this section. This is marked `Refund/Reversal`, because the URLs that you list below will ONLY be notified in those specific cases, as opposed to the EOT notifications, which are all inclusive. This is very similar to the EOT/Deletion decribed above. But, there is an important distinction. EOT includes cancellations, expirations, failed payments, refunds, chargebacks, etc, etc. In other words, ANY time a deletion or End Of Term action takes place.</p>' . "\n";
197
- echo '<p>So the distinction is that Refund/Reversal notifications are ONLY sent under these specific circumstances: 1. You log into your PayPal® account and refund a payment that is associated with a Subscription. 2. The Customer complains to PayPal® and a chargeback occurs, forcing a Reversal. In both of these cases, an EOT/Deletion notification will be sent ( as described above ), but since EOT is a more broad notification, the Refund/Reversal notification is here so you can nail down specific back-office operations in these two specific scenarios. Please note, this feature is not to be confused with the PayPal® IPN service. PayPal® IPN integration is already built into s2Member and remains active at all times. These Refund/Reversal Notifications are an added layer of functionality, and they are completely optional; used primarily in affiliate program integration &amp; other back-office routines.</p>' . "\n";
198
  /**/
199
  echo '<table class="form-table">' . "\n";
200
  echo '<tbody>' . "\n";
@@ -212,23 +263,75 @@ echo '<tr>' . "\n";
212
  echo '<td>' . "\n";
213
  echo 'You can input multiple notification URLs by inserting one per line.<br />' . "\n";
214
  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";
215
- echo 'Refund/Reversal notifications take place silently behind-the-scenes, using a cURL connection. Each URL will be notified every time a payment is refunded through PayPal® or a chargeback occurs.<br /><br />' . "\n";
216
  echo '<strong>You can also use these special replacement codes if you need them:</strong>' . "\n";
217
  echo '<ul>' . "\n";
218
  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 ( 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 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";
219
  echo '<li><code>%%parent_txn_id%% = The PayPal® Transaction ID, associated with the original payment that is being refunded/reversed.</code></li>' . "\n";
220
- echo '<li><code>%%-amount%% = The negative amount of the payment in USD, that was refunded or reversed back to the customer.</code></li>' . "\n";
221
- echo '<li><code>%%first_name%% = The first name of the customer who purchased the membership subscription through PayPal®.</code></li>' . "\n";
222
- echo '<li><code>%%last_name%% = The last name of the customer who purchased the membership subscription through PayPal®.</code></li>' . "\n";
223
- echo '<li><code>%%full_name%% = The full name ( first & last ) of the customer who purchased the membership subscription.</code></li>' . "\n";
224
- echo '<li><code>%%payer_email%% = The email address of the customer who purchased the membership subscription through PayPal®.</code></li>' . "\n";
225
- echo '<li><code>%%item_number%% = The item number ( in other words, the membership level: 1, 2, 3 or 4 ) that the payment was for.</code></li>' . "\n";
226
- echo '<li><code>%%item_name%% = The item name ( in other words, the associated membership level label that briefly describes the item number ).</code></li>' . "\n";
227
  echo '</ul>' . "\n";
228
  echo '<strong>Custom replacement codes can also be inserted using these instructions:</strong>' . "\n";
229
  echo '<ul>' . "\n";
230
- echo '<li><code>%%cv0%% = The domain of your site, which is passed through to PayPal® using the `custom` field in your PayPal® button code.</code></li>' . "\n";
231
- echo '<li><code>%%cv1%% = If you need to track additional custom variables, you can pipe delimit them into the `custom` field of your button code like this: &lt;input type="hidden" name="custom" value="' . $_SERVER["HTTP_HOST"] . '|cv1|cv2|cv3" /&gt;. You can have an unlimited number of custom variables that track IP addresses, affiliate IDs, etc. In some cases you may need to use PHP code to insert a value into the custom field dynamically. Obviously this is for advanced webmasters, but the functionality has been made available for those who need it.</li>' . "\n";
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
232
  echo '</ul>' . "\n";
233
  echo '<strong>This example uses cv1 to track a user\'s IP address:</strong><br />' . "\n";
234
  echo '<em>( The IP address can be referenced in your notification URL using %%cv1%% )</em><br />' . "\n";
@@ -252,6 +355,8 @@ echo '</td>' . "\n";
252
  /**/
253
  echo '<td class="ws-menu-page-table-r">' . "\n";
254
  /**/
 
 
255
  echo ($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["menu-r"]["tools"]) ? '<div class="ws-menu-page-tools"><img src="' . $GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["dir_url"] . '/images/brand-tools.png" alt="." /></div>' . "\n" : '';
256
  /**/
257
  echo ($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["menu-r"]["tips"]) ? '<div class="ws-menu-page-tips"><a href="' . ws_plugin__s2member_parse_readme_value ("Customization URI") . '"><img src="' . $GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["dir_url"] . '/images/brand-tips.png" alt="." /></a></div>' . "\n" : '';
36
  /**/
37
  echo '<div class="ws-menu-page-section ws-plugin--s2member-signup-notifications-section">' . "\n";
38
  echo '<h3>Signup Notification URLs ( optional )</h3>' . "\n";
39
+ echo '<p>If you use affiliate software, or have back-office routines that need to be notified whenever a new subscription is created, you\'ll want to read this section. This is marked `Signup`, because the URLs that you list below, will be notified each time a Member signs up. Depending on your fee structure, this may include a first initial payment that establishes their subscription. This notification will only be triggered once for each Member. Signup Notifications are sent right after a Member signs up successfully through PayPal®, regardless of whether any money has actually been received. In other words, this notification is triggered anytime a Member signs up, even if you provided them with a free trial. Please note, this feature is not to be confused with the PayPal® IPN service. PayPal® IPN integration is already built into s2Member and remains active at all times. These Signup Notifications are an added layer of functionality, and they are completely optional; used primarily in affiliate program integration &amp; other back-office routines.</p>' . "\n";
40
  /**/
41
  echo '<table class="form-table">' . "\n";
42
  echo '<tbody>' . "\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-scenes, 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 ( 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 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";
61
+ echo '<li><code>%%initial%% = The Initial Fee charged during signup. If you offered a free trial, this will be 0.</code> [ <a href="#" onclick="alert(\'If no initial period was offered or required, this initial amount will be equal to the %%regular%% rate. In other words, this will always represent the amount of money the Customer spent whenever they signed up, no matter what.\\n\\nIf a user signs up under the terms of a free trial period, this will be 0. So be careful using this value with 3rd party affiliate integrations because a $0 sale amount could cause havoc. If you have a lot of trouble, try using the %%regular%% amount, or use the `Payment` Notifications instead of the `Signup` Notifications.\'); return false;">?</a> ]</li>' . "\n";
62
+ echo '<li><code>%%regular%% = The Regular Amount of the subscription. This value is always > 0, no matter what.</code> [ <a href="#" onclick="alert(\'This is how much the subscription costs after an initial period expires. The %%regular%% rate is always > 0. If you did not offer an initial period, %%initial%% and %%regular%% will be equal to the same thing.\'); return false;">?</a> ]</li>' . "\n";
63
+ echo '<li><code>%%recurring%% = This is the amount that will be charged on a Recurring basis, or 0 if non-Recurring.</code> [ <a href="#" onclick="alert(\'If recurring payments have not been required, this will be equal to 0. That being said, %%regular%% &amp; %%recurring%% are usually the same value. This variable can be used in two different ways. You can use it to determine what the regular recurring rate is, or to determine whether the subscription will recur or not. If it is going to recur, %%recurring%% will be > 0.\\n\\nThe only time this is NOT equal to the %%regular%% rate, is when recurring payments are not required; and only a one-time regular rate applies. If you have trouble, try using the %%regular%% amount, or use the `Payment` Notifications instead of the `Signup` Notifications.\'); return false;">?</a> ]</li>' . "\n";
64
+ echo '<li><code>%%first_name%% = The First Name of the Customer who purchased the membership subscription through PayPal®.</code></li>' . "\n";
65
+ echo '<li><code>%%last_name%% = The Last Name of the Customer who purchased the membership subscription through PayPal®.</code></li>' . "\n";
66
+ echo '<li><code>%%full_name%% = The Full Name ( First & Last ) of the Customer who purchased the membership subscription.</code></li>' . "\n";
67
+ echo '<li><code>%%payer_email%% = The Email Address of the Customer who purchased the membership subscription through PayPal®.</code></li>' . "\n";
68
+ echo '<li><code>%%item_number%% = The Item Number ( colon separated <em>level:custom_capabilities</em> ) for the membership subscription.</code></li>' . "\n";
69
+ echo '<li><code>%%item_name%% = The Item Name ( in other words, the associated membership Level Label that briefly describes the Item Number ).</code></li>' . "\n";
70
  echo '<li><code>%%initial_term%% = This is the term length of the initial period. This will be a numeric value, followed by a space, then a single letter.</code> [ <a href="#" onclick="alert(\'Here are some examples:\\n\\n%%initial_term%% = 1 D ( this means 1 Day )\\n%%initial_term%% = 1 M ( this means 1 Month )\\n%%initial_term%% = 1 Y ( this means 1 Year )\\n\\nThe initial period never recurs, so this only lasts for the term length specified, then it is over. If no initial period was even offered, the value of %%initial_term%% will just be: 0 D, meaning zero days.\'); return false;">?</a> ]</li>' . "\n";
71
+ echo '<li><code>%%regular_term%% = This is the term length of the regular period. This will be a numeric value, followed by a space, then a single letter.</code> [ <a href="#" onclick="alert(\'Here are some examples:\\n\\n%%regular_term%% = 1 D ( this means 1 Day )\\n%%regular_term%% = 1 M ( this means 1 Month )\\n%%regular_term%% = 1 Y ( this means 1 Year )\\n%%regular_term%% = 1 L ( this means 1 Lifetime )\\n\\nThe regular term is usually recurring. So the regular term value represents the period ( or duration ) of each recurring period. If %%recurring%% = 0, then the regular term only applies once, because it is not recurring. So if it is not recurring, the value of %%regular_term%% simply represents how long their membership privileges are going to last after the %%initial_term%% has expired, if there was an initial term. The value of this variable ( %%regular_term%% ) will never be empty, it will always be at least: 1 D, meaning 1 day. No exceptions.\'); return false;">?</a> ]</li>' . "\n";
72
  echo '</ul>' . "\n";
73
  echo '<strong>Custom replacement codes can also be inserted using these instructions:</strong>' . "\n";
74
  echo '<ul>' . "\n";
75
+ echo '<li><code>%%cv0%% = The domain of your site, which is passed through to PayPal® using the `custom` field in your PayPal® Button Code.</code></li>' . "\n";
76
+ echo '<li><code>%%cv1%% = If you need to track additional custom variables, you can pipe delimit them into the `custom` field of your Button Code like this: &lt;input type="hidden" name="custom" value="' . $_SERVER["HTTP_HOST"] . '|cv1|cv2|cv3" /&gt;. You can have an unlimited number of custom variables that track IP addresses, affiliate IDs, etc. In some cases you may need to use PHP code to insert a value into the custom field dynamically. Obviously this is for advanced webmasters, but the functionality has been made available for those who need it.</li>' . "\n";
77
+ echo '</ul>' . "\n";
78
+ echo '<strong>This example uses cv1 to track a user\'s IP address:</strong><br />' . "\n";
79
+ echo '<em>( The IP address can be referenced in your notification URL using %%cv1%% )</em><br />' . "\n";
80
+ echo '<code>&lt;input type="hidden" name="custom" value="' . $_SERVER["HTTP_HOST"] . '|&lt;?php echo $_SERVER["REMOTE_ADDR"]; ?&gt;" /&gt;</code>' . "\n";
81
+ echo '</td>' . "\n";
82
+ /**/
83
+ echo '</tr>' . "\n";
84
+ echo '</tbody>' . "\n";
85
+ echo '</table>' . "\n";
86
+ echo '</div>' . "\n";
87
+ /**/
88
+ echo '</div>' . "\n";
89
+ /**/
90
+ echo '<div class="ws-menu-page-group" title="Registration Notifications">' . "\n";
91
+ /**/
92
+ echo '<div class="ws-menu-page-section ws-plugin--s2member-registration-notifications-section">' . "\n";
93
+ echo '<h3>Registration Notification URLs ( optional )</h3>' . "\n";
94
+ echo '<p>If you use affiliate software, or have back-office routines that need to be notified whenever a new Member is created, you\'ll want to read this section. This is marked `Registration`, because the URLs that you list below, will be notified each time a Member registers a Username. This is usually triggered right after a `Signup` Notification; at the point in which a new Member successfully completes the Registration form, and they are assigned a Username. However, this is ALSO triggered whenever you create a new User inside your WordPress® Dashboard with a Free Subscriber Role, or with one of the s2Member Roles. It will NOT be triggered for other Roles; such as Administrators, Editors, Authors, and Contributors. Please note, this feature is not to be confused with the PayPal® IPN service. PayPal® IPN integration is already built into s2Member and remains active at all times. These Registration Notifications are an added layer of functionality, and they are completely optional; used primarily in affiliate program integration &amp; other back-office routines.</p>' . "\n";
95
+ /**/
96
+ echo '<table class="form-table">' . "\n";
97
+ echo '<tbody>' . "\n";
98
+ echo '<tr>' . "\n";
99
+ /**/
100
+ echo '<th>' . "\n";
101
+ echo '<label for="ws-plugin--s2member-registration-notification-urls">' . "\n";
102
+ echo 'Registration Notification URLs:' . "\n";
103
+ echo '</label>' . "\n";
104
+ echo '</th>' . "\n";
105
+ /**/
106
+ echo '</tr>' . "\n";
107
+ echo '<tr>' . "\n";
108
+ /**/
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-scenes, 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";
116
+ echo '<li><code>%%user_first_name%% = The First Name of the Member who registered their Username.</code></li>' . "\n";
117
+ echo '<li><code>%%user_last_name%% = The Last Name of the Member who registered their Username.</code></li>' . "\n";
118
+ echo '<li><code>%%user_full_name%% = The Full Name ( First & Last ) of the Member who registered their Username</code></li>' . "\n";
119
+ echo '<li><code>%%user_email%% = The Email Address of the Member who registered their Username.</code></li>' . "\n";
120
+ echo '<li><code>%%user_login%% = The Username the Member selected during registration.</code></li>' . "\n";
121
+ echo '<li><code>%%user_pass%% = Is only filled when you\'re allowing Custom Passwords.<br />' ./**/
122
+ '<em>See: s2Member -> General Options -> Custom Registration Fields.</em></code></li>' . "\n";
123
+ echo '</ul>' . "\n";
124
+ echo '<strong>Custom replacement codes can also be inserted using these instructions:</strong>' . "\n";
125
+ echo '<ul>' . "\n";
126
+ echo '<li><code>%%cv0%% = The domain of your site, which is passed through to PayPal® using the `custom` field in your PayPal® Button Code.</code></li>' . "\n";
127
+ echo '<li><code>%%cv1%% = If you need to track additional custom variables, you can pipe delimit them into the `custom` field of your Button Code like this: &lt;input type="hidden" name="custom" value="' . $_SERVER["HTTP_HOST"] . '|cv1|cv2|cv3" /&gt;. You can have an unlimited number of custom variables that track IP addresses, affiliate IDs, etc. In some cases you may need to use PHP code to insert a value into the custom field dynamically. Obviously this is for advanced webmasters, but the functionality has been made available for those who need it.</li>' . "\n";
128
  echo '</ul>' . "\n";
129
  echo '<strong>This example uses cv1 to track a user\'s IP address:</strong><br />' . "\n";
130
  echo '<em>( The IP address can be referenced in your notification URL using %%cv1%% )</em><br />' . "\n";
142
  /**/
143
  echo '<div class="ws-menu-page-section ws-plugin--s2member-payment-notifications-section">' . "\n";
144
  echo '<h3>Payment Notification URLs ( optional )</h3>' . "\n";
145
+ echo '<p>If you use affiliate software, or have back-office routines that need to be notified whenever payment transactions take place, and/or for recurring payments, you\'ll want to read this section. This is marked `Payment`, because the URLs that you list below, will be notified each time an actual payment occurs. Depending on your fee structure, this may include a first initial payment that establishes a subscription. But more importantly, this will be triggered on all future payments that are received for the lifetime of the subscription. So unlike the `Signup` Notification, `Payment` Notifications take place whenever actual payments are received, instead of just once after signup is completed. If a payment is required during signup ( e.g. no free trial is being offered ), a Signup Notification will be triggered, and a Payment Notification will ALSO be triggered. In other words, a Payment Notification occurs anytime funds are received, no matter what. Please note, this feature is not to be confused with the PayPal® IPN service. PayPal® IPN integration is already built into s2Member and remains active at all times. These Payment Notifications are an added layer of functionality, and they are completely optional; used primarily in affiliate program integration &amp; other back-office routines.</p>' . "\n";
146
  /**/
147
  echo '<table class="form-table">' . "\n";
148
  echo '<tbody>' . "\n";
160
  echo '<td>' . "\n";
161
  echo 'You can input multiple notification URLs by inserting one per line.<br />' . "\n";
162
  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";
163
+ echo 'Payment Notifications take place silently behind-the-scenes, using a cURL connection. Each URL will be notified every time an initial and/or recurring payment occurs.<br /><br />' . "\n";
164
  echo '<strong>You can also use these special replacement codes if you need them:</strong>' . "\n";
165
  echo '<ul>' . "\n";
166
  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 ( 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 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";
167
  echo '<li><code>%%txn_id%% = The PayPal® unique Transaction ID, which is always unique for each payment received.</code></li>' . "\n";
168
+ echo '<li><code>%%amount%% = The Amount of the payment. Most affiliate programs calculate commissions from this.</code></li>' . "\n";
169
+ echo '<li><code>%%first_name%% = The First Name of the Customer who purchased the membership subscription through PayPal®.</code></li>' . "\n";
170
+ echo '<li><code>%%last_name%% = The Last Name of the Customer who purchased the membership subscription through PayPal®.</code></li>' . "\n";
171
+ echo '<li><code>%%full_name%% = The Full Name ( First & Last ) of the Customer who purchased the membership subscription.</code></li>' . "\n";
172
+ echo '<li><code>%%payer_email%% = The Email Address of the Customer who purchased the membership subscription through PayPal®.</code></li>' . "\n";
173
+ echo '<li><code>%%item_number%% = The Item Number ( colon separated <em>level:custom_capabilities</em> ) that the payment is for.</code></li>' . "\n";
174
+ echo '<li><code>%%item_name%% = The Item Name ( in other words, the associated membership Level Label that briefly describes the item number ).</code></li>' . "\n";
175
  echo '</ul>' . "\n";
176
  echo '<strong>Custom replacement codes can also be inserted using these instructions:</strong>' . "\n";
177
  echo '<ul>' . "\n";
178
+ echo '<li><code>%%cv0%% = The domain of your site, which is passed through to PayPal® using the `custom` field in your PayPal® Button Code.</code></li>' . "\n";
179
+ echo '<li><code>%%cv1%% = If you need to track additional custom variables, you can pipe delimit them into the `custom` field of your Button Code like this: &lt;input type="hidden" name="custom" value="' . $_SERVER["HTTP_HOST"] . '|cv1|cv2|cv3" /&gt;. You can have an unlimited number of custom variables that track IP addresses, affiliate IDs, etc. In some cases you may need to use PHP code to insert a value into the custom field dynamically. Obviously this is for advanced webmasters, but the functionality has been made available for those who need it.</li>' . "\n";
180
  echo '</ul>' . "\n";
181
  echo '<strong>This example uses cv1 to track a user\'s IP address:</strong><br />' . "\n";
182
  echo '<em>( The IP address can be referenced in your notification URL using %%cv1%% )</em><br />' . "\n";
194
  /**/
195
  echo '<div class="ws-menu-page-section ws-plugin--s2member-eot-deletion-notifications-section">' . "\n";
196
  echo '<h3>EOT/Deletion Notification URLs ( optional )</h3>' . "\n";
197
+ echo '<p>If you use affiliate software, or have back-office routines that need to be notified whenever subscriptions have ended ( and a Member is demoted to a Free Subscriber ), or when an account is deleted from the system, you\'ll want to read this section. This is marked `EOT/Deletion`, because the URLs that you list below, will be notified in both cases. EOT = End Of Term. An EOT is triggered anytime you cancel or refund a subscription via PayPal®, or if a Member cancels their own subscription through PayPal®, fails to make payments, etc. In other words, anytime a subscription reaches the end of its term, because you issue a refund, a chargeback occurs, a cancellation occurs, or failed payments force PayPal® to end their subscription, this is triggered.</p>' . "\n";
198
+ echo '<p>EOTs are not necessarily triggered immediately after a cancellation takes place though. For example, if a Member 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 your site for another 15 days, and then, on Feb 1st, the time they paid for has completely elapsed. That is when their account is automatically demoted to a Free Subscriber, or deleted from the system completely ( based on your configuration ), and an EOT Notification is triggered. That being said, there are cases when an EOT is triggered immediately. For instance, if too many of their subscription payments fail at PayPal® ( more than 2 in a row ), an EOT will be issued immediately, also resulting in the automatic demotion or deletion of their account. If you log into your PayPal® account and issue a refund to an unhappy Customer, their account will automatically be demoted or deleted, and an EOT is triggered immediately.</p>' . "\n";
199
+ echo '<p>Manual Deletions are the other case in which these Notifications will be triggered. If you delete an account manually from within your WordPress® Dashboard, your affiliate software will be notified automatically through this notification. So the two events are an EOT and/or a manual Deletion. Please note, this feature is not to be confused with the PayPal® IPN service. PayPal® IPN integration is already built into s2Member and remains active at all times. These EOT/Deletion Notifications are an added layer of functionality, and they are completely optional; used primarily in affiliate program integration &amp; other back-office routines.</p>' . "\n";
200
  /**/
201
  echo '<table class="form-table">' . "\n";
202
  echo '<tbody>' . "\n";
214
  echo '<td>' . "\n";
215
  echo 'You can input multiple notification URLs by inserting one per line.<br />' . "\n";
216
  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";
217
+ echo 'EOT/Deletion Notifications take place silently behind-the-scenes, using a cURL connection. Each URL will be notified every time a subscription reaches the end of its term or is deleted.<br /><br />' . "\n";
218
  echo '<strong>You can also use these special replacement codes if you need them:</strong>' . "\n";
219
  echo '<ul>' . "\n";
220
  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 ( 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 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";
221
+ echo '<li><code>%%user_first_name%% = The First Name listed on their User account. This might be different than what is on file at PayPal®.</code></li>' . "\n";
222
+ echo '<li><code>%%user_last_name%% = The Last Name listed on their User account. This might be different than what is on file at PayPal®.</code></li>' . "\n";
223
+ echo '<li><code>%%user_full_name%% = The Full Name listed on their User account. This might be different than what is on file at PayPal®.</code></li>' . "\n";
224
+ echo '<li><code>%%user_email%% = The Email Address associated with their User account. This might be different than what is on file at PayPal®.</code></li>' . "\n";
225
  echo '</ul>' . "\n";
226
  echo '<strong>Custom replacement codes can also be inserted using these instructions:</strong>' . "\n";
227
  echo '<ul>' . "\n";
228
+ echo '<li><code>%%cv0%% = The domain of your site, which is passed through to PayPal® using the `custom` field in your PayPal® Button Code.</code></li>' . "\n";
229
+ echo '<li><code>%%cv1%% = If you need to track additional custom variables, you can pipe delimit them into the `custom` field of your Button Code like this: &lt;input type="hidden" name="custom" value="' . $_SERVER["HTTP_HOST"] . '|cv1|cv2|cv3" /&gt;. You can have an unlimited number of custom variables that track IP addresses, affiliate IDs, etc. In some cases you may need to use PHP code to insert a value into the custom field dynamically. Obviously this is for advanced webmasters, but the functionality has been made available for those who need it.</li>' . "\n";
230
  echo '</ul>' . "\n";
231
  echo '<strong>This example uses cv1 to track a user\'s IP address:</strong><br />' . "\n";
232
  echo '<em>( The IP address can be referenced in your notification URL using %%cv1%% )</em><br />' . "\n";
244
  /**/
245
  echo '<div class="ws-menu-page-section ws-plugin--s2member-refund-reversal-notifications-section">' . "\n";
246
  echo '<h3>Refund/Reversal Notification URLs ( optional )</h3>' . "\n";
247
+ echo '<p>If you use affiliate software, or have back-office routines that need to be notified whenever subscriptions have been refunded or reversed ( e.g. charged back to you ), you\'ll want to read this section. This is marked `Refund/Reversal`, because the URLs that you list below, will ONLY be notified in those specific cases, as opposed to the EOT Notifications, which are all-inclusive. This is very similar to the EOT/Deletion described above. But, there is an important distinction. EOT includes cancellations, expirations, failed payments, refunds, chargebacks, etc, etc. In other words, ANY time a deletion or End Of Term action takes place.</p>' . "\n";
248
+ echo '<p>So the distinction is that Refund/Reversal Notifications are ONLY sent under these specific circumstances: 1. You log into your PayPal® account and refund a payment that is associated with a Subscription. 2. The Customer complains to PayPal® and a chargeback occurs, forcing a Reversal. In both of these cases, an EOT/Deletion Notification will be sent ( as described above ), but since EOT is a more broad Notification, the Refund/Reversal Notification is here so you can nail down specific back-office operations in these two specific scenarios. Please note, this feature is not to be confused with the PayPal® IPN service. PayPal® IPN integration is already built into s2Member and remains active at all times. These Refund/Reversal Notifications are an added layer of functionality, and they are completely optional; used primarily in affiliate program integration &amp; other back-office routines.</p>' . "\n";
249
  /**/
250
  echo '<table class="form-table">' . "\n";
251
  echo '<tbody>' . "\n";
263
  echo '<td>' . "\n";
264
  echo 'You can input multiple notification URLs by inserting one per line.<br />' . "\n";
265
  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";
266
+ echo 'Refund/Reversal Notifications take place silently behind-the-scenes, using a cURL connection. Each URL will be notified every time a payment is refunded through PayPal® or a chargeback occurs.<br /><br />' . "\n";
267
  echo '<strong>You can also use these special replacement codes if you need them:</strong>' . "\n";
268
  echo '<ul>' . "\n";
269
  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 ( 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 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";
270
  echo '<li><code>%%parent_txn_id%% = The PayPal® Transaction ID, associated with the original payment that is being refunded/reversed.</code></li>' . "\n";
271
+ echo '<li><code>%%-amount%% = The Negative Amount of the payment, that was refunded or reversed back to the Customer.</code></li>' . "\n";
272
+ echo '<li><code>%%first_name%% = The First Name of the Customer who purchased the membership subscription through PayPal®.</code></li>' . "\n";
273
+ echo '<li><code>%%last_name%% = The Last Name of the Customer who purchased the membership subscription through PayPal®.</code></li>' . "\n";
274
+ echo '<li><code>%%full_name%% = The Full Name ( First & Last ) of the Customer who purchased the membership subscription.</code></li>' . "\n";
275
+ echo '<li><code>%%payer_email%% = The Email Address of the Customer who purchased the membership subscription through PayPal®.</code></li>' . "\n";
276
+ echo '<li><code>%%item_number%% = The Item Number ( colon separated <em>level:custom_capabilities</em> ) that the payment was for.</code></li>' . "\n";
277
+ echo '<li><code>%%item_name%% = The Item Name ( in other words, the associated membership Level Label that briefly describes the item number ).</code></li>' . "\n";
278
  echo '</ul>' . "\n";
279
  echo '<strong>Custom replacement codes can also be inserted using these instructions:</strong>' . "\n";
280
  echo '<ul>' . "\n";
281
+ echo '<li><code>%%cv0%% = The domain of your site, which is passed through to PayPal® using the `custom` field in your PayPal® Button Code.</code></li>' . "\n";
282
+ echo '<li><code>%%cv1%% = If you need to track additional custom variables, you can pipe delimit them into the `custom` field of your Button Code like this: &lt;input type="hidden" name="custom" value="' . $_SERVER["HTTP_HOST"] . '|cv1|cv2|cv3" /&gt;. You can have an unlimited number of custom variables that track IP addresses, affiliate IDs, etc. In some cases you may need to use PHP code to insert a value into the custom field dynamically. Obviously this is for advanced webmasters, but the functionality has been made available for those who need it.</li>' . "\n";
283
+ echo '</ul>' . "\n";
284
+ echo '<strong>This example uses cv1 to track a user\'s IP address:</strong><br />' . "\n";
285
+ echo '<em>( The IP address can be referenced in your notification URL using %%cv1%% )</em><br />' . "\n";
286
+ echo '<code>&lt;input type="hidden" name="custom" value="' . $_SERVER["HTTP_HOST"] . '|&lt;?php echo $_SERVER["REMOTE_ADDR"]; ?&gt;" /&gt;</code>' . "\n";
287
+ echo '</td>' . "\n";
288
+ /**/
289
+ echo '</tr>' . "\n";
290
+ echo '</tbody>' . "\n";
291
+ echo '</table>' . "\n";
292
+ echo '</div>' . "\n";
293
+ /**/
294
+ echo '</div>' . "\n";
295
+ /**/
296
+ echo '<div class="ws-menu-page-group" title="Single-Page Access Notifications">' . "\n";
297
+ /**/
298
+ echo '<div class="ws-menu-page-section ws-plugin--s2member-sp-notifications-section">' . "\n";
299
+ echo '<h3>Single-Page Access Notification URLs ( optional )</h3>' . "\n";
300
+ echo '<p>If you use affiliate software, or have back-office routines that need to be notified whenever Single-Page transactions take place, you\'ll want to read this section. This is marked `Single-Page`, because the URLs that you list below, will be notified each time a payment occurs, specifically for a Single-Page sale. This is the only Notification that is sent for Single-Page Access. All of the other API Notifications are designed for Membership Level Access. Please note, this feature is not to be confused with the PayPal® IPN service. PayPal® IPN integration is already built into s2Member and remains active at all times. These Payment Notifications are an added layer of functionality, and they are completely optional; used primarily in affiliate program integration &amp; other back-office routines.</p>' . "\n";
301
+ /**/
302
+ echo '<table class="form-table">' . "\n";
303
+ echo '<tbody>' . "\n";
304
+ echo '<tr>' . "\n";
305
+ /**/
306
+ echo '<th>' . "\n";
307
+ echo '<label for="ws-plugin--s2member-sp-notification-urls">' . "\n";
308
+ echo 'Single-Page Notification URLs:' . "\n";
309
+ echo '</label>' . "\n";
310
+ echo '</th>' . "\n";
311
+ /**/
312
+ echo '</tr>' . "\n";
313
+ echo '<tr>' . "\n";
314
+ /**/
315
+ echo '<td>' . "\n";
316
+ echo 'You can input multiple notification URLs by inserting one per line.<br />' . "\n";
317
+ 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";
318
+ echo 'Single-Page Notifications take place silently behind-the-scenes, using a cURL connection. Each URL will be notified every time a sale occurs.<br /><br />' . "\n";
319
+ echo '<strong>You can also use these special replacement codes if you need them:</strong>' . "\n";
320
+ echo '<ul>' . "\n";
321
+ echo '<li><code>%%sp_access_url%% = The full URL ( generated by s2Member ) where the Customer can gain access. Valid for 72 hours.</code></li>' . "\n";
322
+ echo '<li><code>%%txn_id%% = The PayPal® Transaction ID. PayPal® assigns a unique identifier for every purchase.</code></li>' . "\n";
323
+ echo '<li><code>%%amount%% = The full Amount of the sale. Most affiliate programs calculate commissions from this.</code></li>' . "\n";
324
+ echo '<li><code>%%first_name%% = The First Name of the Customer who purchased Single-Page Access through PayPal®.</code></li>' . "\n";
325
+ echo '<li><code>%%last_name%% = The Last Name of the Customer who purchased Single-Page Access through PayPal®.</code></li>' . "\n";
326
+ echo '<li><code>%%full_name%% = The Full Name ( First & Last ) of the Customer who purchased Single-Page Access.</code></li>' . "\n";
327
+ echo '<li><code>%%payer_email%% = The Email Address of the Customer who purchased Single-Page Access through PayPal®.</code></li>' . "\n";
328
+ echo '<li><code>%%item_number%% = The Item Number. Ex: <em>sp:13</em> ( the numerical portion is a Single-Page ID ).</code></li>' . "\n";
329
+ echo '<li><code>%%item_name%% = The Item Name. In other words, a brief description, detailing what this purchase was for.</code></li>' . "\n";
330
+ echo '</ul>' . "\n";
331
+ echo '<strong>Custom replacement codes can also be inserted using these instructions:</strong>' . "\n";
332
+ echo '<ul>' . "\n";
333
+ echo '<li><code>%%cv0%% = The domain of your site, which is passed through to PayPal® using the `custom` field in your PayPal® Button Code.</code></li>' . "\n";
334
+ echo '<li><code>%%cv1%% = If you need to track additional custom variables, you can pipe delimit them into the `custom` field of your Button Code like this: &lt;input type="hidden" name="custom" value="' . $_SERVER["HTTP_HOST"] . '|cv1|cv2|cv3" /&gt;. You can have an unlimited number of custom variables that track IP addresses, affiliate IDs, etc. In some cases you may need to use PHP code to insert a value into the custom field dynamically. Obviously this is for advanced webmasters, but the functionality has been made available for those who need it.</li>' . "\n";
335
  echo '</ul>' . "\n";
336
  echo '<strong>This example uses cv1 to track a user\'s IP address:</strong><br />' . "\n";
337
  echo '<em>( The IP address can be referenced in your notification URL using %%cv1%% )</em><br />' . "\n";
355
  /**/
356
  echo '<td class="ws-menu-page-table-r">' . "\n";
357
  /**/
358
+ echo ($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["menu-r"]["installation"]) ? '<div class="ws-menu-page-installation"><a href="' . ws_plugin__s2member_parse_readme_value ("Professional Installation URI") . '"><img src="' . $GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["dir_url"] . '/images/brand-installation.png" alt="." title="Contact PriMoThemes!" /></a></div>' . "\n" : '';
359
+ /**/
360
  echo ($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["menu-r"]["tools"]) ? '<div class="ws-menu-page-tools"><img src="' . $GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["dir_url"] . '/images/brand-tools.png" alt="." /></div>' . "\n" : '';
361
  /**/
362
  echo ($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["menu-r"]["tips"]) ? '<div class="ws-menu-page-tips"><a href="' . ws_plugin__s2member_parse_readme_value ("Customization URI") . '"><img src="' . $GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["dir_url"] . '/images/brand-tips.png" alt="." /></a></div>' . "\n" : '';
includes/menu-pages/button.html CHANGED
@@ -1,12 +1,12 @@
1
  <form action="https://%%endpoint%%/cgi-bin/webscr" method="post">
2
  <input type="hidden" name="business" value="%%paypal_business%%" />
3
  <input type="hidden" name="cmd" value="_xclick-subscriptions" />
4
- <!-- Instant Payment Notification / Return Details -->
5
  <input type="hidden" name="notify_url" value="%%notify_url%%" />
6
  <input type="hidden" name="cancel_return" value="%%cancel_return%%" />
7
  <input type="hidden" name="return" value="%%return%%" />
8
  <input type="hidden" name="rm" value="2" />
9
- <!-- Identify / Customize The Checkout Fields. -->
10
  <input type="hidden" name="no_shipping" value="1" />
11
  <input type="hidden" name="no_note" value="1" />
12
  <input type="hidden" name="custom" value="%%domain%%" />
@@ -14,11 +14,12 @@
14
  <input type="hidden" name="page_style" value="paypal" />
15
  <input type="hidden" name="item_name" value="%%level_label%%" />
16
  <input type="hidden" name="item_number" value="%%level%%" />
17
- <!-- Set The Terms Of The Subscription. -->
18
- <!--<input type="hidden" name="on0" value="" />-->
19
- <!--<input type="hidden" name="os0" value="" />-->
 
 
20
  <!--<input type="hidden" name="amount" value="0.01" />-->
21
- <input type="hidden" name="modify" value="0" />
22
  <input type="hidden" name="src" value="1" />
23
  <input type="hidden" name="sra" value="1" />
24
  <input type="hidden" name="a1" value="0.00" />
@@ -27,6 +28,6 @@
27
  <input type="hidden" name="a3" value="0.01" />
28
  <input type="hidden" name="p3" value="1" />
29
  <input type="hidden" name="t3" value="M" />
30
- <!-- Display The Subscription Button. -->
31
- <input type="image" alt="PayPal®" style="border:0;" src="https://www.paypal.com/en_GB/i/btn/btn_xpressCheckout.gif" />
32
  </form>
1
  <form action="https://%%endpoint%%/cgi-bin/webscr" method="post">
2
  <input type="hidden" name="business" value="%%paypal_business%%" />
3
  <input type="hidden" name="cmd" value="_xclick-subscriptions" />
4
+ <!-- Instant Payment Notification & Return Page Details -->
5
  <input type="hidden" name="notify_url" value="%%notify_url%%" />
6
  <input type="hidden" name="cancel_return" value="%%cancel_return%%" />
7
  <input type="hidden" name="return" value="%%return%%" />
8
  <input type="hidden" name="rm" value="2" />
9
+ <!-- Configures All Of The Checkout Fields -->
10
  <input type="hidden" name="no_shipping" value="1" />
11
  <input type="hidden" name="no_note" value="1" />
12
  <input type="hidden" name="custom" value="%%domain%%" />
14
  <input type="hidden" name="page_style" value="paypal" />
15
  <input type="hidden" name="item_name" value="%%level_label%%" />
16
  <input type="hidden" name="item_number" value="%%level%%" />
17
+ <!-- Identifies/Updates An Existing Member After Checkout -->
18
+ <input type="hidden" name="on0" value="<?php echo S2MEMBER_CURRENT_USER_VALUE_FOR_PP_ON0; ?>" />
19
+ <input type="hidden" name="os0" value="<?php echo S2MEMBER_CURRENT_USER_VALUE_FOR_PP_OS0; ?>" />
20
+ <input type="hidden" name="modify" value="1" />
21
+ <!-- Customizes Prices, Payments & Billing Cycle -->
22
  <!--<input type="hidden" name="amount" value="0.01" />-->
 
23
  <input type="hidden" name="src" value="1" />
24
  <input type="hidden" name="sra" value="1" />
25
  <input type="hidden" name="a1" value="0.00" />
28
  <input type="hidden" name="a3" value="0.01" />
29
  <input type="hidden" name="p3" value="1" />
30
  <input type="hidden" name="t3" value="M" />
31
+ <!-- Displays The PayPal® Image Button -->
32
+ <input type="image" alt="PayPal®" style="border:0;" src="https://www.paypal.com/en_US/i/btn/btn_xpressCheckout.gif" />
33
  </form>
includes/menu-pages/buttons.inc.php CHANGED
@@ -19,7 +19,7 @@ PayPal® Button Generating page.
19
  echo '<div class="wrap ws-menu-page">' . "\n";
20
  /**/
21
  echo '<div id="icon-plugins" class="icon32"><br /></div>' . "\n";
22
- echo '<h2><div>Developed by <a href="' . ws_plugin__s2member_parse_readme_value ("Plugin URI") . '"><img src="' . $GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["dir_url"] . '/images/brand-light.png" alt="." /></a></div>s2Member PayPal® Subscription Buttons</h2>' . "\n";
23
  /**/
24
  echo '<div class="ws-menu-page-hr"></div>' . "\n";
25
  /**/
@@ -32,19 +32,19 @@ if (get_option ("ws_plugin__s2member_configured") && $GLOBALS["WS_PLUGIN__"]["s2
32
  {
33
  echo '<form method="post" name="ws_plugin__s2member_buttons_form" id="ws-plugin--s2member-buttons-form">' . "\n";
34
  /**/
35
- echo '<div class="ws-menu-page-group" title="PayPal® Button For Level #1 Subscriptions">' . "\n";
36
  /**/
37
  echo '<div class="ws-menu-page-section ws-plugin--s2member-button-code-1-section">' . "\n";
38
- echo '<h3>Button Code Generator For Level #1 Subscriptions</h3>' . "\n";
39
- echo '<p>Very simple. All you do is customize the form fields provided, for each Membership Level that you plan to offer. Then press (Generate Button Code). These special subscription buttons are customized to work with s2Member seamlessly. User accounts will be activated instantly, in an automated fashion. When you, or a User, cancels their membership, or fails to make payments on time, s2Member will automatically terminate their membership privileges using automated routines. s2Member makes extensive use of the PayPal® IPN service, which receives updates directly from PayPal® behind the scenes.</p>' . "\n";
40
- echo '<p><em>* Buttons are NOT saved here. This is only a Button Generator. Once you\'ve generated your Button, copy/paste it into your Membership Options Page. If you lose your Button Code, you\'ll need to come back &amp; regenerate a new one. If you\'re currently in Sandbox testing mode, please remember to come back and regenerate new Buttons once you go live.</em></p>' . "\n";
41
  /**/
42
  echo '<table class="form-table">' . "\n";
43
  echo '<tbody>' . "\n";
44
  echo '<tr>' . "\n";
45
  /**/
46
  echo '<th class="ws-menu-page-th-side">' . "\n";
47
- echo '<label for="ws-plugin--s2member-level1-button">' . "\n";
48
  echo 'Button Code<br />For Level #1:<br /><br />' . "\n";
49
  echo '<div id="ws-plugin--s2member-level1-button-prev"></div>' . "\n";
50
  echo '</label>' . "\n";
@@ -53,7 +53,8 @@ if (get_option ("ws_plugin__s2member_configured") && $GLOBALS["WS_PLUGIN__"]["s2
53
  echo '<td>' . "\n";
54
  echo '<p id="ws-plugin--s2member-level1-trial-line">I\'ll offer the first <input type="text" id="ws-plugin--s2member-level1-trial-period" value="0" size="2" /> <select id="ws-plugin--s2member-level1-trial-term"><option value="D" selected="selected">Days</option><option value="W">Weeks</option><option value="M">Months</option><option value="Y">Years</option></select> free.</p>' . "\n";
55
  echo '<p><span id="ws-plugin--s2member-level1-trial-then">Then, </span>I want to charge: $<input type="text" id="ws-plugin--s2member-level1-amount" value="0.01" size="4" /> / <select id="ws-plugin--s2member-level1-term"><optgroup label="Recurring Subscriptions"><option value="1-D-1">Daily ( recurring charge, for ongoing access )</option><option value="1-W-1">Weekly ( recurring charge, for ongoing access )</option><option value="1-M-1" selected="selected">Monthly ( recurring charge, for ongoing access )</option><option value="3-M-1">Quarterly ( recurring charge, for ongoing access )</option><option value="1-Y-1">Yearly ( recurring charge, for ongoing access )</option></optgroup><optgroup label="Days / Non-Recurring"><option value="1-D-0">One Time ( for 1 day access, non-recurring )</option><option value="2-D-0">One Time ( for 2 day access, non-recurring )</option><option value="3-D-0">One Time ( for 3 day access, non-recurring )</option><option value="4-D-0">One Time ( for 4 day access, non-recurring )</option><option value="5-D-0">One Time ( for 5 day access, non-recurring )</option><option value="6-D-0">One Time ( for 6 day access, non-recurring )</option></optgroup><optgroup label="Weeks / Non-Recurring"><option value="1-W-0">One Time ( for 1 week access, non-recurring )</option><option value="2-W-0">One Time ( for 2 week access, non-recurring )</option><option value="3-W-0">One Time ( for 3 week access, non-recurring )</option></optgroup><optgroup label="Months / Non-Recurring"><option value="1-M-0">One Time ( for 1 month access, non-recurring )</option><option value="2-M-0">One Time ( for 2 month access, non-recurring )</option><option value="3-M-0">One Time ( for 3 month access, non-recurring )</option><option value="4-M-0">One Time ( for 4 month access, non-recurring )</option><option value="5-M-0">One Time ( for 5 month access, non-recurring )</option><option value="6-M-0">One Time ( for 6 month access, non-recurring )</option></optgroup><optgroup label="Years / Non-Recurring"><option value="1-Y-0">One Time ( for 1 year access, non-recurring )</option><option value="2-Y-0">One Time ( for 2 year access, non-recurring )</option><option value="3-Y-0">One Time ( for 3 year access, non-recurring )</option><option value="4-Y-0">One Time ( for 4 year access, non-recurring )</option><option value="5-Y-0">One Time ( for 5 year access, non-recurring )</option></optgroup><optgroup label="Lifetime / Buy Now / Non-Recurring / No Trial"><option value="1-L-0">Buy Now ( for lifetime access, no-trial, non-recurring )</option></optgroup></select></p>' . "\n";
56
- echo '<p>Checkout Page Style [<a href="#" onclick="alert(\'Optional. This can be configured inside your PayPal® account. PayPal® allows you to create Custom Page Styles, and assign a unique name to them. Once you\\\'ve created a Custom Page Style at PayPal®, you can enter that Page Style here.\'); return false;">?</a>]: <input type="text" id="ws-plugin--s2member-level1-page-style" value="paypal" size="10" /> <select id="ws-plugin--s2member-level1-currency"><optgroup label="Currency"><option value="USD" title="U.S. Dollar">USD</option><option value="AUD" title="Australian Dollar">AUD</option><option value="BRL" title="Brazilian Real">BRL</option><option value="CAD" title="Canadian Dollar">CAD</option><option value="CZK" title="Czech Koruna">CZK</option><option value="DKK" title="Danish Krone">DKK</option><option value="EUR" title="Euro">EUR</option><option value="HKD" title="Hong Kong Dollar">HKD</option><option value="HUF" title="Hungarian Forint">HUF</option><option value="ILS" title="Israeli New Sheqel">ILS</option><option value="JPY" title="Japanese Yen">JPY</option><option value="MYR" title="Malaysian Ringgit">MYR</option><option value="MXN" title="Mexican Peso">MXN</option><option value="NOK" title="Norwegian Krone">NOK</option><option value="NZD" title="New Zealand Dollar">NZD</option><option value="PHP" title="Philippine Peso">PHP</option><option value="PLN" title="Polish Zloty">PLN</option><option value="GBP" title="Pound Sterling">GBP</option><option value="SGD" title="Singapore Dollar">SGD</option><option value="SEK" title="Swedish Krona">SEK</option><option value="CHF" title="Swiss Franc">CHF</option><option value="TWD" title="Taiwan New Dollar">TWD</option><option value="THB" title="Thai Baht">THB</option><option value="USD" title="U.S. Dollar">USD</option></optgroup></select> <input type="button" value="Generate Button Code" onclick="ws_plugin__s2member_paypalButtonGenerate(1);" class="button-primary" /></p>' . "\n";
 
57
  echo '</td>' . "\n";
58
  /**/
59
  echo '</tr>' . "\n";
@@ -64,6 +65,7 @@ if (get_option ("ws_plugin__s2member_configured") && $GLOBALS["WS_PLUGIN__"]["s2
64
  $ws_plugin__s2member_temp_s = trim (file_get_contents (dirname (__FILE__) . "/shortcode.html"));
65
  $ws_plugin__s2member_temp_s = preg_replace ("/%%domain%%/", strtolower ($_SERVER["HTTP_HOST"]), $ws_plugin__s2member_temp_s);
66
  $ws_plugin__s2member_temp_s = preg_replace ("/%%level%%/", "1", $ws_plugin__s2member_temp_s);
 
67
  echo '<input id="ws-plugin--s2member-level1-shortcode" type="text" value="' . format_to_edit ($ws_plugin__s2member_temp_s) . '" onclick="this.select ();" /><br /><br />' . "\n";
68
  echo '<strong>Resulting PayPal® Button Code:</strong> ( ultimately, your Shortcode will produce this snippet )<br />' . "\n";
69
  echo '<textarea id="ws-plugin--s2member-level1-button" rows="8" wrap="off" onclick="this.select ();">';
@@ -88,19 +90,19 @@ if (get_option ("ws_plugin__s2member_configured") && $GLOBALS["WS_PLUGIN__"]["s2
88
  /**/
89
  echo '</div>' . "\n";
90
  /**/
91
- echo '<div class="ws-menu-page-group" title="PayPal® Button For Level #2 Subscriptions">' . "\n";
92
  /**/
93
  echo '<div class="ws-menu-page-section ws-plugin--s2member-button-code-2-section">' . "\n";
94
- echo '<h3>Button Code Generator For Level #2 Subscriptions</h3>' . "\n";
95
- echo '<p>Very simple. All you do is customize the form fields provided, for each Membership Level that you plan to offer. Then press (Generate Button Code). These special subscription buttons are customized to work with s2Member seamlessly. User accounts will be activated instantly, in an automated fashion. When you, or a User, cancels their membership, or fails to make payments on time, s2Member will automatically terminate their membership privileges using automated routines. s2Member makes extensive use of the PayPal® IPN service, which receives updates directly from PayPal® behind the scenes.</p>' . "\n";
96
- echo '<p><em>* Buttons are NOT saved here. This is only a Button Generator. Once you\'ve generated your Button, copy/paste it into your Membership Options Page. If you lose your Button Code, you\'ll need to come back &amp; regenerate a new one. If you\'re currently in Sandbox testing mode, please remember to come back and regenerate new Buttons once you go live.</em></p>' . "\n";
97
  /**/
98
  echo '<table class="form-table">' . "\n";
99
  echo '<tbody>' . "\n";
100
  echo '<tr>' . "\n";
101
  /**/
102
  echo '<th class="ws-menu-page-th-side">' . "\n";
103
- echo '<label for="ws-plugin--s2member-level2-button">' . "\n";
104
  echo 'Button Code<br />For Level #2:<br /><br />' . "\n";
105
  echo '<div id="ws-plugin--s2member-level2-button-prev"></div>' . "\n";
106
  echo '</label>' . "\n";
@@ -109,7 +111,8 @@ if (get_option ("ws_plugin__s2member_configured") && $GLOBALS["WS_PLUGIN__"]["s2
109
  echo '<td>' . "\n";
110
  echo '<p id="ws-plugin--s2member-level2-trial-line">I\'ll offer the first <input type="text" id="ws-plugin--s2member-level2-trial-period" value="0" size="2" /> <select id="ws-plugin--s2member-level2-trial-term"><option value="D" selected="selected">Days</option><option value="W">Weeks</option><option value="M">Months</option><option value="Y">Years</option></select> free.</p>' . "\n";
111
  echo '<p><span id="ws-plugin--s2member-level2-trial-then">Then, </span>I want to charge: $<input type="text" id="ws-plugin--s2member-level2-amount" value="0.01" size="4" /> / <select id="ws-plugin--s2member-level2-term"><optgroup label="Recurring Subscriptions"><option value="1-D-1">Daily ( recurring charge, for ongoing access )</option><option value="1-W-1">Weekly ( recurring charge, for ongoing access )</option><option value="1-M-1" selected="selected">Monthly ( recurring charge, for ongoing access )</option><option value="3-M-1">Quarterly ( recurring charge, for ongoing access )</option><option value="1-Y-1">Yearly ( recurring charge, for ongoing access )</option></optgroup><optgroup label="Days / Non-Recurring"><option value="1-D-0">One Time ( for 1 day access, non-recurring )</option><option value="2-D-0">One Time ( for 2 day access, non-recurring )</option><option value="3-D-0">One Time ( for 3 day access, non-recurring )</option><option value="4-D-0">One Time ( for 4 day access, non-recurring )</option><option value="5-D-0">One Time ( for 5 day access, non-recurring )</option><option value="6-D-0">One Time ( for 6 day access, non-recurring )</option></optgroup><optgroup label="Weeks / Non-Recurring"><option value="1-W-0">One Time ( for 1 week access, non-recurring )</option><option value="2-W-0">One Time ( for 2 week access, non-recurring )</option><option value="3-W-0">One Time ( for 3 week access, non-recurring )</option></optgroup><optgroup label="Months / Non-Recurring"><option value="1-M-0">One Time ( for 1 month access, non-recurring )</option><option value="2-M-0">One Time ( for 2 month access, non-recurring )</option><option value="3-M-0">One Time ( for 3 month access, non-recurring )</option><option value="4-M-0">One Time ( for 4 month access, non-recurring )</option><option value="5-M-0">One Time ( for 5 month access, non-recurring )</option><option value="6-M-0">One Time ( for 6 month access, non-recurring )</option></optgroup><optgroup label="Years / Non-Recurring"><option value="1-Y-0">One Time ( for 1 year access, non-recurring )</option><option value="2-Y-0">One Time ( for 2 year access, non-recurring )</option><option value="3-Y-0">One Time ( for 3 year access, non-recurring )</option><option value="4-Y-0">One Time ( for 4 year access, non-recurring )</option><option value="5-Y-0">One Time ( for 5 year access, non-recurring )</option></optgroup><optgroup label="Lifetime / Buy Now / Non-Recurring / No Trial"><option value="1-L-0">Buy Now ( for lifetime access, no-trial, non-recurring )</option></optgroup></select></p>' . "\n";
112
- echo '<p>Checkout Page Style [<a href="#" onclick="alert(\'Optional. This can be configured inside your PayPal® account. PayPal® allows you to create Custom Page Styles, and assign a unique name to them. Once you\\\'ve created a Custom Page Style at PayPal®, you can enter that Page Style here.\'); return false;">?</a>]: <input type="text" id="ws-plugin--s2member-level2-page-style" value="paypal" size="10" /> <select id="ws-plugin--s2member-level2-currency"><optgroup label="Currency"><option value="USD" title="U.S. Dollar">USD</option><option value="AUD" title="Australian Dollar">AUD</option><option value="BRL" title="Brazilian Real">BRL</option><option value="CAD" title="Canadian Dollar">CAD</option><option value="CZK" title="Czech Koruna">CZK</option><option value="DKK" title="Danish Krone">DKK</option><option value="EUR" title="Euro">EUR</option><option value="HKD" title="Hong Kong Dollar">HKD</option><option value="HUF" title="Hungarian Forint">HUF</option><option value="ILS" title="Israeli New Sheqel">ILS</option><option value="JPY" title="Japanese Yen">JPY</option><option value="MYR" title="Malaysian Ringgit">MYR</option><option value="MXN" title="Mexican Peso">MXN</option><option value="NOK" title="Norwegian Krone">NOK</option><option value="NZD" title="New Zealand Dollar">NZD</option><option value="PHP" title="Philippine Peso">PHP</option><option value="PLN" title="Polish Zloty">PLN</option><option value="GBP" title="Pound Sterling">GBP</option><option value="SGD" title="Singapore Dollar">SGD</option><option value="SEK" title="Swedish Krona">SEK</option><option value="CHF" title="Swiss Franc">CHF</option><option value="TWD" title="Taiwan New Dollar">TWD</option><option value="THB" title="Thai Baht">THB</option><option value="USD" title="U.S. Dollar">USD</option></optgroup></select> <input type="button" value="Generate Button Code" onclick="ws_plugin__s2member_paypalButtonGenerate(2);" class="button-primary" /></p>' . "\n";
 
113
  echo '</td>' . "\n";
114
  /**/
115
  echo '</tr>' . "\n";
@@ -120,6 +123,7 @@ if (get_option ("ws_plugin__s2member_configured") && $GLOBALS["WS_PLUGIN__"]["s2
120
  $ws_plugin__s2member_temp_s = trim (file_get_contents (dirname (__FILE__) . "/shortcode.html"));
121
  $ws_plugin__s2member_temp_s = preg_replace ("/%%domain%%/", strtolower ($_SERVER["HTTP_HOST"]), $ws_plugin__s2member_temp_s);
122
  $ws_plugin__s2member_temp_s = preg_replace ("/%%level%%/", "2", $ws_plugin__s2member_temp_s);
 
123
  echo '<input id="ws-plugin--s2member-level2-shortcode" type="text" value="' . format_to_edit ($ws_plugin__s2member_temp_s) . '" onclick="this.select ();" /><br /><br />' . "\n";
124
  echo '<strong>Resulting PayPal® Button Code:</strong> ( ultimately, your Shortcode will produce this snippet )<br />' . "\n";
125
  echo '<textarea id="ws-plugin--s2member-level2-button" rows="8" wrap="off" onclick="this.select ();">';
@@ -144,19 +148,19 @@ if (get_option ("ws_plugin__s2member_configured") && $GLOBALS["WS_PLUGIN__"]["s2
144
  /**/
145
  echo '</div>' . "\n";
146
  /**/
147
- echo '<div class="ws-menu-page-group" title="PayPal® Button For Level #3 Subscriptions">' . "\n";
148
  /**/
149
  echo '<div class="ws-menu-page-section ws-plugin--s2member-button-code-3-section">' . "\n";
150
- echo '<h3>Button Code Generator For Level #3 Subscriptions</h3>' . "\n";
151
- echo '<p>Very simple. All you do is customize the form fields provided, for each Membership Level that you plan to offer. Then press (Generate Button Code). These special subscription buttons are customized to work with s2Member seamlessly. User accounts will be activated instantly, in an automated fashion. When you, or a User, cancels their membership, or fails to make payments on time, s2Member will automatically terminate their membership privileges using automated routines. s2Member makes extensive use of the PayPal® IPN service, which receives updates directly from PayPal® behind the scenes.</p>' . "\n";
152
- echo '<p><em>* Buttons are NOT saved here. This is only a Button Generator. Once you\'ve generated your Button, copy/paste it into your Membership Options Page. If you lose your Button Code, you\'ll need to come back &amp; regenerate a new one. If you\'re currently in Sandbox testing mode, please remember to come back and regenerate new Buttons once you go live.</em></p>' . "\n";
153
  /**/
154
  echo '<table class="form-table">' . "\n";
155
  echo '<tbody>' . "\n";
156
  echo '<tr>' . "\n";
157
  /**/
158
  echo '<th class="ws-menu-page-th-side">' . "\n";
159
- echo '<label for="ws-plugin--s2member-level3-button">' . "\n";
160
  echo 'Button Code<br />For Level #3:<br /><br />' . "\n";
161
  echo '<div id="ws-plugin--s2member-level3-button-prev"></div>' . "\n";
162
  echo '</label>' . "\n";
@@ -165,7 +169,8 @@ if (get_option ("ws_plugin__s2member_configured") && $GLOBALS["WS_PLUGIN__"]["s2
165
  echo '<td>' . "\n";
166
  echo '<p id="ws-plugin--s2member-level3-trial-line">I\'ll offer the first <input type="text" id="ws-plugin--s2member-level3-trial-period" value="0" size="2" /> <select id="ws-plugin--s2member-level3-trial-term"><option value="D" selected="selected">Days</option><option value="W">Weeks</option><option value="M">Months</option><option value="Y">Years</option></select> free.</p>' . "\n";
167
  echo '<p><span id="ws-plugin--s2member-level3-trial-then">Then, </span>I want to charge: $<input type="text" id="ws-plugin--s2member-level3-amount" value="0.01" size="4" /> / <select id="ws-plugin--s2member-level3-term"><optgroup label="Recurring Subscriptions"><option value="1-D-1">Daily ( recurring charge, for ongoing access )</option><option value="1-W-1">Weekly ( recurring charge, for ongoing access )</option><option value="1-M-1" selected="selected">Monthly ( recurring charge, for ongoing access )</option><option value="3-M-1">Quarterly ( recurring charge, for ongoing access )</option><option value="1-Y-1">Yearly ( recurring charge, for ongoing access )</option></optgroup><optgroup label="Days / Non-Recurring"><option value="1-D-0">One Time ( for 1 day access, non-recurring )</option><option value="2-D-0">One Time ( for 2 day access, non-recurring )</option><option value="3-D-0">One Time ( for 3 day access, non-recurring )</option><option value="4-D-0">One Time ( for 4 day access, non-recurring )</option><option value="5-D-0">One Time ( for 5 day access, non-recurring )</option><option value="6-D-0">One Time ( for 6 day access, non-recurring )</option></optgroup><optgroup label="Weeks / Non-Recurring"><option value="1-W-0">One Time ( for 1 week access, non-recurring )</option><option value="2-W-0">One Time ( for 2 week access, non-recurring )</option><option value="3-W-0">One Time ( for 3 week access, non-recurring )</option></optgroup><optgroup label="Months / Non-Recurring"><option value="1-M-0">One Time ( for 1 month access, non-recurring )</option><option value="2-M-0">One Time ( for 2 month access, non-recurring )</option><option value="3-M-0">One Time ( for 3 month access, non-recurring )</option><option value="4-M-0">One Time ( for 4 month access, non-recurring )</option><option value="5-M-0">One Time ( for 5 month access, non-recurring )</option><option value="6-M-0">One Time ( for 6 month access, non-recurring )</option></optgroup><optgroup label="Years / Non-Recurring"><option value="1-Y-0">One Time ( for 1 year access, non-recurring )</option><option value="2-Y-0">One Time ( for 2 year access, non-recurring )</option><option value="3-Y-0">One Time ( for 3 year access, non-recurring )</option><option value="4-Y-0">One Time ( for 4 year access, non-recurring )</option><option value="5-Y-0">One Time ( for 5 year access, non-recurring )</option></optgroup><optgroup label="Lifetime / Buy Now / Non-Recurring / No Trial"><option value="1-L-0">Buy Now ( for lifetime access, no-trial, non-recurring )</option></optgroup></select></p>' . "\n";
168
- echo '<p>Checkout Page Style [<a href="#" onclick="alert(\'Optional. This can be configured inside your PayPal® account. PayPal® allows you to create Custom Page Styles, and assign a unique name to them. Once you\\\'ve created a Custom Page Style at PayPal®, you can enter that Page Style here.\'); return false;">?</a>]: <input type="text" id="ws-plugin--s2member-level3-page-style" value="paypal" size="10" /> <select id="ws-plugin--s2member-level3-currency"><optgroup label="Currency"><option value="USD" title="U.S. Dollar">USD</option><option value="AUD" title="Australian Dollar">AUD</option><option value="BRL" title="Brazilian Real">BRL</option><option value="CAD" title="Canadian Dollar">CAD</option><option value="CZK" title="Czech Koruna">CZK</option><option value="DKK" title="Danish Krone">DKK</option><option value="EUR" title="Euro">EUR</option><option value="HKD" title="Hong Kong Dollar">HKD</option><option value="HUF" title="Hungarian Forint">HUF</option><option value="ILS" title="Israeli New Sheqel">ILS</option><option value="JPY" title="Japanese Yen">JPY</option><option value="MYR" title="Malaysian Ringgit">MYR</option><option value="MXN" title="Mexican Peso">MXN</option><option value="NOK" title="Norwegian Krone">NOK</option><option value="NZD" title="New Zealand Dollar">NZD</option><option value="PHP" title="Philippine Peso">PHP</option><option value="PLN" title="Polish Zloty">PLN</option><option value="GBP" title="Pound Sterling">GBP</option><option value="SGD" title="Singapore Dollar">SGD</option><option value="SEK" title="Swedish Krona">SEK</option><option value="CHF" title="Swiss Franc">CHF</option><option value="TWD" title="Taiwan New Dollar">TWD</option><option value="THB" title="Thai Baht">THB</option><option value="USD" title="U.S. Dollar">USD</option></optgroup></select> <input type="button" value="Generate Button Code" onclick="ws_plugin__s2member_paypalButtonGenerate(3);" class="button-primary" /></p>' . "\n";
 
169
  echo '</td>' . "\n";
170
  /**/
171
  echo '</tr>' . "\n";
@@ -176,6 +181,7 @@ if (get_option ("ws_plugin__s2member_configured") && $GLOBALS["WS_PLUGIN__"]["s2
176
  $ws_plugin__s2member_temp_s = trim (file_get_contents (dirname (__FILE__) . "/shortcode.html"));
177
  $ws_plugin__s2member_temp_s = preg_replace ("/%%domain%%/", strtolower ($_SERVER["HTTP_HOST"]), $ws_plugin__s2member_temp_s);
178
  $ws_plugin__s2member_temp_s = preg_replace ("/%%level%%/", "3", $ws_plugin__s2member_temp_s);
 
179
  echo '<input id="ws-plugin--s2member-level3-shortcode" type="text" value="' . format_to_edit ($ws_plugin__s2member_temp_s) . '" onclick="this.select ();" /><br /><br />' . "\n";
180
  echo '<strong>Resulting PayPal® Button Code:</strong> ( ultimately, your Shortcode will produce this snippet )<br />' . "\n";
181
  echo '<textarea id="ws-plugin--s2member-level3-button" rows="8" wrap="off" onclick="this.select ();">';
@@ -200,19 +206,19 @@ if (get_option ("ws_plugin__s2member_configured") && $GLOBALS["WS_PLUGIN__"]["s2
200
  /**/
201
  echo '</div>' . "\n";
202
  /**/
203
- echo '<div class="ws-menu-page-group" title="PayPal® Button For Level #4 Subscriptions">' . "\n";
204
  /**/
205
  echo '<div class="ws-menu-page-section ws-plugin--s2member-button-code-4-section">' . "\n";
206
- echo '<h3>Button Code Generator For Level #4 Subscriptions</h3>' . "\n";
207
- echo '<p>Very simple. All you do is customize the form fields provided, for each Membership Level that you plan to offer. Then press (Generate Button Code). These special subscription buttons are customized to work with s2Member seamlessly. User accounts will be activated instantly, in an automated fashion. When you, or a User, cancels their membership, or fails to make payments on time, s2Member will automatically terminate their membership privileges using automated routines. s2Member makes extensive use of the PayPal® IPN service, which receives updates directly from PayPal® behind the scenes.</p>' . "\n";
208
- echo '<p><em>* Buttons are NOT saved here. This is only a Button Generator. Once you\'ve generated your Button, copy/paste it into your Membership Options Page. If you lose your Button Code, you\'ll need to come back &amp; regenerate a new one. If you\'re currently in Sandbox testing mode, please remember to come back and regenerate new Buttons once you go live.</em></p>' . "\n";
209
  /**/
210
  echo '<table class="form-table">' . "\n";
211
  echo '<tbody>' . "\n";
212
  echo '<tr>' . "\n";
213
  /**/
214
  echo '<th class="ws-menu-page-th-side">' . "\n";
215
- echo '<label for="ws-plugin--s2member-level4-button">' . "\n";
216
  echo 'Button Code<br />For Level #4:<br /><br />' . "\n";
217
  echo '<div id="ws-plugin--s2member-level4-button-prev"></div>' . "\n";
218
  echo '</label>' . "\n";
@@ -221,7 +227,8 @@ if (get_option ("ws_plugin__s2member_configured") && $GLOBALS["WS_PLUGIN__"]["s2
221
  echo '<td>' . "\n";
222
  echo '<p id="ws-plugin--s2member-level4-trial-line">I\'ll offer the first <input type="text" id="ws-plugin--s2member-level4-trial-period" value="0" size="2" /> <select id="ws-plugin--s2member-level4-trial-term"><option value="D" selected="selected">Days</option><option value="W">Weeks</option><option value="M">Months</option><option value="Y">Years</option></select> free.</p>' . "\n";
223
  echo '<p><span id="ws-plugin--s2member-level4-trial-then">Then, </span>I want to charge: $<input type="text" id="ws-plugin--s2member-level4-amount" value="0.01" size="4" /> / <select id="ws-plugin--s2member-level4-term"><optgroup label="Recurring Subscriptions"><option value="1-D-1">Daily ( recurring charge, for ongoing access )</option><option value="1-W-1">Weekly ( recurring charge, for ongoing access )</option><option value="1-M-1" selected="selected">Monthly ( recurring charge, for ongoing access )</option><option value="3-M-1">Quarterly ( recurring charge, for ongoing access )</option><option value="1-Y-1">Yearly ( recurring charge, for ongoing access )</option></optgroup><optgroup label="Days / Non-Recurring"><option value="1-D-0">One Time ( for 1 day access, non-recurring )</option><option value="2-D-0">One Time ( for 2 day access, non-recurring )</option><option value="3-D-0">One Time ( for 3 day access, non-recurring )</option><option value="4-D-0">One Time ( for 4 day access, non-recurring )</option><option value="5-D-0">One Time ( for 5 day access, non-recurring )</option><option value="6-D-0">One Time ( for 6 day access, non-recurring )</option></optgroup><optgroup label="Weeks / Non-Recurring"><option value="1-W-0">One Time ( for 1 week access, non-recurring )</option><option value="2-W-0">One Time ( for 2 week access, non-recurring )</option><option value="3-W-0">One Time ( for 3 week access, non-recurring )</option></optgroup><optgroup label="Months / Non-Recurring"><option value="1-M-0">One Time ( for 1 month access, non-recurring )</option><option value="2-M-0">One Time ( for 2 month access, non-recurring )</option><option value="3-M-0">One Time ( for 3 month access, non-recurring )</option><option value="4-M-0">One Time ( for 4 month access, non-recurring )</option><option value="5-M-0">One Time ( for 5 month access, non-recurring )</option><option value="6-M-0">One Time ( for 6 month access, non-recurring )</option></optgroup><optgroup label="Years / Non-Recurring"><option value="1-Y-0">One Time ( for 1 year access, non-recurring )</option><option value="2-Y-0">One Time ( for 2 year access, non-recurring )</option><option value="3-Y-0">One Time ( for 3 year access, non-recurring )</option><option value="4-Y-0">One Time ( for 4 year access, non-recurring )</option><option value="5-Y-0">One Time ( for 5 year access, non-recurring )</option></optgroup><optgroup label="Lifetime / Buy Now / Non-Recurring / No Trial"><option value="1-L-0">Buy Now ( for lifetime access, no-trial, non-recurring )</option></optgroup></select></p>' . "\n";
224
- echo '<p>Checkout Page Style [<a href="#" onclick="alert(\'Optional. This can be configured inside your PayPal® account. PayPal® allows you to create Custom Page Styles, and assign a unique name to them. Once you\\\'ve created a Custom Page Style at PayPal®, you can enter that Page Style here.\'); return false;">?</a>]: <input type="text" id="ws-plugin--s2member-level4-page-style" value="paypal" size="10" /> <select id="ws-plugin--s2member-level4-currency"><optgroup label="Currency"><option value="USD" title="U.S. Dollar">USD</option><option value="AUD" title="Australian Dollar">AUD</option><option value="BRL" title="Brazilian Real">BRL</option><option value="CAD" title="Canadian Dollar">CAD</option><option value="CZK" title="Czech Koruna">CZK</option><option value="DKK" title="Danish Krone">DKK</option><option value="EUR" title="Euro">EUR</option><option value="HKD" title="Hong Kong Dollar">HKD</option><option value="HUF" title="Hungarian Forint">HUF</option><option value="ILS" title="Israeli New Sheqel">ILS</option><option value="JPY" title="Japanese Yen">JPY</option><option value="MYR" title="Malaysian Ringgit">MYR</option><option value="MXN" title="Mexican Peso">MXN</option><option value="NOK" title="Norwegian Krone">NOK</option><option value="NZD" title="New Zealand Dollar">NZD</option><option value="PHP" title="Philippine Peso">PHP</option><option value="PLN" title="Polish Zloty">PLN</option><option value="GBP" title="Pound Sterling">GBP</option><option value="SGD" title="Singapore Dollar">SGD</option><option value="SEK" title="Swedish Krona">SEK</option><option value="CHF" title="Swiss Franc">CHF</option><option value="TWD" title="Taiwan New Dollar">TWD</option><option value="THB" title="Thai Baht">THB</option><option value="USD" title="U.S. Dollar">USD</option></optgroup></select> <input type="button" value="Generate Button Code" onclick="ws_plugin__s2member_paypalButtonGenerate(4);" class="button-primary" /></p>' . "\n";
 
225
  echo '</td>' . "\n";
226
  /**/
227
  echo '</tr>' . "\n";
@@ -232,6 +239,7 @@ if (get_option ("ws_plugin__s2member_configured") && $GLOBALS["WS_PLUGIN__"]["s2
232
  $ws_plugin__s2member_temp_s = trim (file_get_contents (dirname (__FILE__) . "/shortcode.html"));
233
  $ws_plugin__s2member_temp_s = preg_replace ("/%%domain%%/", strtolower ($_SERVER["HTTP_HOST"]), $ws_plugin__s2member_temp_s);
234
  $ws_plugin__s2member_temp_s = preg_replace ("/%%level%%/", "4", $ws_plugin__s2member_temp_s);
 
235
  echo '<input id="ws-plugin--s2member-level4-shortcode" type="text" value="' . format_to_edit ($ws_plugin__s2member_temp_s) . '" onclick="this.select ();" /><br /><br />' . "\n";
236
  echo '<strong>Resulting PayPal® Button Code:</strong> ( ultimately, your Shortcode will produce this snippet )<br />' . "\n";
237
  echo '<textarea id="ws-plugin--s2member-level4-button" rows="8" wrap="off" onclick="this.select ();">';
@@ -256,15 +264,235 @@ if (get_option ("ws_plugin__s2member_configured") && $GLOBALS["WS_PLUGIN__"]["s2
256
  /**/
257
  echo '</div>' . "\n";
258
  /**/
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
259
  echo '</form>' . "\n";
260
  }
261
  else /* They need to first configure the options. */
262
- echo '<p>Please configure the s2Member PayPal® Options first. Once your PayPal® Options have been properly configured, return to this page &amp; generate your PayPal® subscription button(s).</p>' . "\n";
263
  /**/
264
  echo '</td>' . "\n";
265
  /**/
266
  echo '<td class="ws-menu-page-table-r">' . "\n";
267
  /**/
 
 
268
  echo ($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["menu-r"]["tools"]) ? '<div class="ws-menu-page-tools"><img src="' . $GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["dir_url"] . '/images/brand-tools.png" alt="." /></div>' . "\n" : '';
269
  /**/
270
  echo ($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["menu-r"]["tips"]) ? '<div class="ws-menu-page-tips"><a href="' . ws_plugin__s2member_parse_readme_value ("Customization URI") . '"><img src="' . $GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["dir_url"] . '/images/brand-tips.png" alt="." /></a></div>' . "\n" : '';
19
  echo '<div class="wrap ws-menu-page">' . "\n";
20
  /**/
21
  echo '<div id="icon-plugins" class="icon32"><br /></div>' . "\n";
22
+ echo '<h2><div>Developed by <a href="' . ws_plugin__s2member_parse_readme_value ("Plugin URI") . '"><img src="' . $GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["dir_url"] . '/images/brand-light.png" alt="." /></a></div>s2Member / PayPal® Button Codes</h2>' . "\n";
23
  /**/
24
  echo '<div class="ws-menu-page-hr"></div>' . "\n";
25
  /**/
32
  {
33
  echo '<form method="post" name="ws_plugin__s2member_buttons_form" id="ws-plugin--s2member-buttons-form">' . "\n";
34
  /**/
35
+ echo '<div class="ws-menu-page-group" title="PayPal® Buttons For Level #1 Access">' . "\n";
36
  /**/
37
  echo '<div class="ws-menu-page-section ws-plugin--s2member-button-code-1-section">' . "\n";
38
+ echo '<h3>Button Code Generator For Level #1 Access</h3>' . "\n";
39
+ echo '<p>Very simple. All you do is customize the form fields provided, for each Membership Level that you plan to offer. Then press (Generate Button Code). These special PayPal® Buttons are customized to work with s2Member seamlessly. Member accounts will be activated instantly, in an automated fashion. When you, or a Member, cancels their membership, or fails to make payments on time, s2Member will automatically terminate their membership privileges. s2Member makes extensive use of the PayPal® IPN service. s2Member receives updates from PayPal® behind-the-scenes.</p>' . "\n";
40
+ echo '<p><em>* Buttons are NOT saved here. This is only a Button Generator. Once you\'ve generated your Button, copy/paste it into your Membership Options Page. If you lose your Button Code, you\'ll need to come back &amp; re-generate a new one. If you\'re in Sandbox Test-Mode, and you\'re NOT using the Shortcode Format, please remember to come back and re-generate your Buttons before you go live.</em></p>' . "\n";
41
  /**/
42
  echo '<table class="form-table">' . "\n";
43
  echo '<tbody>' . "\n";
44
  echo '<tr>' . "\n";
45
  /**/
46
  echo '<th class="ws-menu-page-th-side">' . "\n";
47
+ echo '<label for="ws-plugin--s2member-level1-shortcode">' . "\n";
48
  echo 'Button Code<br />For Level #1:<br /><br />' . "\n";
49
  echo '<div id="ws-plugin--s2member-level1-button-prev"></div>' . "\n";
50
  echo '</label>' . "\n";
53
  echo '<td>' . "\n";
54
  echo '<p id="ws-plugin--s2member-level1-trial-line">I\'ll offer the first <input type="text" id="ws-plugin--s2member-level1-trial-period" value="0" size="2" /> <select id="ws-plugin--s2member-level1-trial-term"><option value="D" selected="selected">Days</option><option value="W">Weeks</option><option value="M">Months</option><option value="Y">Years</option></select> free.</p>' . "\n";
55
  echo '<p><span id="ws-plugin--s2member-level1-trial-then">Then, </span>I want to charge: $<input type="text" id="ws-plugin--s2member-level1-amount" value="0.01" size="4" /> / <select id="ws-plugin--s2member-level1-term"><optgroup label="Recurring Subscriptions"><option value="1-D-1">Daily ( recurring charge, for ongoing access )</option><option value="1-W-1">Weekly ( recurring charge, for ongoing access )</option><option value="1-M-1" selected="selected">Monthly ( recurring charge, for ongoing access )</option><option value="3-M-1">Quarterly ( recurring charge, for ongoing access )</option><option value="1-Y-1">Yearly ( recurring charge, for ongoing access )</option></optgroup><optgroup label="Days / Non-Recurring"><option value="1-D-0">One Time ( for 1 day access, non-recurring )</option><option value="2-D-0">One Time ( for 2 day access, non-recurring )</option><option value="3-D-0">One Time ( for 3 day access, non-recurring )</option><option value="4-D-0">One Time ( for 4 day access, non-recurring )</option><option value="5-D-0">One Time ( for 5 day access, non-recurring )</option><option value="6-D-0">One Time ( for 6 day access, non-recurring )</option></optgroup><optgroup label="Weeks / Non-Recurring"><option value="1-W-0">One Time ( for 1 week access, non-recurring )</option><option value="2-W-0">One Time ( for 2 week access, non-recurring )</option><option value="3-W-0">One Time ( for 3 week access, non-recurring )</option></optgroup><optgroup label="Months / Non-Recurring"><option value="1-M-0">One Time ( for 1 month access, non-recurring )</option><option value="2-M-0">One Time ( for 2 month access, non-recurring )</option><option value="3-M-0">One Time ( for 3 month access, non-recurring )</option><option value="4-M-0">One Time ( for 4 month access, non-recurring )</option><option value="5-M-0">One Time ( for 5 month access, non-recurring )</option><option value="6-M-0">One Time ( for 6 month access, non-recurring )</option></optgroup><optgroup label="Years / Non-Recurring"><option value="1-Y-0">One Time ( for 1 year access, non-recurring )</option><option value="2-Y-0">One Time ( for 2 year access, non-recurring )</option><option value="3-Y-0">One Time ( for 3 year access, non-recurring )</option><option value="4-Y-0">One Time ( for 4 year access, non-recurring )</option><option value="5-Y-0">One Time ( for 5 year access, non-recurring )</option></optgroup><optgroup label="Lifetime / Buy Now / Non-Recurring / No Trial"><option value="1-L-0">Buy Now ( for lifetime access, no-trial, non-recurring )</option></optgroup></select></p>' . "\n";
56
+ echo '<p>Checkout Page Style <a href="#" onclick="alert(\'Optional. This can be configured inside your PayPal® account. PayPal® allows you to create Custom Page Styles, and assign a unique name to them. You can add your own header image and color selection to the checkout form. Once you\\\'ve created a Custom Page Style at PayPal®, you can enter that Page Style here.\'); return false;">[?]</a>: <input type="text" id="ws-plugin--s2member-level1-page-style" value="paypal" size="18" /> <select id="ws-plugin--s2member-level1-currency"><optgroup label="Currency"><option value="USD" title="U.S. Dollar">USD</option><option value="AUD" title="Australian Dollar">AUD</option><option value="BRL" title="Brazilian Real">BRL</option><option value="CAD" title="Canadian Dollar">CAD</option><option value="CZK" title="Czech Koruna">CZK</option><option value="DKK" title="Danish Krone">DKK</option><option value="EUR" title="Euro">EUR</option><option value="HKD" title="Hong Kong Dollar">HKD</option><option value="HUF" title="Hungarian Forint">HUF</option><option value="ILS" title="Israeli New Sheqel">ILS</option><option value="JPY" title="Japanese Yen">JPY</option><option value="MYR" title="Malaysian Ringgit">MYR</option><option value="MXN" title="Mexican Peso">MXN</option><option value="NOK" title="Norwegian Krone">NOK</option><option value="NZD" title="New Zealand Dollar">NZD</option><option value="PHP" title="Philippine Peso">PHP</option><option value="PLN" title="Polish Zloty">PLN</option><option value="GBP" title="Pound Sterling">GBP</option><option value="SGD" title="Singapore Dollar">SGD</option><option value="SEK" title="Swedish Krona">SEK</option><option value="CHF" title="Swiss Franc">CHF</option><option value="TWD" title="Taiwan New Dollar">TWD</option><option value="THB" title="Thai Baht">THB</option><option value="USD" title="U.S. Dollar">USD</option></optgroup></select> <input type="button" value="Generate Button Code" onclick="ws_plugin__s2member_paypalButtonGenerate(\'level1\');" class="button-primary" /></p>' . "\n";
57
+ echo '<p>Custom Capabilities ( comma delimited ) <a href="#" onclick="alert(\'Optional. This is VERY advanced. For full details, see:\\ns2Member -> API Scripting -> Custom Capabilities.\'); return false;">[?]</a> <input type="text" id="ws-plugin--s2member-level1-ccaps" size="40" maxlength="125" /></p>' . "\n";
58
  echo '</td>' . "\n";
59
  /**/
60
  echo '</tr>' . "\n";
65
  $ws_plugin__s2member_temp_s = trim (file_get_contents (dirname (__FILE__) . "/shortcode.html"));
66
  $ws_plugin__s2member_temp_s = preg_replace ("/%%domain%%/", strtolower ($_SERVER["HTTP_HOST"]), $ws_plugin__s2member_temp_s);
67
  $ws_plugin__s2member_temp_s = preg_replace ("/%%level%%/", "1", $ws_plugin__s2member_temp_s);
68
+ $ws_plugin__s2member_temp_s = preg_replace ("/%%level_label%%/", $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["level1_label"], $ws_plugin__s2member_temp_s);
69
  echo '<input id="ws-plugin--s2member-level1-shortcode" type="text" value="' . format_to_edit ($ws_plugin__s2member_temp_s) . '" onclick="this.select ();" /><br /><br />' . "\n";
70
  echo '<strong>Resulting PayPal® Button Code:</strong> ( ultimately, your Shortcode will produce this snippet )<br />' . "\n";
71
  echo '<textarea id="ws-plugin--s2member-level1-button" rows="8" wrap="off" onclick="this.select ();">';
90
  /**/
91
  echo '</div>' . "\n";
92
  /**/
93
+ echo '<div class="ws-menu-page-group" title="PayPal® Buttons For Level #2 Access">' . "\n";
94
  /**/
95
  echo '<div class="ws-menu-page-section ws-plugin--s2member-button-code-2-section">' . "\n";
96
+ echo '<h3>Button Code Generator For Level #2 Access</h3>' . "\n";
97
+ echo '<p>Very simple. All you do is customize the form fields provided, for each Membership Level that you plan to offer. Then press (Generate Button Code). These special PayPal® Buttons are customized to work with s2Member seamlessly. Member accounts will be activated instantly, in an automated fashion. When you, or a Member, cancels their membership, or fails to make payments on time, s2Member will automatically terminate their membership privileges. s2Member makes extensive use of the PayPal® IPN service. s2Member receives updates from PayPal® behind-the-scenes.</p>' . "\n";
98
+ echo '<p><em>* Buttons are NOT saved here. This is only a Button Generator. Once you\'ve generated your Button, copy/paste it into your Membership Options Page. If you lose your Button Code, you\'ll need to come back &amp; re-generate a new one. If you\'re in Sandbox Test-Mode, and you\'re NOT using the Shortcode Format, please remember to come back and re-generate your Buttons before you go live.</em></p>' . "\n";
99
  /**/
100
  echo '<table class="form-table">' . "\n";
101
  echo '<tbody>' . "\n";
102
  echo '<tr>' . "\n";
103
  /**/
104
  echo '<th class="ws-menu-page-th-side">' . "\n";
105
+ echo '<label for="ws-plugin--s2member-level2-shortcode">' . "\n";
106
  echo 'Button Code<br />For Level #2:<br /><br />' . "\n";
107
  echo '<div id="ws-plugin--s2member-level2-button-prev"></div>' . "\n";
108
  echo '</label>' . "\n";
111
  echo '<td>' . "\n";
112
  echo '<p id="ws-plugin--s2member-level2-trial-line">I\'ll offer the first <input type="text" id="ws-plugin--s2member-level2-trial-period" value="0" size="2" /> <select id="ws-plugin--s2member-level2-trial-term"><option value="D" selected="selected">Days</option><option value="W">Weeks</option><option value="M">Months</option><option value="Y">Years</option></select> free.</p>' . "\n";
113
  echo '<p><span id="ws-plugin--s2member-level2-trial-then">Then, </span>I want to charge: $<input type="text" id="ws-plugin--s2member-level2-amount" value="0.01" size="4" /> / <select id="ws-plugin--s2member-level2-term"><optgroup label="Recurring Subscriptions"><option value="1-D-1">Daily ( recurring charge, for ongoing access )</option><option value="1-W-1">Weekly ( recurring charge, for ongoing access )</option><option value="1-M-1" selected="selected">Monthly ( recurring charge, for ongoing access )</option><option value="3-M-1">Quarterly ( recurring charge, for ongoing access )</option><option value="1-Y-1">Yearly ( recurring charge, for ongoing access )</option></optgroup><optgroup label="Days / Non-Recurring"><option value="1-D-0">One Time ( for 1 day access, non-recurring )</option><option value="2-D-0">One Time ( for 2 day access, non-recurring )</option><option value="3-D-0">One Time ( for 3 day access, non-recurring )</option><option value="4-D-0">One Time ( for 4 day access, non-recurring )</option><option value="5-D-0">One Time ( for 5 day access, non-recurring )</option><option value="6-D-0">One Time ( for 6 day access, non-recurring )</option></optgroup><optgroup label="Weeks / Non-Recurring"><option value="1-W-0">One Time ( for 1 week access, non-recurring )</option><option value="2-W-0">One Time ( for 2 week access, non-recurring )</option><option value="3-W-0">One Time ( for 3 week access, non-recurring )</option></optgroup><optgroup label="Months / Non-Recurring"><option value="1-M-0">One Time ( for 1 month access, non-recurring )</option><option value="2-M-0">One Time ( for 2 month access, non-recurring )</option><option value="3-M-0">One Time ( for 3 month access, non-recurring )</option><option value="4-M-0">One Time ( for 4 month access, non-recurring )</option><option value="5-M-0">One Time ( for 5 month access, non-recurring )</option><option value="6-M-0">One Time ( for 6 month access, non-recurring )</option></optgroup><optgroup label="Years / Non-Recurring"><option value="1-Y-0">One Time ( for 1 year access, non-recurring )</option><option value="2-Y-0">One Time ( for 2 year access, non-recurring )</option><option value="3-Y-0">One Time ( for 3 year access, non-recurring )</option><option value="4-Y-0">One Time ( for 4 year access, non-recurring )</option><option value="5-Y-0">One Time ( for 5 year access, non-recurring )</option></optgroup><optgroup label="Lifetime / Buy Now / Non-Recurring / No Trial"><option value="1-L-0">Buy Now ( for lifetime access, no-trial, non-recurring )</option></optgroup></select></p>' . "\n";
114
+ echo '<p>Checkout Page Style <a href="#" onclick="alert(\'Optional. This can be configured inside your PayPal® account. PayPal® allows you to create Custom Page Styles, and assign a unique name to them. You can add your own header image and color selection to the checkout form. Once you\\\'ve created a Custom Page Style at PayPal®, you can enter that Page Style here.\'); return false;">[?]</a>: <input type="text" id="ws-plugin--s2member-level2-page-style" value="paypal" size="18" /> <select id="ws-plugin--s2member-level2-currency"><optgroup label="Currency"><option value="USD" title="U.S. Dollar">USD</option><option value="AUD" title="Australian Dollar">AUD</option><option value="BRL" title="Brazilian Real">BRL</option><option value="CAD" title="Canadian Dollar">CAD</option><option value="CZK" title="Czech Koruna">CZK</option><option value="DKK" title="Danish Krone">DKK</option><option value="EUR" title="Euro">EUR</option><option value="HKD" title="Hong Kong Dollar">HKD</option><option value="HUF" title="Hungarian Forint">HUF</option><option value="ILS" title="Israeli New Sheqel">ILS</option><option value="JPY" title="Japanese Yen">JPY</option><option value="MYR" title="Malaysian Ringgit">MYR</option><option value="MXN" title="Mexican Peso">MXN</option><option value="NOK" title="Norwegian Krone">NOK</option><option value="NZD" title="New Zealand Dollar">NZD</option><option value="PHP" title="Philippine Peso">PHP</option><option value="PLN" title="Polish Zloty">PLN</option><option value="GBP" title="Pound Sterling">GBP</option><option value="SGD" title="Singapore Dollar">SGD</option><option value="SEK" title="Swedish Krona">SEK</option><option value="CHF" title="Swiss Franc">CHF</option><option value="TWD" title="Taiwan New Dollar">TWD</option><option value="THB" title="Thai Baht">THB</option><option value="USD" title="U.S. Dollar">USD</option></optgroup></select> <input type="button" value="Generate Button Code" onclick="ws_plugin__s2member_paypalButtonGenerate(\'level2\');" class="button-primary" /></p>' . "\n";
115
+ echo '<p>Custom Capabilities ( comma delimited ) <a href="#" onclick="alert(\'Optional. This is VERY advanced. For full details, see:\\ns2Member -> API Scripting -> Custom Capabilities.\'); return false;">[?]</a> <input type="text" id="ws-plugin--s2member-level2-ccaps" size="40" maxlength="125" /></p>' . "\n";
116
  echo '</td>' . "\n";
117
  /**/
118
  echo '</tr>' . "\n";
123
  $ws_plugin__s2member_temp_s = trim (file_get_contents (dirname (__FILE__) . "/shortcode.html"));
124
  $ws_plugin__s2member_temp_s = preg_replace ("/%%domain%%/", strtolower ($_SERVER["HTTP_HOST"]), $ws_plugin__s2member_temp_s);
125
  $ws_plugin__s2member_temp_s = preg_replace ("/%%level%%/", "2", $ws_plugin__s2member_temp_s);
126
+ $ws_plugin__s2member_temp_s = preg_replace ("/%%level_label%%/", $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["level2_label"], $ws_plugin__s2member_temp_s);
127
  echo '<input id="ws-plugin--s2member-level2-shortcode" type="text" value="' . format_to_edit ($ws_plugin__s2member_temp_s) . '" onclick="this.select ();" /><br /><br />' . "\n";
128
  echo '<strong>Resulting PayPal® Button Code:</strong> ( ultimately, your Shortcode will produce this snippet )<br />' . "\n";
129
  echo '<textarea id="ws-plugin--s2member-level2-button" rows="8" wrap="off" onclick="this.select ();">';
148
  /**/
149
  echo '</div>' . "\n";
150
  /**/
151
+ echo '<div class="ws-menu-page-group" title="PayPal® Buttons For Level #3 Access">' . "\n";
152
  /**/
153
  echo '<div class="ws-menu-page-section ws-plugin--s2member-button-code-3-section">' . "\n";
154
+ echo '<h3>Button Code Generator For Level #3 Access</h3>' . "\n";
155
+ echo '<p>Very simple. All you do is customize the form fields provided, for each Membership Level that you plan to offer. Then press (Generate Button Code). These special PayPal® Buttons are customized to work with s2Member seamlessly. Member accounts will be activated instantly, in an automated fashion. When you, or a Member, cancels their membership, or fails to make payments on time, s2Member will automatically terminate their membership privileges. s2Member makes extensive use of the PayPal® IPN service. s2Member receives updates from PayPal® behind-the-scenes.</p>' . "\n";
156
+ echo '<p><em>* Buttons are NOT saved here. This is only a Button Generator. Once you\'ve generated your Button, copy/paste it into your Membership Options Page. If you lose your Button Code, you\'ll need to come back &amp; re-generate a new one. If you\'re in Sandbox Test-Mode, and you\'re NOT using the Shortcode Format, please remember to come back and re-generate your Buttons before you go live.</em></p>' . "\n";
157
  /**/
158
  echo '<table class="form-table">' . "\n";
159
  echo '<tbody>' . "\n";
160
  echo '<tr>' . "\n";
161
  /**/
162
  echo '<th class="ws-menu-page-th-side">' . "\n";
163
+ echo '<label for="ws-plugin--s2member-level3-shortcode">' . "\n";
164
  echo 'Button Code<br />For Level #3:<br /><br />' . "\n";
165
  echo '<div id="ws-plugin--s2member-level3-button-prev"></div>' . "\n";
166
  echo '</label>' . "\n";
169
  echo '<td>' . "\n";
170
  echo '<p id="ws-plugin--s2member-level3-trial-line">I\'ll offer the first <input type="text" id="ws-plugin--s2member-level3-trial-period" value="0" size="2" /> <select id="ws-plugin--s2member-level3-trial-term"><option value="D" selected="selected">Days</option><option value="W">Weeks</option><option value="M">Months</option><option value="Y">Years</option></select> free.</p>' . "\n";
171
  echo '<p><span id="ws-plugin--s2member-level3-trial-then">Then, </span>I want to charge: $<input type="text" id="ws-plugin--s2member-level3-amount" value="0.01" size="4" /> / <select id="ws-plugin--s2member-level3-term"><optgroup label="Recurring Subscriptions"><option value="1-D-1">Daily ( recurring charge, for ongoing access )</option><option value="1-W-1">Weekly ( recurring charge, for ongoing access )</option><option value="1-M-1" selected="selected">Monthly ( recurring charge, for ongoing access )</option><option value="3-M-1">Quarterly ( recurring charge, for ongoing access )</option><option value="1-Y-1">Yearly ( recurring charge, for ongoing access )</option></optgroup><optgroup label="Days / Non-Recurring"><option value="1-D-0">One Time ( for 1 day access, non-recurring )</option><option value="2-D-0">One Time ( for 2 day access, non-recurring )</option><option value="3-D-0">One Time ( for 3 day access, non-recurring )</option><option value="4-D-0">One Time ( for 4 day access, non-recurring )</option><option value="5-D-0">One Time ( for 5 day access, non-recurring )</option><option value="6-D-0">One Time ( for 6 day access, non-recurring )</option></optgroup><optgroup label="Weeks / Non-Recurring"><option value="1-W-0">One Time ( for 1 week access, non-recurring )</option><option value="2-W-0">One Time ( for 2 week access, non-recurring )</option><option value="3-W-0">One Time ( for 3 week access, non-recurring )</option></optgroup><optgroup label="Months / Non-Recurring"><option value="1-M-0">One Time ( for 1 month access, non-recurring )</option><option value="2-M-0">One Time ( for 2 month access, non-recurring )</option><option value="3-M-0">One Time ( for 3 month access, non-recurring )</option><option value="4-M-0">One Time ( for 4 month access, non-recurring )</option><option value="5-M-0">One Time ( for 5 month access, non-recurring )</option><option value="6-M-0">One Time ( for 6 month access, non-recurring )</option></optgroup><optgroup label="Years / Non-Recurring"><option value="1-Y-0">One Time ( for 1 year access, non-recurring )</option><option value="2-Y-0">One Time ( for 2 year access, non-recurring )</option><option value="3-Y-0">One Time ( for 3 year access, non-recurring )</option><option value="4-Y-0">One Time ( for 4 year access, non-recurring )</option><option value="5-Y-0">One Time ( for 5 year access, non-recurring )</option></optgroup><optgroup label="Lifetime / Buy Now / Non-Recurring / No Trial"><option value="1-L-0">Buy Now ( for lifetime access, no-trial, non-recurring )</option></optgroup></select></p>' . "\n";
172
+ echo '<p>Checkout Page Style <a href="#" onclick="alert(\'Optional. This can be configured inside your PayPal® account. PayPal® allows you to create Custom Page Styles, and assign a unique name to them. You can add your own header image and color selection to the checkout form. Once you\\\'ve created a Custom Page Style at PayPal®, you can enter that Page Style here.\'); return false;">[?]</a>: <input type="text" id="ws-plugin--s2member-level3-page-style" value="paypal" size="18" /> <select id="ws-plugin--s2member-level3-currency"><optgroup label="Currency"><option value="USD" title="U.S. Dollar">USD</option><option value="AUD" title="Australian Dollar">AUD</option><option value="BRL" title="Brazilian Real">BRL</option><option value="CAD" title="Canadian Dollar">CAD</option><option value="CZK" title="Czech Koruna">CZK</option><option value="DKK" title="Danish Krone">DKK</option><option value="EUR" title="Euro">EUR</option><option value="HKD" title="Hong Kong Dollar">HKD</option><option value="HUF" title="Hungarian Forint">HUF</option><option value="ILS" title="Israeli New Sheqel">ILS</option><option value="JPY" title="Japanese Yen">JPY</option><option value="MYR" title="Malaysian Ringgit">MYR</option><option value="MXN" title="Mexican Peso">MXN</option><option value="NOK" title="Norwegian Krone">NOK</option><option value="NZD" title="New Zealand Dollar">NZD</option><option value="PHP" title="Philippine Peso">PHP</option><option value="PLN" title="Polish Zloty">PLN</option><option value="GBP" title="Pound Sterling">GBP</option><option value="SGD" title="Singapore Dollar">SGD</option><option value="SEK" title="Swedish Krona">SEK</option><option value="CHF" title="Swiss Franc">CHF</option><option value="TWD" title="Taiwan New Dollar">TWD</option><option value="THB" title="Thai Baht">THB</option><option value="USD" title="U.S. Dollar">USD</option></optgroup></select> <input type="button" value="Generate Button Code" onclick="ws_plugin__s2member_paypalButtonGenerate(\'level3\');" class="button-primary" /></p>' . "\n";
173
+ echo '<p>Custom Capabilities ( comma delimited ) <a href="#" onclick="alert(\'Optional. This is VERY advanced. For full details, see:\\ns2Member -> API Scripting -> Custom Capabilities.\'); return false;">[?]</a> <input type="text" id="ws-plugin--s2member-level3-ccaps" size="40" maxlength="125" /></p>' . "\n";
174
  echo '</td>' . "\n";
175
  /**/
176
  echo '</tr>' . "\n";
181
  $ws_plugin__s2member_temp_s = trim (file_get_contents (dirname (__FILE__) . "/shortcode.html"));
182
  $ws_plugin__s2member_temp_s = preg_replace ("/%%domain%%/", strtolower ($_SERVER["HTTP_HOST"]), $ws_plugin__s2member_temp_s);
183
  $ws_plugin__s2member_temp_s = preg_replace ("/%%level%%/", "3", $ws_plugin__s2member_temp_s);
184
+ $ws_plugin__s2member_temp_s = preg_replace ("/%%level_label%%/", $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["level3_label"], $ws_plugin__s2member_temp_s);
185
  echo '<input id="ws-plugin--s2member-level3-shortcode" type="text" value="' . format_to_edit ($ws_plugin__s2member_temp_s) . '" onclick="this.select ();" /><br /><br />' . "\n";
186
  echo '<strong>Resulting PayPal® Button Code:</strong> ( ultimately, your Shortcode will produce this snippet )<br />' . "\n";
187
  echo '<textarea id="ws-plugin--s2member-level3-button" rows="8" wrap="off" onclick="this.select ();">';
206
  /**/
207
  echo '</div>' . "\n";
208
  /**/
209
+ echo '<div class="ws-menu-page-group" title="PayPal® Buttons For Level #4 Access">' . "\n";
210
  /**/
211
  echo '<div class="ws-menu-page-section ws-plugin--s2member-button-code-4-section">' . "\n";
212
+ echo '<h3>Button Code Generator For Level #4 Access</h3>' . "\n";
213
+ echo '<p>Very simple. All you do is customize the form fields provided, for each Membership Level that you plan to offer. Then press (Generate Button Code). These special PayPal® Buttons are customized to work with s2Member seamlessly. Member accounts will be activated instantly, in an automated fashion. When you, or a Member, cancels their membership, or fails to make payments on time, s2Member will automatically terminate their membership privileges. s2Member makes extensive use of the PayPal® IPN service. s2Member receives updates from PayPal® behind-the-scenes.</p>' . "\n";
214
+ echo '<p><em>* Buttons are NOT saved here. This is only a Button Generator. Once you\'ve generated your Button, copy/paste it into your Membership Options Page. If you lose your Button Code, you\'ll need to come back &amp; re-generate a new one. If you\'re in Sandbox Test-Mode, and you\'re NOT using the Shortcode Format, please remember to come back and re-generate your Buttons before you go live.</em></p>' . "\n";
215
  /**/
216
  echo '<table class="form-table">' . "\n";
217
  echo '<tbody>' . "\n";
218
  echo '<tr>' . "\n";
219
  /**/
220
  echo '<th class="ws-menu-page-th-side">' . "\n";
221
+ echo '<label for="ws-plugin--s2member-level4-shortcode">' . "\n";
222
  echo 'Button Code<br />For Level #4:<br /><br />' . "\n";
223
  echo '<div id="ws-plugin--s2member-level4-button-prev"></div>' . "\n";
224
  echo '</label>' . "\n";
227
  echo '<td>' . "\n";
228
  echo '<p id="ws-plugin--s2member-level4-trial-line">I\'ll offer the first <input type="text" id="ws-plugin--s2member-level4-trial-period" value="0" size="2" /> <select id="ws-plugin--s2member-level4-trial-term"><option value="D" selected="selected">Days</option><option value="W">Weeks</option><option value="M">Months</option><option value="Y">Years</option></select> free.</p>' . "\n";
229
  echo '<p><span id="ws-plugin--s2member-level4-trial-then">Then, </span>I want to charge: $<input type="text" id="ws-plugin--s2member-level4-amount" value="0.01" size="4" /> / <select id="ws-plugin--s2member-level4-term"><optgroup label="Recurring Subscriptions"><option value="1-D-1">Daily ( recurring charge, for ongoing access )</option><option value="1-W-1">Weekly ( recurring charge, for ongoing access )</option><option value="1-M-1" selected="selected">Monthly ( recurring charge, for ongoing access )</option><option value="3-M-1">Quarterly ( recurring charge, for ongoing access )</option><option value="1-Y-1">Yearly ( recurring charge, for ongoing access )</option></optgroup><optgroup label="Days / Non-Recurring"><option value="1-D-0">One Time ( for 1 day access, non-recurring )</option><option value="2-D-0">One Time ( for 2 day access, non-recurring )</option><option value="3-D-0">One Time ( for 3 day access, non-recurring )</option><option value="4-D-0">One Time ( for 4 day access, non-recurring )</option><option value="5-D-0">One Time ( for 5 day access, non-recurring )</option><option value="6-D-0">One Time ( for 6 day access, non-recurring )</option></optgroup><optgroup label="Weeks / Non-Recurring"><option value="1-W-0">One Time ( for 1 week access, non-recurring )</option><option value="2-W-0">One Time ( for 2 week access, non-recurring )</option><option value="3-W-0">One Time ( for 3 week access, non-recurring )</option></optgroup><optgroup label="Months / Non-Recurring"><option value="1-M-0">One Time ( for 1 month access, non-recurring )</option><option value="2-M-0">One Time ( for 2 month access, non-recurring )</option><option value="3-M-0">One Time ( for 3 month access, non-recurring )</option><option value="4-M-0">One Time ( for 4 month access, non-recurring )</option><option value="5-M-0">One Time ( for 5 month access, non-recurring )</option><option value="6-M-0">One Time ( for 6 month access, non-recurring )</option></optgroup><optgroup label="Years / Non-Recurring"><option value="1-Y-0">One Time ( for 1 year access, non-recurring )</option><option value="2-Y-0">One Time ( for 2 year access, non-recurring )</option><option value="3-Y-0">One Time ( for 3 year access, non-recurring )</option><option value="4-Y-0">One Time ( for 4 year access, non-recurring )</option><option value="5-Y-0">One Time ( for 5 year access, non-recurring )</option></optgroup><optgroup label="Lifetime / Buy Now / Non-Recurring / No Trial"><option value="1-L-0">Buy Now ( for lifetime access, no-trial, non-recurring )</option></optgroup></select></p>' . "\n";
230
+ echo '<p>Checkout Page Style <a href="#" onclick="alert(\'Optional. This can be configured inside your PayPal® account. PayPal® allows you to create Custom Page Styles, and assign a unique name to them. You can add your own header image and color selection to the checkout form. Once you\\\'ve created a Custom Page Style at PayPal®, you can enter that Page Style here.\'); return false;">[?]</a>: <input type="text" id="ws-plugin--s2member-level4-page-style" value="paypal" size="18" /> <select id="ws-plugin--s2member-level4-currency"><optgroup label="Currency"><option value="USD" title="U.S. Dollar">USD</option><option value="AUD" title="Australian Dollar">AUD</option><option value="BRL" title="Brazilian Real">BRL</option><option value="CAD" title="Canadian Dollar">CAD</option><option value="CZK" title="Czech Koruna">CZK</option><option value="DKK" title="Danish Krone">DKK</option><option value="EUR" title="Euro">EUR</option><option value="HKD" title="Hong Kong Dollar">HKD</option><option value="HUF" title="Hungarian Forint">HUF</option><option value="ILS" title="Israeli New Sheqel">ILS</option><option value="JPY" title="Japanese Yen">JPY</option><option value="MYR" title="Malaysian Ringgit">MYR</option><option value="MXN" title="Mexican Peso">MXN</option><option value="NOK" title="Norwegian Krone">NOK</option><option value="NZD" title="New Zealand Dollar">NZD</option><option value="PHP" title="Philippine Peso">PHP</option><option value="PLN" title="Polish Zloty">PLN</option><option value="GBP" title="Pound Sterling">GBP</option><option value="SGD" title="Singapore Dollar">SGD</option><option value="SEK" title="Swedish Krona">SEK</option><option value="CHF" title="Swiss Franc">CHF</option><option value="TWD" title="Taiwan New Dollar">TWD</option><option value="THB" title="Thai Baht">THB</option><option value="USD" title="U.S. Dollar">USD</option></optgroup></select> <input type="button" value="Generate Button Code" onclick="ws_plugin__s2member_paypalButtonGenerate(\'level4\');" class="button-primary" /></p>' . "\n";
231
+ echo '<p>Custom Capabilities ( comma delimited ) <a href="#" onclick="alert(\'Optional. This is VERY advanced. For full details, see:\\ns2Member -> API Scripting -> Custom Capabilities.\'); return false;">[?]</a> <input type="text" id="ws-plugin--s2member-level4-ccaps" size="40" maxlength="125" /></p>' . "\n";
232
  echo '</td>' . "\n";
233
  /**/
234
  echo '</tr>' . "\n";
239
  $ws_plugin__s2member_temp_s = trim (file_get_contents (dirname (__FILE__) . "/shortcode.html"));
240
  $ws_plugin__s2member_temp_s = preg_replace ("/%%domain%%/", strtolower ($_SERVER["HTTP_HOST"]), $ws_plugin__s2member_temp_s);
241
  $ws_plugin__s2member_temp_s = preg_replace ("/%%level%%/", "4", $ws_plugin__s2member_temp_s);
242
+ $ws_plugin__s2member_temp_s = preg_replace ("/%%level_label%%/", $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["level4_label"], $ws_plugin__s2member_temp_s);
243
  echo '<input id="ws-plugin--s2member-level4-shortcode" type="text" value="' . format_to_edit ($ws_plugin__s2member_temp_s) . '" onclick="this.select ();" /><br /><br />' . "\n";
244
  echo '<strong>Resulting PayPal® Button Code:</strong> ( ultimately, your Shortcode will produce this snippet )<br />' . "\n";
245
  echo '<textarea id="ws-plugin--s2member-level4-button" rows="8" wrap="off" onclick="this.select ();">';
264
  /**/
265
  echo '</div>' . "\n";
266
  /**/
267
+ echo '<div class="ws-menu-page-group" title="PayPal® Subscr Modification Buttons">' . "\n";
268
+ /**/
269
+ echo '<div class="ws-menu-page-section ws-plugin--s2member-modification-section">' . "\n";
270
+ echo '<h3>Button Code Generator For Subscription Modifications</h3>' . "\n";
271
+ echo '<p>If you\'d like to give your Members ( and/or your Free Subscribers ) the ability to modify their billing plan, by switching to a more expensive option, or a less expensive option; generate a new PayPal® Modification Button here. Configure the updated Level, pricing, terms, etc. Then, make that new Modification Button available to Members who are logged into their existing account with you. For example, you might want to insert a "Level #2" Upgrade Button into your Login Welcome Page, which would up-sell existing Level #1 Members to a more expensive plan that you offer.</p>' . "\n";
272
+ echo '<p><em><strong>*Modification Process*</strong> When you send a Member to PayPal® using a Subscription Modification Button, PayPal® will ask them to login. Once they\'re logged in, instead of being able to signup for a new membership, PayPal® will provide them with the ability to upgrade and/or downgrade their existing membership with you, by allowing them to switch to the Membership Plan that was specified in the Subscription Modification Button. PayPal® handles this nicely, and you\'ll be happy to know that s2Member has been pre-configured to deal with this scenario as well, so that everything remains automated. Their Membership Access Level will either be promoted, or demoted, based on the actions they took at PayPal® during the modification process. Once an existing Member completes their Subscription Modification at PayPal®, they\'ll be brought back to their Login Welcome Page, instead of the registration screen.</em></p>' . "\n";
273
+ echo '<p><em><strong>*Also Works For Free Subscribers*</strong> Although a Free Subscriber does not have an existing PayPal® subscription, s2Member is capable of adapting to this scenario gracefully. Just make sure that your existing Free Subscribers ( the ones who wish to upgrade ) pay for their Membership through a Modification Button generated by s2Member. That will allow them to continue using their existing account with you. In other words, they can keep their existing Username ( and anything already associated with that Username ), rather than being forced to re-register after checkout.</em></p>' . "\n";
274
+ echo '<p><em><strong>*Make It More User-Friendly*</strong> You can make the Subscription Modification Process, more user-friendly, by setting up a <a href="#" onclick="alert(\'Optional. This can be configured inside your PayPal® account. PayPal® allows you to create Custom Page Styles, and assign a unique name to them. You can add your own header image and color selection to the checkout form. Once you\\\'ve created a Custom Page Style at PayPal®, you can tell s2Member to use that Page Style whenever you generate your Button Code.\'); return false;">Custom Page Style at PayPal®</a>, specifically for Subscription Modification Buttons. Use a custom header image, with a brief explanation to the Customer. Something like, "Log into PayPal®", "You can Modify your Subscription!".</em></p>' . "\n";
275
+ echo '<p><em>* Buttons are NOT saved here. This is only a Button Generator. Once you\'ve generated your Button, copy/paste it into your Login Welcome Page, or wherever you feel it would be most appropriate. If you lose your Button Code, you\'ll need to come back &amp; re-generate a new one. If you\'re in Sandbox Test-Mode, and you\'re NOT using the Shortcode Format, please remember to come back and re-generate your Buttons before you go live.</em></p>' . "\n";
276
+ /**/
277
+ echo '<table class="form-table">' . "\n";
278
+ echo '<tbody>' . "\n";
279
+ echo '<tr>' . "\n";
280
+ /**/
281
+ echo '<th class="ws-menu-page-th-side">' . "\n";
282
+ echo '<label for="ws-plugin--s2member-modification-shortcode">' . "\n";
283
+ echo 'Button Code<br />For Modifications:<br /><br />' . "\n";
284
+ echo '<div id="ws-plugin--s2member-modification-button-prev"></div>' . "\n";
285
+ echo '</label>' . "\n";
286
+ echo '</th>' . "\n";
287
+ /**/
288
+ echo '<td>' . "\n";
289
+ echo '<p>Modification: <select id="ws-plugin--s2member-modification-level"><optgroup label="Level #1"><option value="upgrade:1">&uarr; Upgrade To Level #1</option><option value="downgrade:1">&darr; Downgrade To Level #1</option></optgroup><optgroup label="Level #2"><option value="upgrade:2" selected="selected">&uarr; Upgrade To Level #2</option><option value="downgrade:2">&darr; Downgrade To Level #2</option></optgroup><optgroup label="Level #3"><option value="upgrade:3">&uarr; Upgrade To Level #3</option><option value="downgrade:3">&darr; Downgrade To Level #3</option></optgroup><optgroup label="Level #4"><option value="upgrade:4">&uarr; Upgrade To Level #4</option></optgroup></select></p>' . "\n";
290
+ echo '<p id="ws-plugin--s2member-modification-trial-line">I\'ll offer the first <input type="text" id="ws-plugin--s2member-modification-trial-period" value="0" size="2" /> <select id="ws-plugin--s2member-modification-trial-term"><option value="D" selected="selected">Days</option><option value="W">Weeks</option><option value="M">Months</option><option value="Y">Years</option></select> free.</p>' . "\n";
291
+ echo '<p><span id="ws-plugin--s2member-modification-trial-then">Then, </span>I want to charge: $<input type="text" id="ws-plugin--s2member-modification-amount" value="0.01" size="4" /> / <select id="ws-plugin--s2member-modification-term"><optgroup label="Recurring Subscriptions"><option value="1-D-1">Daily ( recurring charge, for ongoing access )</option><option value="1-W-1">Weekly ( recurring charge, for ongoing access )</option><option value="1-M-1" selected="selected">Monthly ( recurring charge, for ongoing access )</option><option value="3-M-1">Quarterly ( recurring charge, for ongoing access )</option><option value="1-Y-1">Yearly ( recurring charge, for ongoing access )</option></optgroup><optgroup label="Days / Non-Recurring"><option value="1-D-0">One Time ( for 1 day access, non-recurring )</option><option value="2-D-0">One Time ( for 2 day access, non-recurring )</option><option value="3-D-0">One Time ( for 3 day access, non-recurring )</option><option value="4-D-0">One Time ( for 4 day access, non-recurring )</option><option value="5-D-0">One Time ( for 5 day access, non-recurring )</option><option value="6-D-0">One Time ( for 6 day access, non-recurring )</option></optgroup><optgroup label="Weeks / Non-Recurring"><option value="1-W-0">One Time ( for 1 week access, non-recurring )</option><option value="2-W-0">One Time ( for 2 week access, non-recurring )</option><option value="3-W-0">One Time ( for 3 week access, non-recurring )</option></optgroup><optgroup label="Months / Non-Recurring"><option value="1-M-0">One Time ( for 1 month access, non-recurring )</option><option value="2-M-0">One Time ( for 2 month access, non-recurring )</option><option value="3-M-0">One Time ( for 3 month access, non-recurring )</option><option value="4-M-0">One Time ( for 4 month access, non-recurring )</option><option value="5-M-0">One Time ( for 5 month access, non-recurring )</option><option value="6-M-0">One Time ( for 6 month access, non-recurring )</option></optgroup><optgroup label="Years / Non-Recurring"><option value="1-Y-0">One Time ( for 1 year access, non-recurring )</option><option value="2-Y-0">One Time ( for 2 year access, non-recurring )</option><option value="3-Y-0">One Time ( for 3 year access, non-recurring )</option><option value="4-Y-0">One Time ( for 4 year access, non-recurring )</option><option value="5-Y-0">One Time ( for 5 year access, non-recurring )</option></optgroup><optgroup label="Lifetime / Buy Now / Non-Recurring / No Trial"><option value="1-L-0">Buy Now ( for lifetime access, no-trial, non-recurring )</option></optgroup></select></p>' . "\n";
292
+ echo '<p>Checkout Page Style <a href="#" onclick="alert(\'Optional. This can be configured inside your PayPal® account. PayPal® allows you to create Custom Page Styles, and assign a unique name to them. You can add your own header image and color selection to the checkout form. Once you\\\'ve created a Custom Page Style at PayPal®, you can enter that Page Style here.\'); return false;">[?]</a>: <input type="text" id="ws-plugin--s2member-modification-page-style" value="paypal" size="18" /> <select id="ws-plugin--s2member-modification-currency"><optgroup label="Currency"><option value="USD" title="U.S. Dollar">USD</option><option value="AUD" title="Australian Dollar">AUD</option><option value="BRL" title="Brazilian Real">BRL</option><option value="CAD" title="Canadian Dollar">CAD</option><option value="CZK" title="Czech Koruna">CZK</option><option value="DKK" title="Danish Krone">DKK</option><option value="EUR" title="Euro">EUR</option><option value="HKD" title="Hong Kong Dollar">HKD</option><option value="HUF" title="Hungarian Forint">HUF</option><option value="ILS" title="Israeli New Sheqel">ILS</option><option value="JPY" title="Japanese Yen">JPY</option><option value="MYR" title="Malaysian Ringgit">MYR</option><option value="MXN" title="Mexican Peso">MXN</option><option value="NOK" title="Norwegian Krone">NOK</option><option value="NZD" title="New Zealand Dollar">NZD</option><option value="PHP" title="Philippine Peso">PHP</option><option value="PLN" title="Polish Zloty">PLN</option><option value="GBP" title="Pound Sterling">GBP</option><option value="SGD" title="Singapore Dollar">SGD</option><option value="SEK" title="Swedish Krona">SEK</option><option value="CHF" title="Swiss Franc">CHF</option><option value="TWD" title="Taiwan New Dollar">TWD</option><option value="THB" title="Thai Baht">THB</option><option value="USD" title="U.S. Dollar">USD</option></optgroup></select> <input type="button" value="Generate Button Code" onclick="ws_plugin__s2member_paypalButtonGenerate(\'modification\');" class="button-primary" /></p>' . "\n";
293
+ echo '<p>Custom Capabilities ( comma delimited ) <a href="#" onclick="alert(\'Optional. This is VERY advanced. For full details, see:\\ns2Member -> API Scripting -> Custom Capabilities.\'); return false;">[?]</a> <input type="text" id="ws-plugin--s2member-modification-ccaps" size="40" maxlength="125" /></p>' . "\n";
294
+ echo '</td>' . "\n";
295
+ /**/
296
+ echo '</tr>' . "\n";
297
+ echo '<tr>' . "\n";
298
+ /**/
299
+ echo '<td colspan="2">' . "\n";
300
+ echo '<strong>WordPress® Shortcode:</strong> ( recommended for both the WordPress® Visual &amp; HTML Editors )<br />' . "\n";
301
+ $ws_plugin__s2member_temp_s = trim (file_get_contents (dirname (__FILE__) . "/shortcode.html"));
302
+ $ws_plugin__s2member_temp_s = preg_replace ("/\/]$/", 'mb="1" /]', $ws_plugin__s2member_temp_s);
303
+ $ws_plugin__s2member_temp_s = preg_replace ("/%%domain%%/", strtolower ($_SERVER["HTTP_HOST"]), $ws_plugin__s2member_temp_s);
304
+ $ws_plugin__s2member_temp_s = preg_replace ("/%%level%%/", "2", $ws_plugin__s2member_temp_s);
305
+ $ws_plugin__s2member_temp_s = preg_replace ("/%%level_label%%/", $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["level2_label"], $ws_plugin__s2member_temp_s);
306
+ echo '<input id="ws-plugin--s2member-modification-shortcode" type="text" value="' . format_to_edit ($ws_plugin__s2member_temp_s) . '" onclick="this.select ();" /><br /><br />' . "\n";
307
+ echo '<strong>Resulting PayPal® Button Code:</strong> ( ultimately, your Shortcode will produce this snippet )<br />' . "\n";
308
+ echo '<textarea id="ws-plugin--s2member-modification-button" rows="8" wrap="off" onclick="this.select ();">';
309
+ $ws_plugin__s2member_temp_s = trim (file_get_contents (dirname (__FILE__) . "/button.html"));
310
+ $ws_plugin__s2member_temp_s = preg_replace ("/%%endpoint%%/", (($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["paypal_sandbox"]) ? "www.sandbox.paypal.com" : "www.paypal.com"), $ws_plugin__s2member_temp_s);
311
+ $ws_plugin__s2member_temp_s = preg_replace ("/%%paypal_business%%/", $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["paypal_business"], $ws_plugin__s2member_temp_s);
312
+ $ws_plugin__s2member_temp_s = preg_replace ("/%%level_label%%/", $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["level2_label"], $ws_plugin__s2member_temp_s);
313
+ $ws_plugin__s2member_temp_s = preg_replace ("/%%cancel_return%%/", get_bloginfo ("url"), $ws_plugin__s2member_temp_s);
314
+ $ws_plugin__s2member_temp_s = preg_replace ("/%%notify_url%%/", get_bloginfo ("url") . "/?s2member_paypal_notify=1", $ws_plugin__s2member_temp_s);
315
+ $ws_plugin__s2member_temp_s = preg_replace ("/%%return%%/", get_bloginfo ("url") . "/?s2member_paypal_return=1", $ws_plugin__s2member_temp_s);
316
+ $ws_plugin__s2member_temp_s = preg_replace ("/%%domain%%/", strtolower ($_SERVER["HTTP_HOST"]), $ws_plugin__s2member_temp_s);
317
+ $ws_plugin__s2member_temp_s = preg_replace ("/%%level%%/", "2", $ws_plugin__s2member_temp_s);
318
+ echo format_to_edit ($ws_plugin__s2member_temp_s);
319
+ echo '</textarea><br />' . "\n";
320
+ echo '&uarr; Use this more advanced Code if you\'re building a theme or plugin that integrates with s2Member.' . "\n";
321
+ echo '</td>' . "\n";
322
+ /**/
323
+ echo '</tr>' . "\n";
324
+ echo '</tbody>' . "\n";
325
+ echo '</table>' . "\n";
326
+ echo '</div>' . "\n";
327
+ /**/
328
+ echo '</div>' . "\n";
329
+ /**/
330
+ echo '<div class="ws-menu-page-group" title="PayPal® Subscr Cancellation Buttons">' . "\n";
331
+ /**/
332
+ echo '<div class="ws-menu-page-section ws-plugin--s2member-cancellation-section">' . "\n";
333
+ echo '<h3>One Button Does It All For Cancellations ( copy/paste )</h3>' . "\n";
334
+ echo '<p>Since every paid Membership is associated with a PayPal® Subscription; and every PayPal® Subscription is associated with a PayPal® Account; your Members will always have a PayPal® Account of their own, which is tied to their Membership with you. So... a Member can simply log into their own PayPal® account and cancel their subscription(s) with you at anytime, all on their own. However, some Customers do not realize this. So, if you would like to make it clearer ( easier ) for Members to cancel their own subscription(s), you can provide this Cancellation Button for them on your Login Welcome Page, or somewhere in the support section of your website. Note... you don\'t have to use this Cancellation Button at all, if you don\'t want to. It\'s completely optional.</p>' . "\n";
335
+ echo '<p><em><strong>*Cancellation Process*</strong> Very simple. A Member clicks the Cancellation Button. PayPal® asks them to log into their PayPal® account. Once they\'re logged in, PayPal® will display a list of all active subscriptions they have with you. They choose which ones they want to cancel, and s2Member is notified silently behind the scenes, through the PayPal® IPN service.</em></p>' . "\n";
336
+ /**/
337
+ echo '<table class="form-table">' . "\n";
338
+ echo '<tbody>' . "\n";
339
+ echo '<tr>' . "\n";
340
+ /**/
341
+ echo '<th class="ws-menu-page-th-side">' . "\n";
342
+ echo '<label for="ws-plugin--s2member-cancellation-shortcode">' . "\n";
343
+ echo 'Button Code<br />For Cancellations:<br /><br />' . "\n";
344
+ echo '<div id="ws-plugin--s2member-cancellation-button-prev">' . "\n";
345
+ $ws_plugin__s2member_temp_s = trim (file_get_contents (dirname (__FILE__) . "/c-button.html"));
346
+ $ws_plugin__s2member_temp_s = preg_replace ("/%%endpoint%%/", (($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["paypal_sandbox"]) ? "www.sandbox.paypal.com" : "www.paypal.com"), $ws_plugin__s2member_temp_s);
347
+ $ws_plugin__s2member_temp_s = preg_replace ("/%%paypal_business%%/", $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["paypal_business"], $ws_plugin__s2member_temp_s);
348
+ echo preg_replace ("/\<a/", '<a target="_blank"', $ws_plugin__s2member_temp_s);
349
+ echo '</div>' . "\n";
350
+ echo '</label>' . "\n";
351
+ echo '</th>' . "\n";
352
+ /**/
353
+ echo '<td>' . "\n";
354
+ echo '<p>No configuration necessary.</p>' . "\n";
355
+ echo '</td>' . "\n";
356
+ /**/
357
+ echo '</tr>' . "\n";
358
+ echo '<tr>' . "\n";
359
+ /**/
360
+ echo '<td colspan="2">' . "\n";
361
+ echo '<strong>WordPress® Shortcode:</strong> ( recommended for both the WordPress® Visual &amp; HTML Editors )<br />' . "\n";
362
+ $ws_plugin__s2member_temp_s = trim (file_get_contents (dirname (__FILE__) . "/c-shortcode.html"));
363
+ echo '<input id="ws-plugin--s2member-cancellation-shortcode" type="text" value="' . format_to_edit ($ws_plugin__s2member_temp_s) . '" onclick="this.select ();" /><br /><br />' . "\n";
364
+ echo '<strong>Resulting PayPal® Button Code:</strong> ( ultimately, your Shortcode will produce this snippet )<br />' . "\n";
365
+ echo '<textarea id="ws-plugin--s2member-cancellation-button" rows="8" wrap="off" onclick="this.select ();">';
366
+ $ws_plugin__s2member_temp_s = trim (file_get_contents (dirname (__FILE__) . "/c-button.html"));
367
+ $ws_plugin__s2member_temp_s = preg_replace ("/%%endpoint%%/", (($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["paypal_sandbox"]) ? "www.sandbox.paypal.com" : "www.paypal.com"), $ws_plugin__s2member_temp_s);
368
+ $ws_plugin__s2member_temp_s = preg_replace ("/%%paypal_business%%/", $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["paypal_business"], $ws_plugin__s2member_temp_s);
369
+ echo format_to_edit ($ws_plugin__s2member_temp_s);
370
+ echo '</textarea><br />' . "\n";
371
+ echo '&uarr; Use this more advanced Code if you\'re building a theme or plugin that integrates with s2Member.' . "\n";
372
+ echo '</td>' . "\n";
373
+ /**/
374
+ echo '</tr>' . "\n";
375
+ echo '</tbody>' . "\n";
376
+ echo '</table>' . "\n";
377
+ echo '</div>' . "\n";
378
+ /**/
379
+ echo '</div>' . "\n";
380
+ /**/
381
+ echo '<div class="ws-menu-page-group" title="PayPal® Single-Page &quot;Buy Now&quot; Access">' . "\n";
382
+ /**/
383
+ echo '<div class="ws-menu-page-section ws-plugin--s2member-sp-section">' . "\n";
384
+ echo '<h3>Button Code Generator For Single-Page Buy Now Buttons</h3>' . "\n";
385
+ echo '<p>s2Member now supports an additional layer of functionality ( very powerful ), which allows you to sell access to specific Pages that you\'ve created in WordPress®. Single-Page Access works independently from Member Level Access. That is, you can sell an unlimited number of Pages using "Buy Now" Buttons, and your Customers will NOT be required to have a Membership Account with your site in order to receive access. If they are already a Member, that\'s fine, but they won\'t need to be. In other words, Customers will NOT need to login, just to receive access to the Single-Page they purchased access to. s2Member will immediately redirect the Customer to the Single-Page after checkout is completed successfully. An email is also sent to the Customer with a link ( see: <code>s2Member -> PayPal® Options -> Single-Page Email</code> ). Authentication is handled automatically through self-expiring links, good for 72 hours.</p>' . "\n";
386
+ echo '<p>Single-Page Access, is sort of like selling a product. Only, instead of shipping anything to the Customer, you just give them access to a specific Page on your site; one that you created in WordPress®. A Single-Page that is protected by s2Member, might contain a download link for your eBook, access to file &amp; music downloads, access to additional support services, and the list goes on and on. The possibilities with this are endless; as long as your digital product can be delivered through access to a WordPress® Page that you\'ve created. To protect Single-Pages, please see: <code>s2Member -> General Options -> Single-Page Access Restrictions</code>. Once you\'ve configured your Single-Page Restrictions, those Pages will be available in the drop-down menu below.</p>' . "\n";
387
+ echo '<p>Very simple. All you do is customize the form fields provided, for each Page that you plan to sell. Then press (Generate Button Code). These special PayPal® Buttons are customized to work with s2Member seamlessly.</p>' . "\n";
388
+ echo '<p><em>* Buttons are NOT saved here. This is only a Button Generator. Once you\'ve generated your Button, copy/paste it into your WordPress® Editor, wherever you feel it would be most appropriate. If you lose your Button Code, you\'ll need to come back &amp; re-generate a new one. If you\'re in Sandbox Test-Mode, and you\'re NOT using the Shortcode Format, please remember to come back and re-generate your Buttons before you go live.</em></p>' . "\n";
389
+ /**/
390
+ echo '<table class="form-table">' . "\n";
391
+ echo '<tbody>' . "\n";
392
+ echo '<tr>' . "\n";
393
+ /**/
394
+ echo '<th class="ws-menu-page-th-side">' . "\n";
395
+ echo '<label for="ws-plugin--s2member-sp-shortcode">' . "\n";
396
+ echo 'Button Code<br />Single-Page Access:<br /><br />' . "\n";
397
+ echo '<div id="ws-plugin--s2member-sp-button-prev"></div>' . "\n";
398
+ echo '</label>' . "\n";
399
+ echo '</th>' . "\n";
400
+ /**/
401
+ echo '<td>' . "\n";
402
+ echo '<p><select id="ws-plugin--s2member-sp-page">' . "\n";
403
+ echo '<option value="">&mdash; Select A Protected Single-Page &mdash;</option>' . "\n";
404
+ /**/
405
+ $ws_plugin__s2member_temp_s_pages = ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["single_pages"]) ?/**/
406
+ array_merge ((array)get_pages ("include=" . $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["single_pages"])) : array ();
407
+ /**/
408
+ foreach (($ws_plugin__s2member_temp_a = $ws_plugin__s2member_temp_s_pages) as $ws_plugin__s2member_temp_o)
409
+ if ($ws_plugin__s2member_temp_o->ID != $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["login_welcome_page"])
410
+ if ($ws_plugin__s2member_temp_o->ID != $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["membership_options_page"])
411
+ if ($ws_plugin__s2member_temp_o->ID != $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["file_download_limit_exceeded_page"])
412
+ if (!in_array ($ws_plugin__s2member_temp_o->ID, preg_split ("/,/", $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["level1_pages"])))
413
+ if (!in_array ($ws_plugin__s2member_temp_o->ID, preg_split ("/,/", $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["level2_pages"])))
414
+ if (!in_array ($ws_plugin__s2member_temp_o->ID, preg_split ("/,/", $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["level3_pages"])))
415
+ if (!in_array ($ws_plugin__s2member_temp_o->ID, preg_split ("/,/", $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["level4_pages"])))
416
+ echo '<option value="' . esc_attr ($ws_plugin__s2member_temp_o->ID) . '">' . esc_html ($ws_plugin__s2member_temp_o->post_title) . '</option>' . "\n";
417
+ /**/
418
+ echo '</select></p>' . "\n";
419
+ echo '<p>Description: <input type="text" id="ws-plugin--s2member-sp-desc" value="" size="68" /></p>' . "\n";
420
+ echo '<p>I want to charge: $<input type="text" id="ws-plugin--s2member-sp-amount" value="0.01" size="4" /> / <select id="ws-plugin--s2member-sp-term"><option value="72-H">Buy Now ( Single-Page Link, valid for 72 hours )</option></select></p>' . "\n";
421
+ echo '<p>Checkout Page Style <a href="#" onclick="alert(\'Optional. This can be configured inside your PayPal® account. PayPal® allows you to create Custom Page Styles, and assign a unique name to them. You can add your own header image and color selection to the checkout form. Once you\\\'ve created a Custom Page Style at PayPal®, you can enter that Page Style here.\'); return false;">[?]</a>: <input type="text" id="ws-plugin--s2member-sp-page-style" value="paypal" size="18" /> <select id="ws-plugin--s2member-sp-currency"><optgroup label="Currency"><option value="USD" title="U.S. Dollar">USD</option><option value="AUD" title="Australian Dollar">AUD</option><option value="BRL" title="Brazilian Real">BRL</option><option value="CAD" title="Canadian Dollar">CAD</option><option value="CZK" title="Czech Koruna">CZK</option><option value="DKK" title="Danish Krone">DKK</option><option value="EUR" title="Euro">EUR</option><option value="HKD" title="Hong Kong Dollar">HKD</option><option value="HUF" title="Hungarian Forint">HUF</option><option value="ILS" title="Israeli New Sheqel">ILS</option><option value="JPY" title="Japanese Yen">JPY</option><option value="MYR" title="Malaysian Ringgit">MYR</option><option value="MXN" title="Mexican Peso">MXN</option><option value="NOK" title="Norwegian Krone">NOK</option><option value="NZD" title="New Zealand Dollar">NZD</option><option value="PHP" title="Philippine Peso">PHP</option><option value="PLN" title="Polish Zloty">PLN</option><option value="GBP" title="Pound Sterling">GBP</option><option value="SGD" title="Singapore Dollar">SGD</option><option value="SEK" title="Swedish Krona">SEK</option><option value="CHF" title="Swiss Franc">CHF</option><option value="TWD" title="Taiwan New Dollar">TWD</option><option value="THB" title="Thai Baht">THB</option><option value="USD" title="U.S. Dollar">USD</option></optgroup></select> <input type="button" value="Generate Button Code" onclick="ws_plugin__s2member_paypalSpButtonGenerate();" class="button-primary" /></p>' . "\n";
422
+ echo '</td>' . "\n";
423
+ /**/
424
+ echo '</tr>' . "\n";
425
+ echo '<tr>' . "\n";
426
+ /**/
427
+ echo '<td colspan="2">' . "\n";
428
+ echo '<strong>WordPress® Shortcode:</strong> ( recommended for both the WordPress® Visual &amp; HTML Editors )<br />' . "\n";
429
+ $ws_plugin__s2member_temp_s = trim (file_get_contents (dirname (__FILE__) . "/sp-shortcode.html"));
430
+ $ws_plugin__s2member_temp_s = preg_replace ("/%%domain%%/", strtolower ($_SERVER["HTTP_HOST"]), $ws_plugin__s2member_temp_s);
431
+ echo '<input id="ws-plugin--s2member-sp-shortcode" type="text" value="' . format_to_edit ($ws_plugin__s2member_temp_s) . '" onclick="this.select ();" /><br /><br />' . "\n";
432
+ echo '<strong>Resulting PayPal® Button Code:</strong> ( ultimately, your Shortcode will produce this snippet )<br />' . "\n";
433
+ echo '<textarea id="ws-plugin--s2member-sp-button" rows="8" wrap="off" onclick="this.select ();">';
434
+ $ws_plugin__s2member_temp_s = trim (file_get_contents (dirname (__FILE__) . "/sp-button.html"));
435
+ $ws_plugin__s2member_temp_s = preg_replace ("/%%endpoint%%/", (($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["paypal_sandbox"]) ? "www.sandbox.paypal.com" : "www.paypal.com"), $ws_plugin__s2member_temp_s);
436
+ $ws_plugin__s2member_temp_s = preg_replace ("/%%paypal_business%%/", $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["paypal_business"], $ws_plugin__s2member_temp_s);
437
+ $ws_plugin__s2member_temp_s = preg_replace ("/%%cancel_return%%/", get_bloginfo ("url"), $ws_plugin__s2member_temp_s);
438
+ $ws_plugin__s2member_temp_s = preg_replace ("/%%notify_url%%/", get_bloginfo ("url") . "/?s2member_paypal_notify=1", $ws_plugin__s2member_temp_s);
439
+ $ws_plugin__s2member_temp_s = preg_replace ("/%%return%%/", get_bloginfo ("url") . "/?s2member_paypal_return=1", $ws_plugin__s2member_temp_s);
440
+ $ws_plugin__s2member_temp_s = preg_replace ("/%%domain%%/", strtolower ($_SERVER["HTTP_HOST"]), $ws_plugin__s2member_temp_s);
441
+ echo format_to_edit ($ws_plugin__s2member_temp_s);
442
+ echo '</textarea><br />' . "\n";
443
+ echo '&uarr; Use this more advanced Code if you\'re building a theme or plugin that integrates with s2Member.' . "\n";
444
+ echo '</td>' . "\n";
445
+ /**/
446
+ echo '</tr>' . "\n";
447
+ echo '</tbody>' . "\n";
448
+ echo '</table>' . "\n";
449
+ /**/
450
+ echo '<div class="ws-menu-page-hr"></div>' . "\n";
451
+ /**/
452
+ echo '<h3>Single-Page Link Generator ( good for 72 hours )</h3>' . "\n";
453
+ echo '<p>s2Member automatically generates Single-Page Links for your Customers after checkout, and also sends them a link in a Confirmation Email. However, if you ever need to deal with a Customer Service issue that requires a new Single-Page Link to be created, you can use this tool for that. Single-Page Links are valid for 72 hours.</p>' . "\n";
454
+ /**/
455
+ echo '<table class="form-table">' . "\n";
456
+ echo '<tbody>' . "\n";
457
+ echo '<tr>' . "\n";
458
+ /**/
459
+ echo '<td>' . "\n";
460
+ echo '<p><select id="ws-plugin--s2member-sp-link-page">' . "\n";
461
+ echo '<option value="">&mdash; Select A Protected Single-Page &mdash;</option>' . "\n";
462
+ /**/
463
+ foreach (($ws_plugin__s2member_temp_a = $ws_plugin__s2member_temp_s_pages) as $ws_plugin__s2member_temp_o)
464
+ if ($ws_plugin__s2member_temp_o->ID != $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["login_welcome_page"])
465
+ if ($ws_plugin__s2member_temp_o->ID != $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["membership_options_page"])
466
+ if ($ws_plugin__s2member_temp_o->ID != $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["file_download_limit_exceeded_page"])
467
+ if (!in_array ($ws_plugin__s2member_temp_o->ID, preg_split ("/,/", $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["level1_pages"])))
468
+ if (!in_array ($ws_plugin__s2member_temp_o->ID, preg_split ("/,/", $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["level2_pages"])))
469
+ if (!in_array ($ws_plugin__s2member_temp_o->ID, preg_split ("/,/", $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["level3_pages"])))
470
+ if (!in_array ($ws_plugin__s2member_temp_o->ID, preg_split ("/,/", $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["level4_pages"])))
471
+ echo '<option value="' . esc_attr ($ws_plugin__s2member_temp_o->ID) . '">' . esc_html ($ws_plugin__s2member_temp_o->post_title) . '</option>' . "\n";
472
+ /**/
473
+ echo '</select> <input type="button" value="Generate Link" onclick="ws_plugin__s2member_paypalSpLinkGenerate();" class="button-primary" /> <img id="ws-plugin--s2member-sp-link-loading" src="' . $GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["dir_url"] . '/images/ajax-loader.gif" alt="" style="display:none;" /></p>' . "\n";
474
+ /**/
475
+ echo '<p id="ws-plugin--s2member-sp-link" style="font-family:Consolas, monospace; display:none;"></p>' . "\n";
476
+ echo '</td>' . "\n";
477
+ /**/
478
+ echo '</tr>' . "\n";
479
+ echo '</tbody>' . "\n";
480
+ echo '</table>' . "\n";
481
+ echo '</div>' . "\n";
482
+ /**/
483
+ echo '</div>' . "\n";
484
+ /**/
485
  echo '</form>' . "\n";
486
  }
487
  else /* They need to first configure the options. */
488
+ echo '<p>Please configure the s2Member PayPal® Options first. Once your PayPal® Options have been properly configured, return to this page &amp; generate your PayPal® Button(s).</p>' . "\n";
489
  /**/
490
  echo '</td>' . "\n";
491
  /**/
492
  echo '<td class="ws-menu-page-table-r">' . "\n";
493
  /**/
494
+ echo ($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["menu-r"]["installation"]) ? '<div class="ws-menu-page-installation"><a href="' . ws_plugin__s2member_parse_readme_value ("Professional Installation URI") . '"><img src="' . $GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["dir_url"] . '/images/brand-installation.png" alt="." title="Contact PriMoThemes!" /></a></div>' . "\n" : '';
495
+ /**/
496
  echo ($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["menu-r"]["tools"]) ? '<div class="ws-menu-page-tools"><img src="' . $GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["dir_url"] . '/images/brand-tools.png" alt="." /></div>' . "\n" : '';
497
  /**/
498
  echo ($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["menu-r"]["tips"]) ? '<div class="ws-menu-page-tips"><a href="' . ws_plugin__s2member_parse_readme_value ("Customization URI") . '"><img src="' . $GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["dir_url"] . '/images/brand-tips.png" alt="." /></a></div>' . "\n" : '';
includes/menu-pages/c-button.html ADDED
@@ -0,0 +1,3 @@
 
 
 
1
+ <a href="https://%%endpoint%%/cgi-bin/webscr?cmd=_subscr-find&amp;alias=%%paypal_business%%" style="outline:none;">
2
+ <img alt="PayPal®" style="border:0;" src="https://www.paypal.com/en_US/i/btn/btn_unsubscribe_LG.gif" />
3
+ </a>
includes/menu-pages/c-shortcode.html ADDED
@@ -0,0 +1 @@
 
1
+ [s2Member-PayPal-Button cb="1" /]
includes/menu-pages/{con-samps/current_user_access_label.php → code-samples/current-user-access-label.php} RENAMED
File without changes
includes/menu-pages/code-samples/current-user-access-level-conditional-upgrades.php ADDED
@@ -0,0 +1,11 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php if (S2MEMBER_CURRENT_USER_ACCESS_LEVEL === 4){ ?>
2
+ Member is already at the highest Level. No Modification Button displayed here.
3
+ <?php } else if (S2MEMBER_CURRENT_USER_ACCESS_LEVEL === 3){ ?>
4
+ Insert Modification Button here. Upgrade Level 3 Members to highest Level 4.
5
+ <?php } else if (S2MEMBER_CURRENT_USER_ACCESS_LEVEL === 2){ ?>
6
+ Insert Modification Button here. Upgrade Level 2 Members to Level 3 or higher.
7
+ <?php } else if (S2MEMBER_CURRENT_USER_ACCESS_LEVEL === 1){ ?>
8
+ Insert Modification Button here. Upgrade Level 1 Members to Level 2 or higher.
9
+ <?php } else if(S2MEMBER_CURRENT_USER_ACCESS_LEVEL === 0){ ?>
10
+ Insert Modification Button here. Let Free Subscribers become a Member.
11
+ <?php } ?>
includes/menu-pages/{con-samps/current_user_access_level.php → code-samples/current-user-access-level.php} RENAMED
@@ -1,13 +1,13 @@
1
  <?php if (S2MEMBER_CURRENT_USER_ACCESS_LEVEL === 4){ ?>
2
- Member has an access level of 4.
3
  <?php } else if (S2MEMBER_CURRENT_USER_ACCESS_LEVEL === 3){ ?>
4
- Member has an access level of 3.
5
  <?php } else if (S2MEMBER_CURRENT_USER_ACCESS_LEVEL === 2){ ?>
6
- Member has an access level of 2.
7
  <?php } else if (S2MEMBER_CURRENT_USER_ACCESS_LEVEL === 1){ ?>
8
- Member has an access level of 1.
9
  <?php } else if(S2MEMBER_CURRENT_USER_ACCESS_LEVEL === 0){ ?>
10
- User is logged in but is not a member.
11
  <?php } else if(S2MEMBER_CURRENT_USER_ACCESS_LEVEL === -1){ ?>
12
- User is not logged in.
13
  <?php } ?>
1
  <?php if (S2MEMBER_CURRENT_USER_ACCESS_LEVEL === 4){ ?>
2
+ A Member has an Access Level of 4.
3
  <?php } else if (S2MEMBER_CURRENT_USER_ACCESS_LEVEL === 3){ ?>
4
+ A Member has an Access Level of 3.
5
  <?php } else if (S2MEMBER_CURRENT_USER_ACCESS_LEVEL === 2){ ?>
6
+ A Member has an Access Level of 2.
7
  <?php } else if (S2MEMBER_CURRENT_USER_ACCESS_LEVEL === 1){ ?>
8
+ A Member has an Access Level of 1.
9
  <?php } else if(S2MEMBER_CURRENT_USER_ACCESS_LEVEL === 0){ ?>
10
+ A User is logged in as a Free Subscriber.
11
  <?php } else if(S2MEMBER_CURRENT_USER_ACCESS_LEVEL === -1){ ?>
12
+ A User is not logged in at all.
13
  <?php } ?>
includes/menu-pages/code-samples/current-user-can-ccaps-1.php ADDED
@@ -0,0 +1,15 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php if (is_user_logged_in() && current_user_can("access_s2member_level1")){ ?>
2
+
3
+ Some premium content for all Level 1 Members.
4
+
5
+ <?php if (current_user_can("access_s2member_ccap_music")){ ?>
6
+ Display links for music as well.
7
+ <?php } ?>
8
+
9
+ <?php if (current_user_can("access_s2member_ccap_videos")){ ?>
10
+ Display videos as well.
11
+ <?php } ?>
12
+
13
+ <?php } else { ?>
14
+ Some public content.
15
+ <?php } ?>
includes/menu-pages/code-samples/current-user-can-ccaps-2.php ADDED
@@ -0,0 +1,28 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php if (is_user_logged_in() && current_user_can("access_s2member_level1")){ ?>
2
+
3
+ Some premium content for all Level 1 Members.
4
+
5
+ <?php if (current_user_can("access_s2member_ccap_ebooks")){ ?>
6
+ Display links for downloading your eBooks.
7
+ <?php } else { ?>
8
+ Insert a PayPal® Modification Button that includes the Custom Capability: ebooks
9
+ This might read, "Upgrade Your Membership for access to my eBooks!".
10
+ <? } ?>
11
+
12
+ <?php if (current_user_can("access_s2member_ccap_reports")){ ?>
13
+ Display links for accessing your reports.
14
+ <?php } else { ?>
15
+ Insert a PayPal® Modification Button that includes the Custom Capability: reports
16
+ This might read, "Upgrade Your Membership for access to my reports!".
17
+ <? } ?>
18
+
19
+ <?php if (current_user_can("access_s2member_ccap_tips")){ ?>
20
+ Display tips.
21
+ <?php } else { ?>
22
+ Insert a PayPal® Modification Button that includes the Custom Capability: tips
23
+ This might read, "Upgrade Your Membership for access to my tips!".
24
+ <? } ?>
25
+
26
+ <?php } else { ?>
27
+ Some public content.
28
+ <?php } ?>
includes/menu-pages/code-samples/current-user-can-constants-1.php ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
1
+ <?php if (S2MEMBER_CURRENT_USER_IS_LOGGED_IN_AS_MEMBER){ ?>
2
+ Content for Members with an s2Member Level >= 1.
3
+ <?php } else if(S2MEMBER_CURRENT_USER_IS_LOGGED_IN) { ?>
4
+ Some content for Free Subscribers.
5
+ <?php } else { ?>
6
+ Some public content.
7
+ <?php } ?>
includes/menu-pages/code-samples/current-user-can-constants-2.php ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php if (S2MEMBER_CURRENT_USER_ACCESS_LEVEL >= 4){ ?>
2
+ Some content for Members with an s2Member Level >= 4.
3
+ <?php if (S2MEMBER_CURRENT_USER_ACCESS_LEVEL >= 3){ ?>
4
+ Some content for Members with an s2Member Level >= 3.
5
+ <?php } else if (S2MEMBER_CURRENT_USER_ACCESS_LEVEL >= 2){ ?>
6
+ Some content for Members with an s2Member Level >= 2.
7
+ <?php } else if (S2MEMBER_CURRENT_USER_ACCESS_LEVEL >= 1){ ?>
8
+ Some content for Members with an s2Member Level >= 1.
9
+ <?php } else if(S2MEMBER_CURRENT_USER_ACCESS_LEVEL === 0){ ?>
10
+ Some content for Free Subscribers.
11
+ <?php } else if(S2MEMBER_CURRENT_USER_ACCESS_LEVEL === -1){ ?>
12
+ Some public content.
13
+ <?php } ?>
includes/menu-pages/code-samples/current-user-can-full-access.php ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
1
+ <?php if (is_user_logged_in() && current_user_can("access_s2member_level1")){ ?>
2
+ Some content for Members who are logged in with an s2Member Level >= 1.
3
+ <?php } else { ?>
4
+ Some public content.
5
+ <?php } ?>
includes/menu-pages/code-samples/current-user-can-specific-content.php ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php if (is_user_logged_in() && current_user_can("access_s2member_level4")){ ?>
2
+ Some premium content for Level 4 Members.
3
+ <?php } else if (is_user_logged_in() && current_user_can("access_s2member_level3")){ ?>
4
+ Some premium content for Level 3 Members.
5
+ <?php } else if (is_user_logged_in() && current_user_can("access_s2member_level2")){ ?>
6
+ Some premium content for Level 2 Members.
7
+ <?php } else if (is_user_logged_in() && current_user_can("access_s2member_level1")){ ?>
8
+ Some premium content for Level 1 Members.
9
+ <?php } else if (is_user_logged_in()){ ?>
10
+ Some content for Free Subscribers.
11
+ <?php } else { ?>
12
+ Some public content.
13
+ <?php } ?>
includes/menu-pages/{con-samps/current_user_custom.php → code-samples/current-user-custom.php} RENAMED
File without changes
includes/menu-pages/{con-samps/current_user_display_name.php → code-samples/current-user-display-name.php} RENAMED
File without changes
includes/menu-pages/{con-samps/current_user_downloads_allowed_days.php → code-samples/current-user-downloads-allowed-days.php} RENAMED
File without changes
includes/menu-pages/{con-samps/current_user_downloads_allowed_is_unlimited.php → code-samples/current-user-downloads-allowed-is-unlimited.php} RENAMED
File without changes
includes/menu-pages/{con-samps/current_user_downloads_allowed.php → code-samples/current-user-downloads-allowed.php} RENAMED
File without changes
includes/menu-pages/{con-samps/current_user_downloads_currently.php → code-samples/current-user-downloads-currently.php} RENAMED
File without changes
includes/menu-pages/{con-samps/current_user_email.php → code-samples/current-user-email.php} RENAMED
File without changes
includes/menu-pages/code-samples/current-user-fields.php ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
1
+ <?php $fields = json_decode(S2MEMBER_CURRENT_USER_FIELDS, true); ?>
2
+ <?php echo $fields["first_name"]; ?> <?php echo $fields["last_name"]; ?>
3
+ This would output the first and last name for the current user.
4
+
5
+ Custom Fields are also included in the JSON decoded array.
6
+ <?php print_r(json_decode(S2MEMBER_CURRENT_USER_FIELDS, true)); ?>
7
+ ( Displays a full list of all associative array elements. )
includes/menu-pages/{con-samps/current_user_first_name.php → code-samples/current-user-first-name.php} RENAMED
File without changes
includes/menu-pages/{con-samps/current_user_id.php → code-samples/current-user-id.php} RENAMED
File without changes
includes/menu-pages/{con-samps/current_user_ip.php → code-samples/current-user-ip.php} RENAMED
File without changes
includes/menu-pages/code-samples/current-user-is-logged-in-as-member.php ADDED
@@ -0,0 +1,3 @@
 
 
 
1
+ <?php if (S2MEMBER_CURRENT_USER_IS_LOGGED_IN_AS_MEMBER){ ?>
2
+ A Member is logged in, with an Access Level >= 1.
3
+ <?php } ?>
includes/menu-pages/code-samples/current-user-is-logged-in.php ADDED
@@ -0,0 +1,3 @@
 
 
 
1
+ <?php if (S2MEMBER_CURRENT_USER_IS_LOGGED_IN){ ?>
2
+ A User/Member is logged in, with an Access Level >= 0.
3
+ <?php } ?>
includes/menu-pages/{con-samps/current_user_last_name.php → code-samples/current-user-last-name.php} RENAMED
File without changes
includes/menu-pages/{con-samps/current_user_login.php → code-samples/current-user-login.php} RENAMED
File without changes
includes/menu-pages/code-samples/current-user-profile-modification-page-url-1.php ADDED
@@ -0,0 +1 @@
 
1
+ <a href="<?php echo S2MEMBER_CURRENT_USER_PROFILE_MODIFICATION_PAGE_URL; ?>">Modify Profile</a>
includes/menu-pages/code-samples/current-user-profile-modification-page-url-2.php ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
1
+ <a href="#" onclick="if(!window.open('<?php echo S2MEMBER_CURRENT_USER_PROFILE_MODIFICATION_PAGE_URL; ?>',
2
+ '_popup', 'height=350,width=400,left=100,screenX=100,top=100,screenY=100,
3
+ location=0,menubar=0,toolbar=0,status=0,scrollbars=1,resizable=1'))
4
+ alert('Please disable popup blockers and try again!');
5
+ return false;">Modify Profile</a>
includes/menu-pages/code-samples/current-user-profile-modification-page-url-3.php ADDED
@@ -0,0 +1 @@
 
1
+ <iframe src="<?php echo S2MEMBER_CURRENT_USER_PROFILE_MODIFICATION_PAGE_URL; ?>" scrolling="auto" style="width:100%; height:325px; border:1px solid #666666;"></iframe>
includes/menu-pages/code-samples/current-user-registration-days-dripping.php ADDED
@@ -0,0 +1,17 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php if(S2MEMBER_CURRENT_USER_IS_LOGGED_IN_AS_MEMBER){ ?>
2
+
3
+ This is some content that will be displayed to all Members.
4
+
5
+ <?php if(S2MEMBER_CURRENT_USER_REGISTRATION_DAYS >= 30){ ?>
6
+ Drip content to Members who are more than 30 days old.
7
+ <?php } ?>
8
+
9
+ <?php if(S2MEMBER_CURRENT_USER_REGISTRATION_DAYS >= 60){ ?>
10
+ Drip content to Members who are more than 60 days old.
11
+ <?php } ?>
12
+
13
+ <?php if(S2MEMBER_CURRENT_USER_REGISTRATION_DAYS >= 90){ ?>
14
+ Drip content to Members who are more than 90 days old.
15
+ <?php } ?>
16
+
17
+ <?php } ?>
includes/menu-pages/code-samples/current-user-registration-days.php ADDED
@@ -0,0 +1,22 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php echo S2MEMBER_CURRENT_USER_REGISTRATION_DAYS; ?>
2
+ This may output something like: 120 ( 120 days is approx 4 months )
3
+
4
+ Here's how you Drip Content. The longer they've been a Member, the more they get.
5
+
6
+ <?php if(S2MEMBER_CURRENT_USER_IS_LOGGED_IN_AS_MEMBER){ ?>
7
+
8
+ This is some content that will be displayed to all Members.
9
+
10
+ <?php if(S2MEMBER_CURRENT_USER_REGISTRATION_DAYS >= 30){ ?>
11
+ Drip content to Members who are more than 30 days old.
12
+ <?php } ?>
13
+
14
+ <?php if(S2MEMBER_CURRENT_USER_REGISTRATION_DAYS >= 60){ ?>
15
+ Drip content to Members who are more than 60 days old.
16
+ <?php } ?>
17
+
18
+ <?php if(S2MEMBER_CURRENT_USER_REGISTRATION_DAYS >= 90){ ?>
19
+ Drip content to Members who are more than 90 days old.
20
+ <?php } ?>
21
+
22
+ <?php } ?>
includes/menu-pages/{con-samps/current_user_registration_time.php → code-samples/current-user-registration-time.php} RENAMED
File without changes
includes/menu-pages/{con-samps/current_user_subscr_id.php → code-samples/current-user-subscr-id.php} RENAMED
File without changes
includes/menu-pages/code-samples/current-user-value-for-pp-on0-os0.php ADDED
@@ -0,0 +1,4 @@
 
 
 
 
1
+ <!-- Identifies/Updates An Existing Member After Checkout -->
2
+ <input type="hidden" name="on0" value="<?php echo S2MEMBER_CURRENT_USER_VALUE_FOR_PP_ON0; ?>" />
3
+ <input type="hidden" name="os0" value="<?php echo S2MEMBER_CURRENT_USER_VALUE_FOR_PP_OS0; ?>" />
4
+ <input type="hidden" name="modify" value="1" />
includes/menu-pages/{con-samps/file_download_limit_exceeded_page_url.php → code-samples/file-download-limit-exceeded-page-url.php} RENAMED
File without changes
includes/menu-pages/code-samples/index.php ADDED
File without changes
includes/menu-pages/code-samples/is-user-logged-in.php ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
1
+ <?php if(is_user_logged_in()){ ?>
2
+ Content for anyone that is logged in, regardless of their Membership Level.
3
+ <?php } else { ?>
4
+ Some public content.
5
+ <?php } ?>
includes/menu-pages/{con-samps/level1_file_downloads_allowed.php → code-samples/level1-file-downloads-allowed-days.php} RENAMED
File without changes
includes/menu-pages/{con-samps/level1_file_downloads_allowed_days.php → code-samples/level1-file-downloads-allowed.php} RENAMED
File without changes
includes/menu-pages/{con-samps/level1_label.php → code-samples/level1-label.php} RENAMED
File without changes
includes/menu-pages/{con-samps/level2_file_downloads_allowed.php → code-samples/level2-file-downloads-allowed-days.php} RENAMED
File without changes
includes/menu-pages/{con-samps/level2_file_downloads_allowed_days.php → code-samples/level2-file-downloads-allowed.php} RENAMED
File without changes
includes/menu-pages/{con-samps/level2_label.php → code-samples/level2-label.php} RENAMED
File without changes
includes/menu-pages/{con-samps/level3_file_downloads_allowed.php → code-samples/level3-file-downloads-allowed-days.php} RENAMED
File without changes
includes/menu-pages/{con-samps/level3_file_downloads_allowed_days.php → code-samples/level3-file-downloads-allowed.php} RENAMED
File without changes
includes/menu-pages/{con-samps/level3_label.php → code-samples/level3-label.php} RENAMED
File without changes
includes/menu-pages/{con-samps/level4_file_downloads_allowed.php → code-samples/level4-file-downloads-allowed-days.php} RENAMED
File without changes
includes/menu-pages/{con-samps/level4_file_downloads_allowed_days.php → code-samples/level4-file-downloads-allowed.php} RENAMED
File without changes
includes/menu-pages/{con-samps/level4_label.php → code-samples/level4-label.php} RENAMED
File without changes
includes/menu-pages/{con-samps/login_page_url.php → code-samples/login-page-url.php} RENAMED
File without changes
includes/menu-pages/{con-samps/login_welcome_page_url.php → code-samples/login-welcome-page-url.php} RENAMED
File without changes
includes/menu-pages/{con-samps/logout_page_url.php → code-samples/logout-page-url.php} RENAMED
File without changes
includes/menu-pages/{con-samps/membership_options_page_url.php → code-samples/membership-options-page-url.php} RENAMED
File without changes
includes/menu-pages/{con-samps/paypal_business.php → code-samples/paypal-business.php} RENAMED
File without changes
includes/menu-pages/{con-samps/paypal_endpoint.php → code-samples/paypal-endpoint.php} RENAMED
File without changes
includes/menu-pages/{con-samps/paypal_notify_url.php → code-samples/paypal-notify-url.php} RENAMED
File without changes
includes/menu-pages/{con-samps/paypal_return_url.php → code-samples/paypal-return-url.php} RENAMED
File without changes
includes/menu-pages/{con-samps/reg_email_from_email.php → code-samples/reg-email-from-email.php} RENAMED
File without changes
includes/menu-pages/{con-samps/reg_email_from_name.php → code-samples/reg-email-from-name.php} RENAMED
File without changes
includes/menu-pages/con-samps/current_user_fields.php DELETED
@@ -1,7 +0,0 @@
1
- <?php $fields = unserialize(S2MEMBER_CURRENT_USER_FIELDS); ?>
2
- <?php echo $fields["first_name"]; ?> <?php echo $fields["last_name"]; ?>
3
- This would output the first and last name for the current user.
4
-
5
- Custom Fields are also included in the unserialized array.
6
- <?php print_r(unserialize(S2MEMBER_CURRENT_USER_FIELDS)); ?>
7
- ( Displays a full list of all array elements. )
 
 
 
 
 
 
 
includes/menu-pages/con-samps/current_user_is_logged_in.php DELETED
@@ -1,3 +0,0 @@
1
- <?php if (S2MEMBER_CURRENT_USER_IS_LOGGED_IN){ ?>
2
- The user is logged in.
3
- <?php } ?>
 
 
 
includes/menu-pages/con-samps/current_user_profile_modification_page_url.php DELETED
@@ -1,8 +0,0 @@
1
- <a href="#" onclick="if(!window.open('<?php echo S2MEMBER_CURRENT_USER_PROFILE_MODIFICATION_PAGE_URL; ?>',
2
- '_popup', 'height=350,width=400,left=100,screenX=100,top=100,screenY=100,
3
- location=0,menubar=0,toolbar=0,status=0,scrollbars=1,resizable=1'))
4
- alert('Please disable popup blockers and try again!');
5
- return false;">Modify Profile</a>
6
-
7
- This could also be embedded into a Post/Page using an IFRAME tag. So if you don't like using pop-ups, try this:
8
- <iframe src="<?php echo S2MEMBER_CURRENT_USER_PROFILE_MODIFICATION_PAGE_URL; ?>" scrolling="auto" style="width:100%; height:325px; border:1px solid #666666;"></iframe>
 
 
 
 
 
 
 
 
includes/menu-pages/con-samps/current_user_registration_days.php DELETED
@@ -1,15 +0,0 @@
1
- <?php echo S2MEMBER_CURRENT_USER_REGISTRATION_DAYS; ?>
2
- This may output something like: 120
3
- ( 120 days means they've been a Member for approx 4 months )
4
-
5
- Here is a more practical example:
6
-
7
- <?php if(S2MEMBER_CURRENT_USER_REGISTRATION_DAYS >= 90){ ?>
8
- Drip content to Members who are more than 90 days old.
9
- <?php } else if(S2MEMBER_CURRENT_USER_REGISTRATION_DAYS >= 60){ ?>
10
- Drip content to Members who are more than 60 days old.
11
- <?php } else if(S2MEMBER_CURRENT_USER_REGISTRATION_DAYS >= 30){ ?>
12
- Drip content to Members who are more than 30 days old.
13
- <?php } else { ?>
14
- Initial content for newer Members.
15
- <?php } ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
includes/menu-pages/cur-samps.php DELETED
@@ -1,33 +0,0 @@
1
- Example #1, Allow all levels greater than or equal to 1 full access.
2
-
3
- <?php if (current_user_can("access_s2member_level1")){ ?>
4
- Show premium members-only content to all members.
5
- <?php } else { ?>
6
- Show non-member public content.
7
- <?php } ?>
8
-
9
- Example #2, Specific content for each member level.
10
-
11
- <?php if (current_user_can("access_s2member_level4")){ ?>
12
- Show level 4 member content.
13
- <?php } else if (current_user_can("access_s2member_level3")){ ?>
14
- Show level 3 member content.
15
- <?php } else if (current_user_can("access_s2member_level2")){ ?>
16
- Show level 2 member content.
17
- <?php } else if (current_user_can("access_s2member_level1")){ ?>
18
- Show level 1 member content.
19
- <?php } else { ?>
20
- Show non-member content.
21
- <?php } ?>
22
-
23
- * Tip ( levels allow incremental access to areas of your site ).
24
- - A user with level 4 access will also be able to access levels 1, 2 & 3.
25
- - A user with level 3 access will also be able to access levels 1 & 2.
26
- - A user with level 2 access will also be able to access level 1.
27
- - A user with level 1 access will only be able to access level 1.
28
-
29
- * WordPress® Administrators, Editors, Authors, and Contributors have level 4 access.
30
-
31
- * WordPress® Subscribers are not allowed membership access. They must be promoted to a member.
32
- However, if you set `Allow Free Subscribers` to `Yes`, then Free Subscribers WILL be able to access
33
- your Login Welcome Page, but that is all. See `s2Member->General Options->Login Welcome Page`.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
includes/menu-pages/down-ops.inc.php CHANGED
@@ -47,8 +47,8 @@ echo '<p>- If needed, you can make certain files available free, using an extra
47
  echo '<div class="ws-menu-page-hr"></div>' . "\n";
48
  /**/
49
  echo '<p>s2Member will allow access to these protected files, based on the configuration you specify below. <em>* Note: repeated downloads of the same exact file are NOT tabulated against the totals below. Once a file has been downloaded, future downloads of the same exact file, by the same exact Member will not be counted against them. In other words, if a Member downloads the same file three times, the system only counts that as one unique download.</em></p>' . "\n";
50
- echo '<p>s2Member will automatically detect links, anywhere in your content, and/or anywhere in your theme files, that contain <code>?s2member_file_download</code>. Whenever a logged-in Member clicks a link that contains <code>?s2member_file_download</code>, the system will politely ask the user to confirm the download using a very intuitive JavaScript confirmation prompt that contains specific details about download limitations. This way your Members will be aware of how many files they\'ve downloaded in the current period; and they\'ll be able to make a consious decision about whether to proceed with a specific download or not.</p>' . "\n";
51
- echo '<p><em>* The above only applies to users who are logged in as members. For all other users in the general public, the <code>?s2member_file_download</code> links will redirect them your Membership Options Page, so that new users can signup, in order to gain access.</em></p>' . "\n";
52
  /**/
53
  echo '<div class="ws-menu-page-hr"></div>' . "\n";
54
  /**/
@@ -132,7 +132,7 @@ echo '<div class="ws-menu-page-group" title="Download Limit Exceeded">' . "\n";
132
  /**/
133
  echo '<div class="ws-menu-page-section ws-plugin--s2member-limit-exceeded-section">' . "\n";
134
  echo '<h3>Download Limit Exceeded Page ( required, if providing access to protected files )</h3>' . "\n";
135
- echo '<p>This Page will be shown if a user reaches their download limit, based on the configuration you\'ve specified in the fields above. This Page should be created by you, in WordPress®. This Page should provide an informative message to the User, describing your file access restrictions. Just tell them a little bit about your policy on file downloads, and why they might have reached this Page.</p>' . "\n";
136
  /**/
137
  echo '<table class="form-table">' . "\n";
138
  echo '<tbody>' . "\n";
@@ -148,12 +148,12 @@ echo '</tr>' . "\n";
148
  echo '<tr>' . "\n";
149
  /**/
150
  echo '<td>' . "\n";
151
- echo '<option value="">&mdash; Select &mdash;</option>' . "\n";
152
  echo '<select name="ws_plugin__s2member_file_download_limit_exceeded_page" id="ws-plugin--s2member-file-download-limit-exceeded-page">' . "\n";
 
153
  foreach (($ws_plugin__s2member_temp_a = array_merge ((array)get_pages ())) as $ws_plugin__s2member_temp_o)
154
  echo '<option value="' . esc_attr ($ws_plugin__s2member_temp_o->ID) . '"' . (($ws_plugin__s2member_temp_o->ID == $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["file_download_limit_exceeded_page"]) ? ' selected="selected"' : '') . '>' . esc_html ($ws_plugin__s2member_temp_o->post_title) . '</option>' . "\n";
155
  echo '</select><br />' . "\n";
156
- echo 'Please choose a Page that Users will see if they reach their file download limit. This Page should provide an informative message to the User, describing your file access restrictions. Just tell them a little bit about your policy on file downloads. We recommend the following title: <code>Download Limit Exceeded</code>.' . "\n";
157
  echo '</td>' . "\n";
158
  /**/
159
  echo '</tr>' . "\n";
@@ -173,6 +173,8 @@ echo '</td>' . "\n";
173
  /**/
174
  echo '<td class="ws-menu-page-table-r">' . "\n";
175
  /**/
 
 
176
  echo ($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["menu-r"]["tools"]) ? '<div class="ws-menu-page-tools"><img src="' . $GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["dir_url"] . '/images/brand-tools.png" alt="." /></div>' . "\n" : '';
177
  /**/
178
  echo ($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["menu-r"]["tips"]) ? '<div class="ws-menu-page-tips"><a href="' . ws_plugin__s2member_parse_readme_value ("Customization URI") . '"><img src="' . $GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["dir_url"] . '/images/brand-tips.png" alt="." /></a></div>' . "\n" : '';
47
  echo '<div class="ws-menu-page-hr"></div>' . "\n";
48
  /**/
49
  echo '<p>s2Member will allow access to these protected files, based on the configuration you specify below. <em>* Note: repeated downloads of the same exact file are NOT tabulated against the totals below. Once a file has been downloaded, future downloads of the same exact file, by the same exact Member will not be counted against them. In other words, if a Member downloads the same file three times, the system only counts that as one unique download.</em></p>' . "\n";
50
+ echo '<p>s2Member will automatically detect links, anywhere in your content, and/or anywhere in your theme files, that contain <code>?s2member_file_download</code>. Whenever a logged-in Member clicks a link that contains <code>?s2member_file_download</code>, the system will politely ask the user to confirm the download using a very intuitive JavaScript confirmation prompt that contains specific details about download limitations. This way your Members will be aware of how many files they\'ve downloaded in the current period; and they\'ll be able to make a conscious decision about whether to proceed with a specific download or not.</p>' . "\n";
51
+ echo '<p><em>* The above only applies to users who are logged in as Members. For all other users in the general public, the <code>?s2member_file_download</code> links will redirect them your Membership Options Page, so that new users can signup, in order to gain access, by becoming a Member.</em></p>' . "\n";
52
  /**/
53
  echo '<div class="ws-menu-page-hr"></div>' . "\n";
54
  /**/
132
  /**/
133
  echo '<div class="ws-menu-page-section ws-plugin--s2member-limit-exceeded-section">' . "\n";
134
  echo '<h3>Download Limit Exceeded Page ( required, if providing access to protected files )</h3>' . "\n";
135
+ echo '<p>This Page will be shown if a Member reaches their download limit, based on the configuration you\'ve specified in the fields above. This Page should be created by you, in WordPress®. This Page should provide an informative message to the Member, describing your file access restrictions. Just tell them a little bit about your policy on file downloads, and why they might have reached this Page.</p>' . "\n";
136
  /**/
137
  echo '<table class="form-table">' . "\n";
138
  echo '<tbody>' . "\n";
148
  echo '<tr>' . "\n";
149
  /**/
150
  echo '<td>' . "\n";
 
151
  echo '<select name="ws_plugin__s2member_file_download_limit_exceeded_page" id="ws-plugin--s2member-file-download-limit-exceeded-page">' . "\n";
152
+ echo '<option value="">&mdash; Select &mdash;</option>' . "\n";
153
  foreach (($ws_plugin__s2member_temp_a = array_merge ((array)get_pages ())) as $ws_plugin__s2member_temp_o)
154
  echo '<option value="' . esc_attr ($ws_plugin__s2member_temp_o->ID) . '"' . (($ws_plugin__s2member_temp_o->ID == $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["file_download_limit_exceeded_page"]) ? ' selected="selected"' : '') . '>' . esc_html ($ws_plugin__s2member_temp_o->post_title) . '</option>' . "\n";
155
  echo '</select><br />' . "\n";
156
+ echo 'Please choose a Page that Members will see if they reach their file download limit. This Page should provide an informative message to the Member, describing your file access restrictions. Just tell them a little bit about your policy on file downloads. We recommend the following title: <code>Download Limit Exceeded</code>.' . "\n";
157
  echo '</td>' . "\n";
158
  /**/
159
  echo '</tr>' . "\n";
173
  /**/
174
  echo '<td class="ws-menu-page-table-r">' . "\n";
175
  /**/
176
+ echo ($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["menu-r"]["installation"]) ? '<div class="ws-menu-page-installation"><a href="' . ws_plugin__s2member_parse_readme_value ("Professional Installation URI") . '"><img src="' . $GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["dir_url"] . '/images/brand-installation.png" alt="." title="Contact PriMoThemes!" /></a></div>' . "\n" : '';
177
+ /**/
178
  echo ($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["menu-r"]["tools"]) ? '<div class="ws-menu-page-tools"><img src="' . $GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["dir_url"] . '/images/brand-tools.png" alt="." /></div>' . "\n" : '';
179
  /**/
180
  echo ($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["menu-r"]["tips"]) ? '<div class="ws-menu-page-tips"><a href="' . ws_plugin__s2member_parse_readme_value ("Customization URI") . '"><img src="' . $GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["dir_url"] . '/images/brand-tips.png" alt="." /></a></div>' . "\n" : '';
includes/menu-pages/drip-samps.php DELETED
@@ -1,9 +0,0 @@
1
- <?php if(S2MEMBER_CURRENT_USER_REGISTRATION_DAYS >= 90){ ?>
2
- Drip content to Members who are more than 90 days old.
3
- <?php } else if(S2MEMBER_CURRENT_USER_REGISTRATION_DAYS >= 60){ ?>
4
- Drip content to Members who are more than 60 days old.
5
- <?php } else if(S2MEMBER_CURRENT_USER_REGISTRATION_DAYS >= 30){ ?>
6
- Drip content to Members who are more than 30 days old.
7
- <?php } else { ?>
8
- Initial content for newer Members.
9
- <?php } ?>
 
 
 
 
 
 
 
 
 
includes/menu-pages/els-ops.inc.php ADDED
@@ -0,0 +1,291 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /*
3
+ Copyright: © 2009 WebSharks, Inc. ( coded in the USA )
4
+ <mailto:support@websharks-inc.com> <http://www.websharks-inc.com/>
5
+
6
+ Released under the terms of the GNU General Public License.
7
+ You should have received a copy of the GNU General Public License,
8
+ along with this software. In the main directory, see: /licensing/
9
+ If not, see: <http://www.gnu.org/licenses/>.
10
+ */
11
+ /*
12
+ Direct access denial.
13
+ */
14
+ if (realpath (__FILE__) === realpath ($_SERVER["SCRIPT_FILENAME"]))
15
+ exit;
16
+ /*
17
+ PayPal® Options page.
18
+ */
19
+ echo '<div class="wrap ws-menu-page">' . "\n";
20
+ /**/
21
+ echo '<div id="icon-plugins" class="icon32"><br /></div>' . "\n";
22
+ echo '<h2><div>Developed by <a href="' . ws_plugin__s2member_parse_readme_value ("Plugin URI") . '"><img src="' . $GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["dir_url"] . '/images/brand-light.png" alt="." /></a></div>s2Member API / List Servers</h2>' . "\n";
23
+ /**/
24
+ echo '<div class="ws-menu-page-hr"></div>' . "\n";
25
+ /**/
26
+ echo '<table class="ws-menu-page-table">' . "\n";
27
+ echo '<tbody class="ws-menu-page-table-tbody">' . "\n";
28
+ echo '<tr class="ws-menu-page-table-tr">' . "\n";
29
+ echo '<td class="ws-menu-page-table-l">' . "\n";
30
+ /**/
31
+ echo '<form method="post" name="ws_plugin__s2member_options_form" id="ws-plugin--s2member-options-form">' . "\n";
32
+ echo '<input type="hidden" name="ws_plugin__s2member_options_save" id="ws-plugin--s2member-options-save" value="' . esc_attr (wp_create_nonce ("ws-plugin--s2member-options-save")) . '" />' . "\n";
33
+ /**/
34
+ echo '<div class="ws-menu-page-group" title="MailChimp® List Server Integration">' . "\n";
35
+ /**/
36
+ echo '<div class="ws-menu-page-section ws-plugin--s2member-mailchimp-section">' . "\n";
37
+ echo '<a href="http://www.mailchimp.com/signup/?aid=8f347da54d66b5298d13237d9&afl=1" target="_blank"><img src="' . $GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["dir_url"] . '/images/mailchimp-stamp.png" class="ws-menu-page-right" style="width:125px; height:125px; border:0;" alt="." /></a>' . "\n";
38
+ echo '<h3>MailChimp® List Server Integration ( optional )</h3>' . "\n";
39
+ echo '<p>s2Member can be integrated with MailChimp®. MailChimp® is an email marketing service. MailChimp® makes it easy to send email newsletters to your Customers, manage your MailChimp® subscriber lists, and track campaign performance. Although s2Member can be integrated with almost ANY list server, we highly recommend MailChimp®; because of their <a href="http://www.mailchimp.com/api/?aid=8f347da54d66b5298d13237d9&afl=1" target="_blank" rel="xlink">powerful API for MailChimp® services</a>. In future versions of s2Member, we plan to build additional features into s2Member that work with, and extend, MailChimp® services.</p>' . "\n";
40
+ echo '<p>For now, we\'ve covered the basics. You can have your Members automatically subscribed to your MailChimp® marketing lists ( e.g. newsletters / auto-responders ). You\'ll need a <a href="http://www.mailchimp.com/signup/?aid=8f347da54d66b5298d13237d9&afl=1" target="_blank" rel="xlink">MailChimp® account</a>, a <a href="http://admin.mailchimp.com/account/api-key-popup" target="_blank" rel="xlink">MailChimp® API Key</a>, and your <a href="#" onclick="alert(\'To obtain your MailChimp® List ID(s), log into your MailChimp® account, click on the Lists tab. Click the (View) button, for the list(s) you want to integrate with s2Member. Then, click the (settings) link at the top. On the main (settings) page, for each list, you\\\'ll find a Unique List ID.\'); return false;">MailChimp® List IDs</a>.</p>' . "\n";
41
+ /**/
42
+ echo '<table class="form-table">' . "\n";
43
+ echo '<tbody>' . "\n";
44
+ echo '<tr>' . "\n";
45
+ /**/
46
+ echo '<th>' . "\n";
47
+ echo '<label for="ws-plugin--s2member-mailchimp-api-key">' . "\n";
48
+ echo 'MailChimp® API Key:' . "\n";
49
+ echo '</label>' . "\n";
50
+ echo '</th>' . "\n";
51
+ /**/
52
+ echo '</tr>' . "\n";
53
+ echo '<tr>' . "\n";
54
+ /**/
55
+ echo '<td>' . "\n";
56
+ echo '<input type="text" name="ws_plugin__s2member_mailchimp_api_key" id="ws-plugin--s2member-mailchimp-api-key" value="' . format_to_edit ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["mailchimp_api_key"]) . '" /><br />' . "\n";
57
+ echo 'Once you have a MailChimp® account, you\'ll need to <a href="http://admin.mailchimp.com/account/api-key-popup" target="_blank" rel="xlink">add an API Key</a>.' . "\n";
58
+ echo '</td>' . "\n";
59
+ /**/
60
+ echo '</tr>' . "\n";
61
+ echo '<tr>' . "\n";
62
+ /**/
63
+ echo '<th>' . "\n";
64
+ echo '<label for="ws-plugin--s2member-level0-mailchimp-list-ids">' . "\n";
65
+ echo 'List ID(s) for Free Subscribers ( comma delimited ):' . "\n";
66
+ echo '</label>' . "\n";
67
+ echo '</th>' . "\n";
68
+ /**/
69
+ echo '</tr>' . "\n";
70
+ echo '<tr>' . "\n";
71
+ /**/
72
+ echo '<td>' . "\n";
73
+ echo '<input type="text" name="ws_plugin__s2member_level0_mailchimp_list_ids" id="ws-plugin--s2member-level0-mailchimp-list-ids" value="' . format_to_edit ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["level0_mailchimp_list_ids"]) . '" /><br />' . "\n";
74
+ echo 'New Free Subscribers will be subscribed to these List IDs.<br />' . "\n";
75
+ echo 'Ex: <code>4654aad4s5d, 4323344ksdf, 23234j23k3</code>' . "\n";
76
+ echo '</td>' . "\n";
77
+ /**/
78
+ echo '</tr>' . "\n";
79
+ echo '<tr>' . "\n";
80
+ /**/
81
+ echo '<th>' . "\n";
82
+ echo '<label for="ws-plugin--s2member-level1-mailchimp-list-ids">' . "\n";
83
+ echo 'List ID(s) for Level #1 ( comma delimited ):' . "\n";
84
+ echo '</label>' . "\n";
85
+ echo '</th>' . "\n";
86
+ /**/
87
+ echo '</tr>' . "\n";
88
+ echo '<tr>' . "\n";
89
+ /**/
90
+ echo '<td>' . "\n";
91
+ echo '<input type="text" name="ws_plugin__s2member_level1_mailchimp_list_ids" id="ws-plugin--s2member-level1-mailchimp-list-ids" value="' . format_to_edit ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["level1_mailchimp_list_ids"]) . '" /><br />' . "\n";
92
+ echo 'New Level 1 Members will be subscribed to these List IDs.<br />' . "\n";
93
+ echo 'Ex: <code>4654aad4s5d, 4323344ksdf, 23234j23k3</code>' . "\n";
94
+ echo '</td>' . "\n";
95
+ /**/
96
+ echo '</tr>' . "\n";
97
+ echo '<tr>' . "\n";
98
+ /**/
99
+ echo '<th>' . "\n";
100
+ echo '<label for="ws-plugin--s2member-level2-mailchimp-list-ids">' . "\n";
101
+ echo 'List ID(s) for Level #2 ( comma delimited ):' . "\n";
102
+ echo '</label>' . "\n";
103
+ echo '</th>' . "\n";
104
+ /**/
105
+ echo '</tr>' . "\n";
106
+ echo '<tr>' . "\n";
107
+ /**/
108
+ echo '<td>' . "\n";
109
+ echo '<input type="text" name="ws_plugin__s2member_level2_mailchimp_list_ids" id="ws-plugin--s2member-level2-mailchimp-list-ids" value="' . format_to_edit ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["level2_mailchimp_list_ids"]) . '" /><br />' . "\n";
110
+ echo 'New Level 2 Members will be subscribed to these List IDs.' . "\n";
111
+ echo '</td>' . "\n";
112
+ /**/
113
+ echo '</tr>' . "\n";
114
+ echo '<tr>' . "\n";
115
+ /**/
116
+ echo '<th>' . "\n";
117
+ echo '<label for="ws-plugin--s2member-level3-mailchimp-list-ids">' . "\n";
118
+ echo 'List ID(s) for Level #3 ( comma delimited ):' . "\n";
119
+ echo '</label>' . "\n";
120
+ echo '</th>' . "\n";
121
+ /**/
122
+ echo '</tr>' . "\n";
123
+ echo '<tr>' . "\n";
124
+ /**/
125
+ echo '<td>' . "\n";
126
+ echo '<input type="text" name="ws_plugin__s2member_level3_mailchimp_list_ids" id="ws-plugin--s2member-level3-mailchimp-list-ids" value="' . format_to_edit ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["level3_mailchimp_list_ids"]) . '" /><br />' . "\n";
127
+ echo 'New Level 3 Members will be subscribed to these List IDs.' . "\n";
128
+ echo '</td>' . "\n";
129
+ /**/
130
+ echo '</tr>' . "\n";
131
+ echo '<tr>' . "\n";
132
+ /**/
133
+ echo '<th>' . "\n";
134
+ echo '<label for="ws-plugin--s2member-level4-mailchimp-list-ids">' . "\n";
135
+ echo 'List ID(s) for Level #4 ( comma delimited ):' . "\n";
136
+ echo '</label>' . "\n";
137
+ echo '</th>' . "\n";
138
+ /**/
139
+ echo '</tr>' . "\n";
140
+ echo '<tr>' . "\n";
141
+ /**/
142
+ echo '<td>' . "\n";
143
+ echo '<input type="text" name="ws_plugin__s2member_level4_mailchimp_list_ids" id="ws-plugin--s2member-level4-mailchimp-list-ids" value="' . format_to_edit ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["level4_mailchimp_list_ids"]) . '" /><br />' . "\n";
144
+ echo 'New Level 4 Members will be subscribed to these List IDs.' . "\n";
145
+ echo '</td>' . "\n";
146
+ /**/
147
+ echo '</tr>' . "\n";
148
+ echo '</tbody>' . "\n";
149
+ echo '</table>' . "\n";
150
+ echo '</div>' . "\n";
151
+ /**/
152
+ echo '</div>' . "\n";
153
+ /**/
154
+ echo '<div class="ws-menu-page-group" title="AWeber® List Server Integration">' . "\n";
155
+ /**/
156
+ echo '<div class="ws-menu-page-section ws-plugin--s2member-aweber-section">' . "\n";
157
+ echo '<a href="http://aweber.com/?348037" target="_blank"><img src="' . $GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["dir_url"] . '/images/aweber-logo.png" class="ws-menu-page-right" style="width:125px; height:125px; border:0;" alt="." /></a>' . "\n";
158
+ echo '<h3>AWeber® List Server Integration ( optional )</h3>' . "\n";
159
+ echo '<p>s2Member can be integrated with AWeber®. AWeber® is an email marketing service. Whether you\'re looking to get your first email campaign off the ground, or you\'re a seasoned veteran who wants to dig into advanced tools like detailed email web analytics, activity based segmentation, geo-targeting and broadcast split-testing, AWeber\'s got just what you need to make email marketing work for you.</p>' . "\n";
160
+ echo '<p>You can have your Members automatically subscribed to your AWeber® marketing lists ( e.g. newsletters / auto-responders ). You\'ll need an <a href="http://aweber.com/?348037" target="_blank" rel="xlink">AWeber® account</a> and your <a href="#" onclick="alert(\'To obtain your AWeber® List ID(s), log into your AWeber® account. Click on the Lists tab. On that page you\\\'ll find a Unique List ID associated with each of your lists. AWeber® sometimes refers to this as a List Name instead of a List ID.\'); return false;">AWeber® List IDs</a>. You will ALSO need to configure a Custom Email Parser inside your AWeber® account. Log into AWeber®, and go to <em>My Lists -> Email Parser</em>. Choose the PayPal® Parser. You can safely ignore the additional instructions they provide. s2Member just needs the PayPal® box checked, and that\'s all. At some point, we\'ll get in contact with AWeber® about integrating a Custom Parser that is specifically designed for s2Member. Until then, you can just use the PayPal® Parser that is already available in your AWeber® account.</p>' . "\n";
161
+ /**/
162
+ echo '<table class="form-table">' . "\n";
163
+ echo '<tbody>' . "\n";
164
+ echo '<tr>' . "\n";
165
+ /**/
166
+ echo '<th>' . "\n";
167
+ echo '<label for="ws-plugin--s2member-level0-aweber-list-ids">' . "\n";
168
+ echo 'List ID(s) for Free Subscribers ( comma delimited ):' . "\n";
169
+ echo '</label>' . "\n";
170
+ echo '</th>' . "\n";
171
+ /**/
172
+ echo '</tr>' . "\n";
173
+ echo '<tr>' . "\n";
174
+ /**/
175
+ echo '<td>' . "\n";
176
+ echo '<input type="text" name="ws_plugin__s2member_level0_aweber_list_ids" id="ws-plugin--s2member-level0-aweber-list-ids" value="' . format_to_edit ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["level0_aweber_list_ids"]) . '" /><br />' . "\n";
177
+ echo 'New Free Subscribers will be subscribed to these List IDs.<br />' . "\n";
178
+ echo 'Ex: <code>mylist, myotherlist, anotherlist</code>' . "\n";
179
+ echo '</td>' . "\n";
180
+ /**/
181
+ echo '</tr>' . "\n";
182
+ echo '<tr>' . "\n";
183
+ /**/
184
+ echo '<th>' . "\n";
185
+ echo '<label for="ws-plugin--s2member-level1-aweber-list-ids">' . "\n";
186
+ echo 'List ID(s) for Level #1 ( comma delimited ):' . "\n";
187
+ echo '</label>' . "\n";
188
+ echo '</th>' . "\n";
189
+ /**/
190
+ echo '</tr>' . "\n";
191
+ echo '<tr>' . "\n";
192
+ /**/
193
+ echo '<td>' . "\n";
194
+ echo '<input type="text" name="ws_plugin__s2member_level1_aweber_list_ids" id="ws-plugin--s2member-level1-aweber-list-ids" value="' . format_to_edit ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["level1_aweber_list_ids"]) . '" /><br />' . "\n";
195
+ echo 'New Level 1 Members will be subscribed to these List IDs.<br />' . "\n";
196
+ echo 'Ex: <code>mylist, myotherlist, anotherlist</code>' . "\n";
197
+ echo '</td>' . "\n";
198
+ /**/
199
+ echo '</tr>' . "\n";
200
+ echo '<tr>' . "\n";
201
+ /**/
202
+ echo '<th>' . "\n";
203
+ echo '<label for="ws-plugin--s2member-level2-aweber-list-ids">' . "\n";
204
+ echo 'List ID(s) for Level #2 ( comma delimited ):' . "\n";
205
+ echo '</label>' . "\n";
206
+ echo '</th>' . "\n";
207
+ /**/
208
+ echo '</tr>' . "\n";
209
+ echo '<tr>' . "\n";
210
+ /**/
211
+ echo '<td>' . "\n";
212
+ echo '<input type="text" name="ws_plugin__s2member_level2_aweber_list_ids" id="ws-plugin--s2member-level2-aweber-list-ids" value="' . format_to_edit ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["level2_aweber_list_ids"]) . '" /><br />' . "\n";
213
+ echo 'New Level 2 Members will be subscribed to these List IDs.' . "\n";
214
+ echo '</td>' . "\n";
215
+ /**/
216
+ echo '</tr>' . "\n";
217
+ echo '<tr>' . "\n";
218
+ /**/
219
+ echo '<th>' . "\n";
220
+ echo '<label for="ws-plugin--s2member-level3-aweber-list-ids">' . "\n";
221
+ echo 'List ID(s) for Level #3 ( comma delimited ):' . "\n";
222
+ echo '</label>' . "\n";
223
+ echo '</th>' . "\n";
224
+ /**/
225
+ echo '</tr>' . "\n";
226
+ echo '<tr>' . "\n";
227
+ /**/
228
+ echo '<td>' . "\n";
229
+ echo '<input type="text" name="ws_plugin__s2member_level3_aweber_list_ids" id="ws-plugin--s2member-level3-aweber-list-ids" value="' . format_to_edit ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["level3_aweber_list_ids"]) . '" /><br />' . "\n";
230
+ echo 'New Level 3 Members will be subscribed to these List IDs.' . "\n";
231
+ echo '</td>' . "\n";
232
+ /**/
233
+ echo '</tr>' . "\n";
234
+ echo '<tr>' . "\n";
235
+ /**/
236
+ echo '<th>' . "\n";
237
+ echo '<label for="ws-plugin--s2member-level4-aweber-list-ids">' . "\n";
238
+ echo 'List ID(s) for Level #4 ( comma delimited ):' . "\n";
239
+ echo '</label>' . "\n";
240
+ echo '</th>' . "\n";
241
+ /**/
242
+ echo '</tr>' . "\n";
243
+ echo '<tr>' . "\n";
244
+ /**/
245
+ echo '<td>' . "\n";
246
+ echo '<input type="text" name="ws_plugin__s2member_level4_aweber_list_ids" id="ws-plugin--s2member-level4-aweber-list-ids" value="' . format_to_edit ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["level4_aweber_list_ids"]) . '" /><br />' . "\n";
247
+ echo 'New Level 4 Members will be subscribed to these List IDs.' . "\n";
248
+ echo '</td>' . "\n";
249
+ /**/
250
+ echo '</tr>' . "\n";
251
+ echo '</tbody>' . "\n";
252
+ echo '</table>' . "\n";
253
+ echo '</div>' . "\n";
254
+ /**/
255
+ echo '</div>' . "\n";
256
+ /**/
257
+ echo '<div class="ws-menu-page-group" title="Other List Server Integration Methods">' . "\n";
258
+ /**/
259
+ echo '<div class="ws-menu-page-section ws-plugin--s2member-other-lists-section">' . "\n";
260
+ echo '<h3>Other List Server Integrations ( there\'s always a way )</h3>' . "\n";
261
+ 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 `Single-Page` notifications that are available to you through the s2Member API. These make it possible to integrate with 3rd party applications; like list servers, affiliate programs, and other back-office routines; in more advanced ways. You will probably need to get help from a web developer though. s2Member API Notifications require some light PHP scripting by someone familiar with web service connections.</p>' . "\n";
262
+ echo '</div>' . "\n";
263
+ /**/
264
+ echo '</div>' . "\n";
265
+ /**/
266
+ echo '<div class="ws-menu-page-hr"></div>' . "\n";
267
+ /**/
268
+ echo '<p class="submit"><input type="submit" class="button-primary" value="Save Changes" /></p>' . "\n";
269
+ /**/
270
+ echo '</form>' . "\n";
271
+ /**/
272
+ echo '</td>' . "\n";
273
+ /**/
274
+ echo '<td class="ws-menu-page-table-r">' . "\n";
275
+ /**/
276
+ echo ($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["menu-r"]["installation"]) ? '<div class="ws-menu-page-installation"><a href="' . ws_plugin__s2member_parse_readme_value ("Professional Installation URI") . '"><img src="' . $GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["dir_url"] . '/images/brand-installation.png" alt="." title="Contact PriMoThemes!" /></a></div>' . "\n" : '';
277
+ /**/
278
+ echo ($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["menu-r"]["tools"]) ? '<div class="ws-menu-page-tools"><img src="' . $GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["dir_url"] . '/images/brand-tools.png" alt="." /></div>' . "\n" : '';
279
+ /**/
280
+ echo ($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["menu-r"]["tips"]) ? '<div class="ws-menu-page-tips"><a href="' . ws_plugin__s2member_parse_readme_value ("Customization URI") . '"><img src="' . $GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["dir_url"] . '/images/brand-tips.png" alt="." /></a></div>' . "\n" : '';
281
+ /**/
282
+ echo ($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["menu-r"]["donations"]) ? '<div class="ws-menu-page-donations"><a href="' . ws_plugin__s2member_parse_readme_value ("Donate link") . '"><img src="' . $GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["dir_url"] . '/images/brand-donations.jpg" alt="." /></a></div>' . "\n" : '';
283
+ /**/
284
+ echo '</td>' . "\n";
285
+ /**/
286
+ echo '</tr>' . "\n";
287
+ echo '</tbody>' . "\n";
288
+ echo '</table>' . "\n";
289
+ /**/
290
+ echo '</div>' . "\n";
291
+ ?>
includes/menu-pages/events.inc.php DELETED
@@ -1,118 +0,0 @@
1
- <?php
2
- /*
3
- Copyright: © 2009 WebSharks, Inc. ( coded in the USA )
4
- <mailto:support@websharks-inc.com> <http://www.websharks-inc.com/>
5
-
6
- Released under the terms of the GNU General Public License.
7
- You should have received a copy of the GNU General Public License,
8
- along with this software. In the main directory, see: /licensing/
9
- If not, see: <http://www.gnu.org/licenses/>.
10
- */
11
- /*
12
- Direct access denial.
13
- */
14
- if (realpath (__FILE__) === realpath ($_SERVER["SCRIPT_FILENAME"]))
15
- exit;
16
- /*
17
- Flow Of Events page.
18
- */
19
- echo '<div class="wrap ws-menu-page">' . "\n";
20
- /**/
21
- echo '<div id="icon-plugins" class="icon32"><br /></div>' . "\n";
22
- echo '<h2><div>Developed by <a href="' . ws_plugin__s2member_parse_readme_value ("Plugin URI") . '"><img src="' . $GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["dir_url"] . '/images/brand-light.png" alt="." /></a></div>s2Member Flow Of Events</h2>' . "\n";
23
- /**/
24
- echo '<div class="ws-menu-page-hr"></div>' . "\n";
25
- /**/
26
- echo '<table class="ws-menu-page-table">' . "\n";
27
- echo '<tbody class="ws-menu-page-table-tbody">' . "\n";
28
- echo '<tr class="ws-menu-page-table-tr">' . "\n";
29
- echo '<td class="ws-menu-page-table-l">' . "\n";
30
- /**/
31
- echo '<div class="ws-menu-page-group" title="The Registration Process">' . "\n";
32
- /**/
33
- echo '<div class="ws-menu-page-section ws-plugin--s2member-registration-process-section">' . "\n";
34
- echo '<h3>The Subscription Registration Process</h3>' . "\n";
35
- echo '<p>1. Internet Users will go to your Membership Options Page ( which you\'ll need to configure on the s2Member General Options panel ). On this Membership Options Page, that YOU will create in WordPress®, you\'ll insert the PayPal® Subscription Buttons that were generated for you by s2Member.</p>' . "\n";
36
- echo '<p>2. An Internet User will click on a PayPal® Subscription Button from your Membership Options Page. They will be transferred over to PayPal® in order to agree to your membership terms and pricing. You can customize the Checkout Page Style, Pricing, Payment Periods, and more whenever you generate your PayPal® Buttons through s2Member.</p>' . "\n";
37
- echo '<p>3. Once a User has completed the Subscription Signup Process at PayPal®, they\'ll be returned to your site, where they\'ll be activated by s2Member instantly, and given the opportunity to register a Username &amp; Password for their membership on the next page ( note: they\'ll be allowed to register a Username &amp; Password, even if you\'ve set \'Anyone Can Register\' to `Off` in your General WordPress® options, because s2Member identifies the user as having paid for membership access through PayPal® ). s2Member will also send the User an email with instructions on how to register their Username &amp; Password, just in case they missed the instructions after checkout. That email will be sent to their PayPal® email address. And it will be sent even if they never returned to your site after checkout for some reason. Much of this is handled through the PayPal® IPN service behind the scenes, where PayPal® and s2Member communicate with each other.</p>' . "\n";
38
- echo '<p>4. Once a User has completed checkout and registered a Username &amp; Password, they\'ll be able to login. The first page they\'ll see after logging in, will be your Login Welcome Page ( which you\'ll need to configure on the s2Member General Options panel ). Your Login Welcome Page can contain whatever you like. Feel free to be creative whenever you create this Page in WordPress®.</p>' . "\n";
39
- echo '</div>' . "\n";
40
- /**/
41
- echo '</div>' . "\n";
42
- /**/
43
- echo '<div class="ws-menu-page-group" title="Subscription Cancellations">' . "\n";
44
- /**/
45
- echo '<div class="ws-menu-page-section ws-plugin--s2member-automation-process-section">' . "\n";
46
- echo '<h3>Subscription Cancellations / Expirations / Terminations</h3>' . "\n";
47
- 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 User\'s subscription, or, if the User 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 scenes. The PayPal® IPN service will notify s2Member whenever a User\'s payments have been failing ( more than 2 times in a row ), and/or whenever a User\'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 be deleted automagically. The communication from PayPal® -> s2Member is seamless. You may also want to check the s2Member API Notifications panel. You\'ll find additional layers of automation available through the use of the `Signup`, `Payment`, `EOT/Deletion` and `Refund/Reversal` notifications that are available to you through the s2Member API. These make it easy to integrate with 3rd party applications like affiliate programs and other back-office routines.</p>' . "\n";
48
- echo '</div>' . "\n";
49
- /**/
50
- echo '<div class="ws-menu-page-hr ws-plugin--s2member-automation-hairy-details-section-hr"></div>' . "\n";
51
- /**/
52
- echo '<div class="ws-menu-page-section ws-plugin--s2member-automation-hairy-details-section">' . "\n";
53
- echo '<h3>Subscription Cancellations / Some Hairy Details With Dates</h3>' . "\n";
54
- echo '<p>There might be times whenever you notice that a User\'s subscription has been cancelled through PayPal®... but, s2Member continues to allow the User to access 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 the SUBSCR_EOT notification via the IPN service. PayPal® will sometimes wait to send this SUBSCR_EOT notification 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 and PayPal® will send the SUBSCR_EOT notification to s2Member. At that time, s2Member will remove their membership privileges by deleting their account from the system automatically.</p>' . "\n";
55
- echo '</div>' . "\n";
56
- /**/
57
- echo '</div>' . "\n";
58
- /**/
59
- echo '<div class="ws-menu-page-group" title="Upgrading/Downgrading Accounts">' . "\n";
60
- /**/
61
- echo '<div class="ws-menu-page-section ws-plugin--s2member-upgrading-downgrading-section">' . "\n";
62
- echo '<h3>Upgrading And/Or Downgrading User Accounts</h3>' . "\n";
63
- echo '<p>s2Member builds upon existing functionality offered through WordPress® Roles and Capabilities. From your WordPress® Dashboard, go to: <code>Users -> Authors &amp; Users</code>. You can use the bulk actions to modify User access levels all at once, or click on an individual User account to modify only their specific access level. If you want to temporarily demote a user so they cannot access membership priveledges, set their Role to Subscriber. When you\'re ready to give them their membership priviledges back, change their Role back to one of the s2Member levels.</p>' . "\n";
64
- echo '<p>All financial details, such as pricing, trial periods, subscription lengths, refunds, and other customer service issues; should be handled by YOU, through your PayPal® account, and NOT through WordPress®. Feel free to modify your Users\' Subscriptions via PayPal® as often as you like. s2Member will be notified through the PayPal® IPN service behind the scenes automatically. For example... If you log into PayPal® and cancel a User\'s paid Subscription, s2Member will be notified by PayPal® behind the scenes, and s2Member will remove their membership priviledges at the correct point in time.</p>' . "\n";
65
- echo '<p>That being said, if you log into your WordPress® Dashboard and delete a User account, you will still need to log into PayPal® and cancel the billing for the account you deleted. In other words, s2Member can be notified automatically about actions you take inside PayPal\'s interface, but PayPal® CANNOT be notified of actions you take inside your WordPress® Dashboard. At least, not in an automated fashion, as that would create a security issue for PayPal® users. So... automation works seamlessly from PayPal® -> to s2Member, but NOT the other way around.</p>' . "\n";
66
- echo '</div>' . "\n";
67
- /**/
68
- echo '<div class="ws-menu-page-hr ws-plugin--s2member-subscription-modification-section-hr"></div>' . "\n";
69
- /**/
70
- echo '<div class="ws-menu-page-section ws-plugin--s2member-subscription-modification-section">' . "\n";
71
- echo '<h3>Giving Members The Ability To Modify Their Own Subscription</h3>' . "\n";
72
- echo '<p>Using the PayPal® Subscription Buttons that were generated for you by s2Member, look for this input variable ( <code>modify=0</code> ) and change that to ( <code>modify=2</code> ). Now you can simply provide your Subscription Modification Buttons to existing Members wherever you feel they would be appropriate on your site. We suggest placing these on the Login Welcome Page that you create in WordPress®, that way they\'re not available to the general public, only to Members who are logged in. When an existing Member clicks one of these Subscription Modification Buttons, they\'ll be taken to PayPal® just like they would if they were setting up a new account. But, once they actually get logged in over at PayPal®, the flow of events that occur next, will be slightly different than they would be normally. The Subscription Modification Buttons cause the PayPal® system to react differently.</p>' . "\n";
73
- echo '<p>When you send a Member to PayPal® using a Subscription Modification Button, instead of being able to signup for a new membership, PayPal® will provide them with the ability to upgrade and/or downgrade their existing membership with you, by allowing them to switch to the one that was specified in the Subscription Modification Button. PayPal® handles this nicely, and you\'ll be happy to know that s2Member has been pre-configured to deal with this scenario as well, so that everything remains automated. Their Membership Access Level will either be promoted or demoted based on the actions they took at PayPal® during the modification process. Once a user completes their Subscription Modification at PayPal®, they\'ll be brought back to their Login Welcome Page, instead of to the registration screen.</p>' . "\n";
74
- echo '</div>' . "\n";
75
- /**/
76
- echo '<div class="ws-menu-page-hr ws-plugin--s2member-subscription-modification-section-hr"></div>' . "\n";
77
- /**/
78
- echo '<div class="ws-menu-page-section ws-plugin--s2member-subscription-modification-section">' . "\n";
79
- echo '<h3>Unfortunately, The <code>modify=2</code> Approach, Does NOT Always Work Well</h3>' . "\n";
80
- echo '<p>There are a few circumstances when this will NOT work using the ( <code>modify=2</code> ) solution described above. For example, if you offer your visitors a subscription option that does NOT recur, then PayPal® will not allow them to modify to a different plan that you offer, because there is no recurring payment associated with the existing subscription they have with you. Another example is when you have a Member who WAS setup to recur, but their subscription has expired or been cancelled; so it is no longer recurring. In other words, PayPal® will ONLY play nice on the ( <code>modify=2</code> ) approach, if the existing subscription ( the one that needs to be modified ) is still active and setup to recur. Luckily, this is usually not a problem, because in most cases a modification is being requested to adjust a monthly or yearly fee, not to stop or start anything.</p>' . "\n";
81
- echo '<p>In those rare cases when you need to send an existing Customer over to PayPal® and have them signup for a new subscription, without forcing them to re-register for a new account afterward, you can add the following two variables to your Button Code. Add ( <code>on0 = "Update Subscription ID"</code> ), and set ( <code>os0 = "[Their existing Subscription ID]"</code> ). Adding these two additional input variables will allow s2Member to work seamlessly with PayPal® after they signup. Instead of asking them to re-register for a new account, s2Member will update their existing account and provide responses similar to what you would see using the ( <code>modify=2</code> ) approach. You can use the s2Member Constants in PHP to access the current Members\'s Subscription ID. We\'ve provided an example below.</p>' . "\n";
82
- echo '<p><strong>S2MEMBER_CURRENT_USER_SUBSCR_ID</strong> = their existing Subscription ID</p>' . "\n";
83
- echo '<p>' . highlight_string (file_get_contents (dirname (__FILE__) . "/con-samps/current_user_subscr_id.php"), true) . '</p>' . "\n";
84
- echo '<div class="ws-menu-page-hr"></div>' . "\n";
85
- echo '<p>' . highlight_string (file_get_contents (dirname (__FILE__) . "/mod-samps.php"), true) . '</p>' . "\n";
86
- echo '</div>' . "\n";
87
- /**/
88
- echo '<div class="ws-menu-page-hr ws-plugin--s2member-subscription-modification-section-hr"></div>' . "\n";
89
- /**/
90
- echo '<div class="ws-menu-page-section ws-plugin--s2member-subscription-modification-section">' . "\n";
91
- echo '<h3>Upgrading Free Subscribers To Paid Members ( same technique )</h3>' . "\n";
92
- echo '<p>If you\'ve allowed Users to signup for free <em><code>( see: s2Member->General Options->Login Welcome Page->Free Subscribers )</code></em>, and now you want to send an existing Free Subscriber over to PayPal® and have them signup for a paid Membership; without forcing them to re-register for a new account afterward; you can add the following two variables to your Button Code. Add ( <code>on0 = "Update Subscriber ID"</code> ), and set ( <code>os0 = "[Their existing Subscriber ID]"</code> ). Adding these two additional input variables will allow s2Member to work seamlessly with PayPal® after they signup. Instead of asking them to re-register for a new account, s2Member will update their existing account and provide responses similar to what you would see using the ( <code>modify=2</code> ) approach. You can use the s2Member Constants in PHP to access the current User\'s Subscriber ID. We\'ve provided an example below.</p>' . "\n";
93
- echo '<p><strong>S2MEMBER_CURRENT_USER_SUBSCR_ID</strong> = their existing Subscriber ID</p>' . "\n";
94
- echo '<p>' . highlight_string (file_get_contents (dirname (__FILE__) . "/con-samps/current_user_subscr_id.php"), true) . '</p>' . "\n";
95
- echo '<div class="ws-menu-page-hr"></div>' . "\n";
96
- echo '<p>' . highlight_string (file_get_contents (dirname (__FILE__) . "/s2m-samps.php"), true) . '</p>' . "\n";
97
- echo '</div>' . "\n";
98
- /**/
99
- echo '</div>' . "\n";
100
- /**/
101
- echo '</td>' . "\n";
102
- /**/
103
- echo '<td class="ws-menu-page-table-r">' . "\n";
104
- /**/
105
- echo ($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["menu-r"]["tools"]) ? '<div class="ws-menu-page-tools"><img src="' . $GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["dir_url"] . '/images/brand-tools.png" alt="." /></div>' . "\n" : '';
106
- /**/
107
- echo ($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["menu-r"]["tips"]) ? '<div class="ws-menu-page-tips"><a href="' . ws_plugin__s2member_parse_readme_value ("Customization URI") . '"><img src="' . $GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["dir_url"] . '/images/brand-tips.png" alt="." /></a></div>' . "\n" : '';
108
- /**/
109
- echo ($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["menu-r"]["donations"]) ? '<div class="ws-menu-page-donations"><a href="' . ws_plugin__s2member_parse_readme_value ("Donate link") . '"><img src="' . $GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["dir_url"] . '/images/brand-donations.jpg" alt="." /></a></div>' . "\n" : '';
110
- /**/
111
- echo '</td>' . "\n";
112
- /**/
113
- echo '</tr>' . "\n";
114
- echo '</tbody>' . "\n";
115
- echo '</table>' . "\n";
116
- /**/
117
- echo '</div>' . "\n";
118
- ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
includes/menu-pages/info.inc.php CHANGED
@@ -40,6 +40,8 @@ echo '</td>' . "\n";
40
  /**/
41
  echo '<td class="ws-menu-page-table-r">' . "\n";
42
  /**/
 
 
43
  echo ($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["menu-r"]["tools"]) ? '<div class="ws-menu-page-tools"><img src="' . $GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["dir_url"] . '/images/brand-tools.png" alt="." /></div>' . "\n" : '';
44
  /**/
45
  echo ($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["menu-r"]["tips"]) ? '<div class="ws-menu-page-tips"><a href="' . ws_plugin__s2member_parse_readme_value("Customization URI") . '"><img src="' . $GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["dir_url"] . '/images/brand-tips.png" alt="." /></a></div>' . "\n" : '';
40
  /**/
41
  echo '<td class="ws-menu-page-table-r">' . "\n";
42
  /**/
43
+ echo ($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["menu-r"]["installation"]) ? '<div class="ws-menu-page-installation"><a href="' . ws_plugin__s2member_parse_readme_value ("Professional Installation URI") . '"><img src="' . $GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["dir_url"] . '/images/brand-installation.png" alt="." title="Contact PriMoThemes!" /></a></div>' . "\n" : '';
44
+ /**/
45
  echo ($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["menu-r"]["tools"]) ? '<div class="ws-menu-page-tools"><img src="' . $GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["dir_url"] . '/images/brand-tools.png" alt="." /></div>' . "\n" : '';
46
  /**/
47
  echo ($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["menu-r"]["tips"]) ? '<div class="ws-menu-page-tips"><a href="' . ws_plugin__s2member_parse_readme_value("Customization URI") . '"><img src="' . $GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["dir_url"] . '/images/brand-tips.png" alt="." /></a></div>' . "\n" : '';
includes/menu-pages/menu-pages.css CHANGED
@@ -455,4 +455,13 @@ div.ws-menu-page > table.ws-menu-page-table > tbody > tr > td.ws-menu-page-table
455
  /*
456
  These CSS selectors are specific to this software.
457
  */
458
- /* None currently. */
 
 
 
 
 
 
 
 
 
455
  /*
456
  These CSS selectors are specific to this software.
457
  */
458
+ div.ws-menu-page > table.ws-menu-page-table > tbody > tr > td.ws-menu-page-table-r > div.ws-menu-page-installation
459
+ {
460
+ margin: 0 0 10px 25px;
461
+ }
462
+ div.ws-menu-page > table.ws-menu-page-table > tbody > tr > td.ws-menu-page-table-r > div.ws-menu-page-installation > a > img
463
+ {
464
+ width: 200px;
465
+ height: 150px;
466
+ border: 1px solid transparent;
467
+ }
includes/menu-pages/menu-pages.js CHANGED
@@ -83,7 +83,7 @@ jQuery(document).ready (function($)
83
  /**/
84
  $('input.ws-menu-page-media-btn').filter (function() /* Only those that have a rel attribute. */
85
  {
86
- return ($(this).attr ('rel')) ? true : false; /* Must have rel targeting an input id. */
87
  })/**/
88
  .click (function() /* Attach click events to media buttons with send_to_editor(). */
89
  {
@@ -128,90 +128,162 @@ jQuery(document).ready (function($)
128
  /*
129
  These routines are all specific to this software.
130
  */
131
- $('form#ws-plugin--s2member-buttons-form select#ws-plugin--s2member-level1-term').change (function()
132
  {
133
- var trialDisabled = ($(this).val ().split ('-')[1].replace (/[^A-Z]/g, '') === 'L') ? 'disabled' : '';
134
- $('p#ws-plugin--s2member-level1-trial-line').css ('display', (trialDisabled ? 'none' : ''));
135
- $('span#ws-plugin--s2member-level1-trial-then').css ('display', (trialDisabled ? 'none' : ''));
136
- });
137
- /**/
138
- $('form#ws-plugin--s2member-buttons-form select#ws-plugin--s2member-level2-term').change (function()
139
- {
140
- var trialDisabled = ($(this).val ().split ('-')[1].replace (/[^A-Z]/g, '') === 'L') ? 'disabled' : '';
141
- $('p#ws-plugin--s2member-level2-trial-line').css ('display', (trialDisabled ? 'none' : ''));
142
- $('span#ws-plugin--s2member-level2-trial-then').css ('display', (trialDisabled ? 'none' : ''));
143
- });
144
- /**/
145
- $('form#ws-plugin--s2member-buttons-form select#ws-plugin--s2member-level3-term').change (function()
146
- {
147
- var trialDisabled = ($(this).val ().split ('-')[1].replace (/[^A-Z]/g, '') === 'L') ? 'disabled' : '';
148
- $('p#ws-plugin--s2member-level3-trial-line').css ('display', (trialDisabled ? 'none' : ''));
149
- $('span#ws-plugin--s2member-level3-trial-then').css ('display', (trialDisabled ? 'none' : ''));
150
- });
151
- /**/
152
- $('form#ws-plugin--s2member-buttons-form select#ws-plugin--s2member-level4-term').change (function()
153
- {
154
- var trialDisabled = ($(this).val ().split ('-')[1].replace (/[^A-Z]/g, '') === 'L') ? 'disabled' : '';
155
- $('p#ws-plugin--s2member-level4-trial-line').css ('display', (trialDisabled ? 'none' : ''));
156
- $('span#ws-plugin--s2member-level4-trial-then').css ('display', (trialDisabled ? 'none' : ''));
157
- });
158
- /**/
159
- ws_plugin__s2member_paypalButtonGenerate = function(level) /* Handles PayPal® Button Generation. */
160
- {
161
- var shortCodeTemplate = '[s2Member-PayPal-Button %%attrs%% /]', shortCodeTemplateAttrs = '';
162
- /**/
163
- var shortCode = $('#ws-plugin--s2member-level' + level + '-shortcode');
164
- var code = $('#ws-plugin--s2member-level' + level + '-button');
165
- /**/
166
- var trialPeriod = $('#ws-plugin--s2member-level' + level + '-trial-period').val ().replace (/[^0-9]/g, '');
167
- var trialTerm = $('#ws-plugin--s2member-level' + level + '-trial-term').val ().replace (/[^A-Z]/g, '');
168
- var regAmount = $('#ws-plugin--s2member-level' + level + '-amount').val ().replace (/[^0-9\.]/g, '');
169
- var regPeriod = $('#ws-plugin--s2member-level' + level + '-term').val ().split ('-')[0].replace (/[^0-9]/g, '');
170
- var regTerm = $('#ws-plugin--s2member-level' + level + '-term').val ().split ('-')[1].replace (/[^A-Z]/g, '');
171
- var regRecur = $('#ws-plugin--s2member-level' + level + '-term').val ().split ('-')[2].replace (/[^0-1]/g, '');
172
- var pageStyle = $.trim ($('#ws-plugin--s2member-level' + level + '-page-style').val ().replace (/["']/g, ''));
173
- var currencyCode = $('#ws-plugin--s2member-level' + level + '-currency').val ().replace (/[^A-Z]/g, '');
174
- trialPeriod = (regTerm === 'L') ? '0' : trialPeriod; /* Lifetime access is NOT compatible w/trials. */
175
- /**/
176
- if (trialTerm === 'D' && trialPeriod > 90) /* Some validation on the trial period. Max days: 90. */
177
- alert('* WARNING: Maximum Free Days is: 90.\nIf you want to offer more than 90 days free, please choose Weeks or Months from the drop-down.'), trialPeriod = 90;
178
- else if (trialTerm === 'W' && trialPeriod > 52) /* Some validation on the trial period. 52 max. */
179
- alert('* WARNING: Maximum Free Weeks is: 52.\nIf you want to offer more than 52 weeks free, please choose Months from the drop-down.'), trialPeriod = 52;
180
- else if (trialTerm === 'M' && trialPeriod > 24) /* Some validation on the trial period. 24 max. */
181
- alert('* WARNING: Maximum Free Months is: 24.\nIf you want to offer more than 24 months free, please choose Years from the drop-down.'), trialPeriod = 24;
182
- else if (trialTerm === 'Y' && trialPeriod > 5) /* 5 years max. */
183
- alert('* WARNING: Maximum Free Years is: 5.'), trialPeriod = 5;
184
- /**/
185
- code.val (code.val ().replace (/ \<\!--(\<input type\="hidden" name\="(amount|modify|src|sra|a1|p1|t1|a3|p3|t3)" value\="(.*?)" \/\>)--\>/g, " $1"));
186
- (parseInt(trialPeriod) <= 0) ? code.val (code.val ().replace (/ (\<input type\="hidden" name\="(a1|p1|t1)" value\="(.*?)" \/\>)/g, " <!--$1-->")) : null;
187
- (regTerm === 'L') ? code.val (code.val ().replace (/ (\<input type\="hidden" name\="cmd" value\=")(.*?)(" \/\>)/g, " $1_xclick$3")) : null;
188
- (regTerm === 'L') ? code.val (code.val ().replace (/ (\<input type\="hidden" name\="(modify|src|sra|a1|p1|t1|a3|p3|t3)" value\="(.*?)" \/\>)/g, " <!--$1-->")) : null;
189
- (regTerm !== 'L') ? code.val (code.val ().replace (/ (\<input type\="hidden" name\="cmd" value\=")(.*?)(" \/\>)/g, " $1_xclick-subscriptions$3")) : null;
190
- (regTerm !== 'L') ? code.val (code.val ().replace (/ (\<input type\="hidden" name\="amount" value\="(.*?)" \/\>)/g, " <!--$1-->")) : null;
191
- /**/
192
- shortCodeTemplateAttrs += 'level="' + level + '" ps="' + pageStyle + '" cc="' + currencyCode + '" on0="" os0="" modify="0" custom="<?php echo $_SERVER["HTTP_HOST"]; ?>"';
193
- shortCodeTemplateAttrs += ' tp="' + trialPeriod + '" tt="' + trialTerm + '" ra="' + regAmount + '" rp="' + regPeriod + '" rt="' + regTerm + '" rr="' + regRecur + '"';
194
- shortCode.val (shortCodeTemplate.replace (/%%attrs%%/, shortCodeTemplateAttrs));
195
- /**/
196
- code.val (code.val ().replace (/ name\="currency_code" value\="(.*?)"/, ' name="currency_code" value="' + currencyCode + '"'));
197
- code.val (code.val ().replace (/ name\="amount" value\="(.*?)"/, ' name="amount" value="' + regAmount + '"'));
198
- code.val (code.val ().replace (/ name\="src" value\="(.*?)"/, ' name="src" value="' + regRecur + '"'));
199
- code.val (code.val ().replace (/ name\="p1" value\="(.*?)"/, ' name="p1" value="' + trialPeriod + '"'));
200
- code.val (code.val ().replace (/ name\="t1" value\="(.*?)"/, ' name="t1" value="' + trialTerm + '"'));
201
- code.val (code.val ().replace (/ name\="a3" value\="(.*?)"/, ' name="a3" value="' + regAmount + '"'));
202
- code.val (code.val ().replace (/ name\="p3" value\="(.*?)"/, ' name="p3" value="' + regPeriod + '"'));
203
- code.val (code.val ().replace (/ name\="t3" value\="(.*?)"/, ' name="t3" value="' + regTerm + '"'));
204
- code.val (code.val ().replace (/ name\="page_style" value\="(.*?)"/, ' name="page_style" value="' + pageStyle + '"'));
205
  /**/
206
- $('#ws-plugin--s2member-level' + level + '-button-prev').html (code.val ().replace (/\<form/, '<form target="_blank"'));
 
 
 
207
  /**/
208
- alert('Your Codes for Membership Level #' + level + ' have been generated. Please copy/paste the Shortcode Format into your Membership Options Page.');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
209
  /**/
210
- shortCode.each (function() /* Focus and select the recommended Shortcode. */
211
  {
212
- this.focus (), this.select ();
213
- });
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
214
  /**/
215
- return false;
216
- };
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
217
  });
83
  /**/
84
  $('input.ws-menu-page-media-btn').filter (function() /* Only those that have a rel attribute. */
85
  {
86
+ return($(this).attr ('rel')) ? true : false; /* Must have rel targeting an input id. */
87
  })/**/
88
  .click (function() /* Attach click events to media buttons with send_to_editor(). */
89
  {
128
  /*
129
  These routines are all specific to this software.
130
  */
131
+ if (location.href.match (/page\=ws-plugin--s2member-buttons/))
132
  {
133
+ $('select#ws-plugin--s2member-level1-term, select#ws-plugin--s2member-level2-term, select#ws-plugin--s2member-level3-term, select#ws-plugin--s2member-level4-term, select#ws-plugin--s2member-modification-term').change (function()
134
+ {
135
+ var button = this.id.replace (/^ws-plugin--s2member-(.+?)-term$/g, '$1');
136
+ var trialDisabled = ($(this).val ().split ('-')[1].replace (/[^A-Z]/g, '') === 'L') ? 'disabled' : '';
137
+ $('p#ws-plugin--s2member-' + button + '-trial-line').css ('display', (trialDisabled ? 'none' : ''));
138
+ $('span#ws-plugin--s2member-' + button + '-trial-then').css ('display', (trialDisabled ? 'none' : ''));
139
+ });
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
140
  /**/
141
+ $('input#ws-plugin--s2member-level1-ccaps, input#ws-plugin--s2member-level2-ccaps, input#ws-plugin--s2member-level3-ccaps, input#ws-plugin--s2member-level4-ccaps, input#ws-plugin--s2member-modification-ccaps').keyup (function()
142
+ {
143
+ this.value = $.trim ($.trim (this.value).replace (/[ \-]/g, '_').replace (/[^A-Z_0-9,]/gi, '').toLowerCase ());
144
+ });
145
  /**/
146
+ ws_plugin__s2member_paypalButtonGenerate = function(button) /* Handles PayPal® Button Generation. */
147
+ {
148
+ var shortCodeTemplate = '[s2Member-PayPal-Button %%attrs%% /]', shortCodeTemplateAttrs = '', labels = {};
149
+ /**/
150
+ labels['level1'] = '<?php echo ws_plugin__s2member_esc_sq ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["level1_label"]); ?>';
151
+ labels['level2'] = '<?php echo ws_plugin__s2member_esc_sq ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["level2_label"]); ?>';
152
+ labels['level3'] = '<?php echo ws_plugin__s2member_esc_sq ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["level3_label"]); ?>';
153
+ labels['level4'] = '<?php echo ws_plugin__s2member_esc_sq ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["level4_label"]); ?>';
154
+ /**/
155
+ var shortCode = $('input#ws-plugin--s2member-' + button + '-shortcode');
156
+ var code = $('textarea#ws-plugin--s2member-' + button + '-button');
157
+ var modLevel = $('select#ws-plugin--s2member-modification-level');
158
+ /**/
159
+ var level = (button === 'modification') ? modLevel.val ().split (':', 2)[1] : button.replace (/^level/, '');
160
+ var label = labels['level' + level].replace (/"/g, "'"); /* Label cannot contain double-quotes. */
161
+ var trialPeriod = $('input#ws-plugin--s2member-' + button + '-trial-period').val ().replace (/[^0-9]/g, '');
162
+ var trialTerm = $('select#ws-plugin--s2member-' + button + '-trial-term').val ().replace (/[^A-Z]/g, '');
163
+ var regAmount = $('input#ws-plugin--s2member-' + button + '-amount').val ().replace (/[^0-9\.]/g, '');
164
+ var regPeriod = $('select#ws-plugin--s2member-' + button + '-term').val ().split ('-')[0].replace (/[^0-9]/g, '');
165
+ var regTerm = $('select#ws-plugin--s2member-' + button + '-term').val ().split ('-')[1].replace (/[^A-Z]/g, '');
166
+ var regRecur = $('select#ws-plugin--s2member-' + button + '-term').val ().split ('-')[2].replace (/[^0-1]/g, '');
167
+ var pageStyle = $.trim ($('input#ws-plugin--s2member-' + button + '-page-style').val ().replace (/"/g, ''));
168
+ var currencyCode = $('select#ws-plugin--s2member-' + button + '-currency').val ().replace (/[^A-Z]/g, '');
169
+ var cCaps = $.trim ($.trim ($('input#ws-plugin--s2member-' + button + '-ccaps').val ()).replace (/[ \-]/g, '_').replace (/[^A-Z_0-9,]/gi, '').toLowerCase ());
170
+ var levelCcaps = (cCaps) ? level + ':' + cCaps : level; /* This is the combination string with custom capabilities attached to the end. */
171
+ trialPeriod = (regTerm === 'L') ? '0' : trialPeriod; /* Lifetime access is NOT compatible w/trials. With lifetime access, the trialPeriod is always 0. */
172
+ /**/
173
+ if (trialTerm === 'D' && trialPeriod > 90) /* Some validation on the trial period. Max days: 90. */
174
+ alert('* WARNING: Maximum Free Days is: 90.\nIf you want to offer more than 90 days free, please choose Weeks or Months from the drop-down.'), trialPeriod = 90;
175
+ else if (trialTerm === 'W' && trialPeriod > 52) /* Some validation on the trial period. 52 max. */
176
+ alert('* WARNING: Maximum Free Weeks is: 52.\nIf you want to offer more than 52 weeks free, please choose Months from the drop-down.'), trialPeriod = 52;
177
+ else if (trialTerm === 'M' && trialPeriod > 24) /* Some validation on the trial period. 24 max. */
178
+ alert('* WARNING: Maximum Free Months is: 24.\nIf you want to offer more than 24 months free, please choose Years from the drop-down.'), trialPeriod = 24;
179
+ else if (trialTerm === 'Y' && trialPeriod > 5) /* 5 years max. */
180
+ alert('* WARNING: Maximum Free Years is: 5.'), trialPeriod = 5;
181
+ /**/
182
+ code.val (code.val ().replace (/ \<\!--(\<input type\="hidden" name\="(amount|src|sra|a1|p1|t1|a3|p3|t3)" value\="(.*?)" \/\>)--\>/g, " $1"));
183
+ (parseInt(trialPeriod) <= 0) ? code.val (code.val ().replace (/ (\<input type\="hidden" name\="(a1|p1|t1)" value\="(.*?)" \/\>)/g, " <!--$1-->")) : null;
184
+ (regTerm === 'L') ? code.val (code.val ().replace (/ (\<input type\="hidden" name\="cmd" value\=")(.*?)(" \/\>)/g, " $1_xclick$3")) : null;
185
+ (regTerm === 'L') ? code.val (code.val ().replace (/ (\<input type\="hidden" name\="(src|sra|a1|p1|t1|a3|p3|t3)" value\="(.*?)" \/\>)/g, " <!--$1-->")) : null;
186
+ (regTerm !== 'L') ? code.val (code.val ().replace (/ (\<input type\="hidden" name\="cmd" value\=")(.*?)(" \/\>)/g, " $1_xclick-subscriptions$3")) : null;
187
+ (regTerm !== 'L') ? code.val (code.val ().replace (/ (\<input type\="hidden" name\="amount" value\="(.*?)" \/\>)/g, " <!--$1-->")) : null;
188
+ /**/
189
+ shortCodeTemplateAttrs += 'level="' + level + '" ccaps="' + cCaps + '" desc="' + label + '" ps="' + pageStyle + '" cc="' + currencyCode + '" custom="<?php echo $_SERVER["HTTP_HOST"]; ?>"';
190
+ shortCodeTemplateAttrs += ' tp="' + trialPeriod + '" tt="' + trialTerm + '" ra="' + regAmount + '" rp="' + regPeriod + '" rt="' + regTerm + '" rr="' + regRecur + '"';
191
+ shortCodeTemplateAttrs += (button === 'modification') ? ' mb="1"' : ''; /* For modification buttons. */
192
+ shortCode.val (shortCodeTemplate.replace (/%%attrs%%/, shortCodeTemplateAttrs));
193
+ /**/
194
+ code.val (code.val ().replace (/ name\="item_name" value\="(.*?)"/, ' name="item_name" value="' + label + '"'));
195
+ code.val (code.val ().replace (/ name\="item_number" value\="(.*?)"/, ' name="item_number" value="' + levelCcaps + '"'));
196
+ code.val (code.val ().replace (/ name\="page_style" value\="(.*?)"/, ' name="page_style" value="' + pageStyle + '"'));
197
+ code.val (code.val ().replace (/ name\="currency_code" value\="(.*?)"/, ' name="currency_code" value="' + currencyCode + '"'));
198
+ code.val (code.val ().replace (/ name\="custom" value\="(.*?)"/, ' name="custom" value="<?php echo $_SERVER["HTTP_HOST"]; ?>"'));
199
+ code.val (code.val ().replace (/ name\="amount" value\="(.*?)"/, ' name="amount" value="' + regAmount + '"'));
200
+ code.val (code.val ().replace (/ name\="src" value\="(.*?)"/, ' name="src" value="' + regRecur + '"'));
201
+ code.val (code.val ().replace (/ name\="p1" value\="(.*?)"/, ' name="p1" value="' + trialPeriod + '"'));
202
+ code.val (code.val ().replace (/ name\="t1" value\="(.*?)"/, ' name="t1" value="' + trialTerm + '"'));
203
+ code.val (code.val ().replace (/ name\="a3" value\="(.*?)"/, ' name="a3" value="' + regAmount + '"'));
204
+ code.val (code.val ().replace (/ name\="p3" value\="(.*?)"/, ' name="p3" value="' + regPeriod + '"'));
205
+ code.val (code.val ().replace (/ name\="t3" value\="(.*?)"/, ' name="t3" value="' + regTerm + '"'));
206
+ /**/
207
+ $('div#ws-plugin--s2member-' + button + '-button-prev').html (code.val ().replace (/\<form/, '<form target="_blank"').replace (/\<\?php echo S2MEMBER_CURRENT_USER_VALUE_FOR_PP_(ON0|OS0); \?\>/, ''));
208
+ /**/
209
+ if (button === 'modification')
210
+ alert('Your Modification Button has been generated.\nPlease copy/paste the Shortcode Format into your Login Welcome Page, or wherever you feel it would be most appropriate.');
211
+ else
212
+ alert('Your Codes for Membership Level #' + level + ' have been generated. Please copy/paste the Shortcode Format into your Membership Options Page.');
213
+ /**/
214
+ shortCode.each (function() /* Focus and select the recommended Shortcode. */
215
+ {
216
+ this.focus (), this.select ();
217
+ });
218
+ /**/
219
+ return false;
220
+ };
221
  /**/
222
+ ws_plugin__s2member_paypalSpButtonGenerate = function() /* Handles PayPal® Button Generation for Single-Page access. */
223
  {
224
+ var shortCodeTemplate = '[s2Member-PayPal-Button %%attrs%% /]', shortCodeTemplateAttrs = '';
225
+ /**/
226
+ var shortCode = $('input#ws-plugin--s2member-sp-shortcode');
227
+ var code = $('textarea#ws-plugin--s2member-sp-button');
228
+ /**/
229
+ var page = $('select#ws-plugin--s2member-sp-page').val ().replace (/[^0-9]/g, '');
230
+ var desc = $.trim ($('input#ws-plugin--s2member-sp-desc').val ().replace (/"/g, ''));
231
+ /**/
232
+ if (!page) /* Must have a Page ID to work with. Otherwise, the purchase would fail. */
233
+ {
234
+ alert('Please select a Page from the drop-down.\n\nIf there are no Pages in the drop-down menu, it\'s because you\'ve not configured s2Member for Single-Page Access yet. See: s2Member -> General Options -> Single-Page Access Restrictions.');
235
+ return false;
236
+ }
237
+ else if (!desc) /* Each Single-Page purchase should have a description. */
238
+ {
239
+ alert('Please type a description for this purchase.');
240
+ return false;
241
+ }
242
+ /**/
243
+ var regAmount = $('input#ws-plugin--s2member-sp-amount').val ().replace (/[^0-9\.]/g, '');
244
+ var pageStyle = $.trim ($('input#ws-plugin--s2member-sp-page-style').val ().replace (/"/g, ''));
245
+ var currencyCode = $('select#ws-plugin--s2member-sp-currency').val ().replace (/[^A-Z]/g, '');
246
+ /**/
247
+ shortCodeTemplateAttrs += 'page="' + page + '" desc="' + desc + '" ps="' + pageStyle + '" cc="' + currencyCode + '"';
248
+ shortCodeTemplateAttrs += ' custom="<?php echo $_SERVER["HTTP_HOST"]; ?>" ra="' + regAmount + '" sp="1"';
249
+ shortCode.val (shortCodeTemplate.replace (/%%attrs%%/, shortCodeTemplateAttrs));
250
+ /**/
251
+ code.val (code.val ().replace (/ name\="item_name" value\="(.*?)"/, ' name="item_name" value="' + desc + '"'));
252
+ code.val (code.val ().replace (/ name\="item_number" value\="(.*?)"/, ' name="item_number" value="sp:' + page + '"'));
253
+ code.val (code.val ().replace (/ name\="page_style" value\="(.*?)"/, ' name="page_style" value="' + pageStyle + '"'));
254
+ code.val (code.val ().replace (/ name\="currency_code" value\="(.*?)"/, ' name="currency_code" value="' + currencyCode + '"'));
255
+ code.val (code.val ().replace (/ name\="custom" value\="(.*?)"/, ' name="custom" value="<?php echo $_SERVER["HTTP_HOST"]; ?>"'));
256
+ code.val (code.val ().replace (/ name\="amount" value\="(.*?)"/, ' name="amount" value="' + regAmount + '"'));
257
+ /**/
258
+ $('div#ws-plugin--s2member-sp-button-prev').html (code.val ().replace (/\<form/, '<form target="_blank"'));
259
+ /**/
260
+ alert('Your Codes have been generated.\nPlease copy/paste the Shortcode Format into your Membership Options Page.');
261
+ /**/
262
+ shortCode.each (function() /* Focus and select the recommended Shortcode. */
263
+ {
264
+ this.focus (), this.select ();
265
+ });
266
+ /**/
267
+ return false;
268
+ };
269
  /**/
270
+ ws_plugin__s2member_paypalSpLinkGenerate = function() /* Handles PayPal® Link Generation for Single-Page access. */
271
+ {
272
+ var page = $('select#ws-plugin--s2member-sp-link-page').val ().replace (/[^0-9]/g, '');
273
+ var $link = $('p#ws-plugin--s2member-sp-link'), $loading = $('img#ws-plugin--s2member-sp-link-loading');
274
+ /**/
275
+ if (!page) /* Must have a Page ID to work with. Otherwise, link generation would fail. */
276
+ {
277
+ alert('Please select a Page from the drop-down.\n\nIf there are no Pages in the drop-down menu, it\'s because you\'ve not configured s2Member for Single-Page Access yet. See: s2Member -> General Options -> Single-Page Access Restrictions.');
278
+ return false;
279
+ }
280
+ /**/
281
+ $link.hide (), $loading.show (), $.post (ajaxurl, {action: 's2member_sp_access_link', s2member_sp_access_link: '<?php echo ws_plugin__s2member_esc_sq (wp_create_nonce ("ws-plugin--s2member-sp-access-link")); ?>', s2member_sp_access_link_page: page}, function(response)
282
+ {
283
+ $link.show ().html ('<a href="' + response + '" target="_blank" rel="xlink">' + response + '</a>'), $loading.hide ();
284
+ });
285
+ /**/
286
+ return false;
287
+ };
288
+ }
289
  });
includes/menu-pages/mod-samps.php DELETED
@@ -1,33 +0,0 @@
1
- <form action="https://www.paypal.com/cgi-bin/webscr" method="post">
2
- <input type="hidden" name="business" value="paypal@example.com">
3
- <input type="hidden" name="cmd" value="_xclick-subscriptions">
4
- <!-- Instant Payment Notification / Return Details -->
5
- <input type="hidden" name="notify_url" value="http://www.example.com/?s2member_paypal_notify=1">
6
- <input type="hidden" name="cancel_return" value="http://www.example.com">
7
- <input type="hidden" name="return" value="http://www.example.com/?s2member_paypal_return=1">
8
- <input type="hidden" name="rm" value="2">
9
- <!-- Identify / Customize The Checkout Fields. -->
10
- <input type="hidden" name="no_shipping" value="1">
11
- <input type="hidden" name="no_note" value="1">
12
- <input type="hidden" name="custom" value="www.example.com">
13
- <input type="hidden" name="currency_code" value="USD">
14
- <input type="hidden" name="page_style" value="paypal">
15
- <input type="hidden" name="item_name" value="Level 2 Upgrade ( $25/mo )">
16
- <input type="hidden" name="item_number" value="2">
17
- <!-- Identify / Update An Existing Member After Checkout. -->
18
- <input type="hidden" name="on0" value="Update Subscription ID">
19
- <input type="hidden" name="os0" value="<?php echo S2MEMBER_CURRENT_USER_SUBSCR_ID; ?>">
20
- <!-- Set The Terms Of The New Subscription. -->
21
- <input type="hidden" name="modify" value="0">
22
- <input type="hidden" name="src" value="1">
23
- <input type="hidden" name="sra" value="1">
24
- <input type="hidden" name="a3" value="25">
25
- <input type="hidden" name="p3" value="1">
26
- <input type="hidden" name="t3" value="M">
27
- <!-- Display The Subscription Button. -->
28
- <input type="image" alt="PayPal®" style="border:0;" src="https://www.paypal.com/en_GB/i/btn/btn_xpressCheckout.gif">
29
- </form>
30
- -------------------------------------------------------------------------------------------------
31
- SO THE RELEVANT SECTION IN THE EXAMPLE GIVEN ABOVE IS:
32
- <input type="hidden" name="on0" value="Update Subscription ID">
33
- <input type="hidden" name="os0" value="<?php echo S2MEMBER_CURRENT_USER_SUBSCR_ID; ?>">
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
includes/menu-pages/options.inc.php CHANGED
@@ -83,7 +83,7 @@ echo '</div>' . "\n";
83
  echo '<div class="ws-menu-page-group" title="Custom Registration Fields">' . "\n";
84
  /**/
85
  echo '<div class="ws-menu-page-section ws-plugin--s2member-custom-reg-fields-section">' . "\n";
86
- echo '<h3>Custom Registration Fields ( optional, for further custmization )</h3>' . "\n";
87
  echo '<p>This is a comma delimited list of additional form fields to collect during registration. By default, all of your Custom Fields will remain optional to the User. That is, the User will NOT be required to enter any of these values. If you want specific fields to be *required*, wrap those Custom Fields inside *asterisks*. Some fields are already built-in by default. The defaults are: <code>*Username*, *Email*, *First Name*, *Last Name*</code>. If you need to add other Custom Fields, in addition to these defaults, you can do that here.</p>' . "\n";
88
  if (defined ("BP_VERSION")) /* Notify the site owner about the conflict with Custom Fields and BuddyPress. */
89
  echo '<p><em class="ws-menu-page-error">* Custom Registration Fields are NOT applicable with BuddyPress. Instead, use <code>BuddyPress -> Profile Field Setup</code>.</em></p>' . "\n";
@@ -138,15 +138,23 @@ echo '<div class="ws-menu-page-group" title="Login/Registration Design">' . "\n"
138
  /**/
139
  echo '<div class="ws-menu-page-section ws-plugin--s2member-login-registration-section">' . "\n";
140
  echo '<h3>Login/Registration Page Customization ( required )</h3>' . "\n";
141
- echo '<p>These settings allow you to customize the user interface for the login / registration pages.</p>' . "\n";
142
  /**/
143
  echo '<table class="form-table">' . "\n";
144
  echo '<tbody>' . "\n";
145
  echo '<tr>' . "\n";
146
  /**/
 
 
 
 
 
 
 
 
147
  echo '<th>' . "\n";
148
  echo '<label for="ws-plugin--s2member-login-reg-background-color">' . "\n";
149
- echo 'Login / Registration Background Color:' . "\n";
150
  echo '</label>' . "\n";
151
  echo '</th>' . "\n";
152
  /**/
@@ -163,7 +171,7 @@ echo '<tr>' . "\n";
163
  /**/
164
  echo '<th>' . "\n";
165
  echo '<label for="ws-plugin--s2member-login-reg-background-image">' . "\n";
166
- echo 'Login / Registration Background Image:' . "\n";
167
  echo '</label>' . "\n";
168
  echo '</th>' . "\n";
169
  /**/
@@ -173,7 +181,8 @@ echo '<tr>' . "\n";
173
  echo '<td>' . "\n";
174
  echo '<input type="text" name="ws_plugin__s2member_login_reg_background_image" id="ws-plugin--s2member-login-reg-background-image" value="' . format_to_edit ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["login_reg_background_image"]) . '" /><br />' . "\n";
175
  echo '<input type="button" id="ws-plugin--s2member-login-reg-background-image-media-btn" value="Open Media Library" class="ws-menu-page-media-btn" rel="ws-plugin--s2member-login-reg-background-image" />' . "\n";
176
- echo 'Set this to the URL of your background image.' . "\n";
 
177
  echo '</td>' . "\n";
178
  /**/
179
  echo '</tr>' . "\n";
@@ -181,7 +190,7 @@ echo '<tr>' . "\n";
181
  /**/
182
  echo '<th>' . "\n";
183
  echo '<label for="ws-plugin--s2member-login-reg-background-text-color">' . "\n";
184
- echo 'Login / Registration Background Text Color:' . "\n";
185
  echo '</label>' . "\n";
186
  echo '</th>' . "\n";
187
  /**/
@@ -198,7 +207,7 @@ echo '<tr>' . "\n";
198
  /**/
199
  echo '<th>' . "\n";
200
  echo '<label for="ws-plugin--s2member-login-reg-background-text-shadow-color">' . "\n";
201
- echo 'Login / Registration Bg Text Shadow Color:' . "\n";
202
  echo '</label>' . "\n";
203
  echo '</th>' . "\n";
204
  /**/
@@ -215,7 +224,7 @@ echo '<tr>' . "\n";
215
  /**/
216
  echo '<th>' . "\n";
217
  echo '<label for="ws-plugin--s2member-login-reg-background-box-shadow-color">' . "\n";
218
- echo 'Login / Registration Bg Box Shadow Color:' . "\n";
219
  echo '</label>' . "\n";
220
  echo '</th>' . "\n";
221
  /**/
@@ -230,9 +239,17 @@ echo '</td>' . "\n";
230
  echo '</tr>' . "\n";
231
  echo '<tr>' . "\n";
232
  /**/
 
 
 
 
 
 
 
 
233
  echo '<th>' . "\n";
234
  echo '<label for="ws-plugin--s2member-login-reg-logo-src">' . "\n";
235
- echo 'Login / Registration Logo Image:' . "\n";
236
  echo '</label>' . "\n";
237
  echo '</th>' . "\n";
238
  /**/
@@ -242,7 +259,8 @@ echo '<tr>' . "\n";
242
  echo '<td>' . "\n";
243
  echo '<input type="text" name="ws_plugin__s2member_login_reg_logo_src" id="ws-plugin--s2member-login-reg-logo-src" value="' . format_to_edit ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["login_reg_logo_src"]) . '" /><br />' . "\n";
244
  echo '<input type="button" id="ws-plugin--s2member-login-reg-logo-src-media-btn" value="Open Media Library" class="ws-menu-page-media-btn" rel="ws-plugin--s2member-login-reg-logo-src" />' . "\n";
245
- echo 'Set this to the URL of your logo image.' . "\n";
 
246
  echo '</td>' . "\n";
247
  /**/
248
  echo '</tr>' . "\n";
@@ -250,7 +268,7 @@ echo '<tr>' . "\n";
250
  /**/
251
  echo '<th>' . "\n";
252
  echo '<label for="ws-plugin--s2member-login-reg-logo-src-width">' . "\n";
253
- echo 'Login / Registration Logo Image Width:' . "\n";
254
  echo '</label>' . "\n";
255
  echo '</th>' . "\n";
256
  /**/
@@ -259,7 +277,7 @@ echo '<tr>' . "\n";
259
  /**/
260
  echo '<td>' . "\n";
261
  echo '<input type="text" name="ws_plugin__s2member_login_reg_logo_src_width" id="ws-plugin--s2member-login-reg-logo-src-width" value="' . format_to_edit ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["login_reg_logo_src_width"]) . '" /><br />' . "\n";
262
- echo 'Set this to pixel width of your logo image. <em>* This also affects the overall width of your login/registration forms. If you want wider form fields, use a wider logo.</em>' . "\n";
263
  echo '</td>' . "\n";
264
  /**/
265
  echo '</tr>' . "\n";
@@ -267,7 +285,7 @@ echo '<tr>' . "\n";
267
  /**/
268
  echo '<th>' . "\n";
269
  echo '<label for="ws-plugin--s2member-login-reg-logo-src-height">' . "\n";
270
- echo 'Login / Registration Logo Image Height:' . "\n";
271
  echo '</label>' . "\n";
272
  echo '</th>' . "\n";
273
  /**/
@@ -276,7 +294,7 @@ echo '<tr>' . "\n";
276
  /**/
277
  echo '<td>' . "\n";
278
  echo '<input type="text" name="ws_plugin__s2member_login_reg_logo_src_height" id="ws-plugin--s2member-login-reg-logo-src-height" value="' . format_to_edit ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["login_reg_logo_src_height"]) . '" /><br />' . "\n";
279
- echo 'Set this to pixel height of your logo image.' . "\n";
280
  echo '</td>' . "\n";
281
  /**/
282
  echo '</tr>' . "\n";
@@ -284,7 +302,7 @@ echo '<tr>' . "\n";
284
  /**/
285
  echo '<th>' . "\n";
286
  echo '<label for="ws-plugin--s2member-login-reg-logo-url">' . "\n";
287
- echo 'Login / Registration Logo Image Click URL:' . "\n";
288
  echo '</label>' . "\n";
289
  echo '</th>' . "\n";
290
  /**/
@@ -293,7 +311,7 @@ echo '<tr>' . "\n";
293
  /**/
294
  echo '<td>' . "\n";
295
  echo '<input type="text" name="ws_plugin__s2member_login_reg_logo_url" id="ws-plugin--s2member-login-reg-logo-url" value="' . format_to_edit ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["login_reg_logo_url"]) . '" /><br />' . "\n";
296
- echo 'Set this to click URL for your logo image.' . "\n";
297
  echo '</td>' . "\n";
298
  /**/
299
  echo '</tr>' . "\n";
@@ -301,7 +319,7 @@ echo '<tr>' . "\n";
301
  /**/
302
  echo '<th>' . "\n";
303
  echo '<label for="ws-plugin--s2member-login-reg-logo-title">' . "\n";
304
- echo 'Login / Registration Logo Image Title:' . "\n";
305
  echo '</label>' . "\n";
306
  echo '</th>' . "\n";
307
  /**/
@@ -310,7 +328,7 @@ echo '<tr>' . "\n";
310
  /**/
311
  echo '<td>' . "\n";
312
  echo '<input type="text" name="ws_plugin__s2member_login_reg_logo_title" id="ws-plugin--s2member-login-reg-logo-title" value="' . format_to_edit ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["login_reg_logo_title"]) . '" /><br />' . "\n";
313
- echo 'Used as the title attribute for your logo image.' . "\n";
314
  echo '</td>' . "\n";
315
  /**/
316
  echo '</tr>' . "\n";
@@ -324,7 +342,7 @@ echo '<div class="ws-menu-page-group" title="Login Welcome Page">' . "\n";
324
  /**/
325
  echo '<div class="ws-menu-page-section ws-plugin--s2member-login-welcome-page-section">' . "\n";
326
  echo '<h3>Login Welcome Page ( required, please customize this )</h3>' . "\n";
327
- echo '<p>Please create and/or choose an existing Page to use as the first page Users will see after logging in.</p>' . "\n";
328
  /**/
329
  echo '<table class="form-table">' . "\n";
330
  echo '<tbody>' . "\n";
@@ -345,7 +363,7 @@ echo '<option value="">&mdash; Select &mdash;</option>' . "\n";
345
  foreach (($ws_plugin__s2member_temp_a = array_merge ((array)get_pages ())) as $ws_plugin__s2member_temp_o)
346
  echo '<option value="' . esc_attr ($ws_plugin__s2member_temp_o->ID) . '"' . ((!$GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["login_redirection_override"] && $ws_plugin__s2member_temp_o->ID == $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["login_welcome_page"]) ? ' selected="selected"' : '') . '>' . esc_html ($ws_plugin__s2member_temp_o->post_title) . '</option>' . "\n";
347
  echo '</select><br />' . "\n";
348
- echo 'Please choose a Page to be used as the first page Users will see after logging in. This Page can contain anything you like. We recommend the following title: <code>Welcome To Our Members Area</code>.<br /><br />' . "\n";
349
  echo '&darr; Or, you may configure a Special Redirection URL, if you prefer. You\'ll need to type in the full URL, starting with: <code>http://</code>' . "\n";
350
  echo '<input type="text" name="ws_plugin__s2member_login_redirection_override" id="ws-plugin--s2member-login-redirection-override" value="' . format_to_edit ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["login_redirection_override"]) . '" /><br />' . "\n";
351
  echo '</td>' . "\n";
@@ -365,9 +383,9 @@ echo '<tr>' . "\n";
365
  echo '<td>' . "\n";
366
  echo '<select name="ws_plugin__s2member_allow_subscribers_in" id="ws-plugin--s2member-allow-subscribers-in">' . "\n";
367
  echo '<option value="0"' . ((!$GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["allow_subscribers_in"]) ? ' selected="selected"' : '') . '>No ( only Members can access their Login Welcome Page )</option>' . "\n";
368
- echo '<option value="1"' . (($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["allow_subscribers_in"]) ? ' selected="selected"' : '') . '>Yes ( if a free Subscriber is logged in, they can also access this Page )</option>' . "\n";
369
  echo '</select><br />' . "\n";
370
- echo 'If you set this to <code>Yes</code>, it means that you\'re giving Free Subscribers the ability to access this special Page that is normally intended only for Members. If you set this to <code>Yes</code>, you\'re also turning on the `Anyone Can Register` option that is built into WordPress®. So what this means, is that you\'re allowing people to signup for free, as a Free Subscriber, who will then have access to the Login Welcome Page, even though they\'re NOT a paid Member. This is only useful if you plan to let Users signup for free ( <a href="' . add_query_arg ("action", "register", wp_login_url ()) . '" target="_blank" rel="xlink">' . esc_html (add_query_arg ("action", "register", wp_login_url ())) . '</a> ). See <code>s2Member->API Scripting->Advanced Conditionals</code>, for details on how to customize your Login Welcome Page with Conditionals; based on Membership Level.' . "\n";
371
  echo '</td>' . "\n";
372
  /**/
373
  echo '</tr>' . "\n";
@@ -381,7 +399,7 @@ echo '<div class="ws-menu-page-group" title="Membership Options Page">' . "\n";
381
  /**/
382
  echo '<div class="ws-menu-page-section ws-plugin--s2member-membership-options-page-section">' . "\n";
383
  echo '<h3>Membership Options Page ( required, please customize this )</h3>' . "\n";
384
- echo '<p>Please create and/or choose an existing Page that showcases your membership subscription options. This special Page is where you will insert the PayPal® Subscription Buttons generated for you by s2Member. This Page serves as your signup page. It should detail all of the features that come with membership to your site, and provide a PayPal® Subscription Button for each level of access you plan to offer. This is also the page that Users will be redirected to, should they attempt to access an area of your site that requires membership.</p>' . "\n";
385
  /**/
386
  echo '<table class="form-table">' . "\n";
387
  echo '<tbody>' . "\n";
@@ -416,8 +434,8 @@ echo '<div class="ws-menu-page-group" title="Membership Levels/Labels">' . "\n";
416
  /**/
417
  echo '<div class="ws-menu-page-section ws-plugin--s2member-membership-levels-section">' . "\n";
418
  echo '<h3>Membership Levels ( required, please customize these )</h3>' . "\n";
419
- echo '<p>The default membership levels are labeled generically; feel free to modify them as needed.</p>' . "\n";
420
- echo '<p>s2Member supports up to 4 different levels of membership. However, you don\'t have to use all of the membership levels if you don\'t want to. To use only 1 or 2 of these levels, just create and/or modify your Membership Options Page, so that it only includes PayPal® Subscription Buttons for the levels you wish to use.</p>' . "\n";
421
  /**/
422
  echo '<table class="form-table">' . "\n";
423
  echo '<tbody>' . "\n";
@@ -434,7 +452,7 @@ echo '<tr>' . "\n";
434
  /**/
435
  echo '<td>' . "\n";
436
  echo '<input type="text" name="ws_plugin__s2member_level1_label" id="ws-plugin--s2member-level1-label" value="' . format_to_edit ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["level1_label"]) . '" /><br />' . "\n";
437
- echo 'This is the label for membership level 1.<br />' . "\n";
438
  echo '</td>' . "\n";
439
  /**/
440
  echo '</tr>' . "\n";
@@ -451,7 +469,7 @@ echo '<tr>' . "\n";
451
  /**/
452
  echo '<td>' . "\n";
453
  echo '<input type="text" name="ws_plugin__s2member_level2_label" id="ws-plugin--s2member-level2-label" value="' . format_to_edit ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["level2_label"]) . '" /><br />' . "\n";
454
- echo 'This is the label for membership level 2.<br />' . "\n";
455
  echo '</td>' . "\n";
456
  /**/
457
  echo '</tr>' . "\n";
@@ -468,7 +486,7 @@ echo '<tr>' . "\n";
468
  /**/
469
  echo '<td>' . "\n";
470
  echo '<input type="text" name="ws_plugin__s2member_level3_label" id="ws-plugin--s2member-level3-label" value="' . format_to_edit ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["level3_label"]) . '" /><br />' . "\n";
471
- echo 'This is the label for membership level 3.<br />' . "\n";
472
  echo '</td>' . "\n";
473
  /**/
474
  echo '</tr>' . "\n";
@@ -485,7 +503,7 @@ echo '<tr>' . "\n";
485
  /**/
486
  echo '<td>' . "\n";
487
  echo '<input type="text" name="ws_plugin__s2member_level4_label" id="ws-plugin--s2member-level4-label" value="' . format_to_edit ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["level4_label"]) . '" /><br />' . "\n";
488
- echo 'This is the label for membership level 4.<br />' . "\n";
489
  echo '</td>' . "\n";
490
  /**/
491
  echo '</tr>' . "\n";
@@ -499,7 +517,7 @@ echo '<div class="ws-menu-page-group" title="Post Access Restrictions">' . "\n";
499
  /**/
500
  echo '<div class="ws-menu-page-section ws-plugin--s2member-post-level-access-section">' . "\n";
501
  echo '<h3>Post Level Access Restrictions ( optional )</h3>' . "\n";
502
- echo '<p>Here you can specify posts that are restricted to certain membership access levels.</p>' . "\n";
503
  /**/
504
  echo '<table class="form-table">' . "\n";
505
  echo '<tbody>' . "\n";
@@ -581,7 +599,7 @@ echo '<div class="ws-menu-page-group" title="Page Access Restrictions">' . "\n";
581
  /**/
582
  echo '<div class="ws-menu-page-section ws-plugin--s2member-page-level-access-section">' . "\n";
583
  echo '<h3>Page Level Access Restrictions ( optional )</h3>' . "\n";
584
- echo '<p>Here you can specify Pages that are restricted to certain membership access levels.</p>' . "\n";
585
  /**/
586
  echo '<table class="form-table">' . "\n";
587
  echo '<tbody>' . "\n";
@@ -663,7 +681,7 @@ echo '<div class="ws-menu-page-group" title="Tag Access Restrictions">' . "\n";
663
  /**/
664
  echo '<div class="ws-menu-page-section ws-plugin--s2member-tag-level-access-section">' . "\n";
665
  echo '<h3>Tag Level Access Restrictions ( optional )</h3>' . "\n";
666
- echo '<p>Here you can specify tags that are restricted to certain membership access levels. Tag restrictions are a bit more complex. When you restrict access to a tag, it also restricts access to any posts that may have the tag. In other words, restricting a tag protects that tag archive, and it also protects any posts that have the tag; even if they have other tags.</p>' . "\n";
667
  /**/
668
  echo '<table class="form-table">' . "\n";
669
  echo '<tbody>' . "\n";
@@ -745,7 +763,7 @@ echo '<div class="ws-menu-page-group" title="Category Access Restrictions">' . "
745
  /**/
746
  echo '<div class="ws-menu-page-section ws-plugin--s2member-category-level-access-section">' . "\n";
747
  echo '<h3>Category Level Access Restrictions ( optional )</h3>' . "\n";
748
- echo '<p>Here you can specify categories that are restricted to certain membership access levels. Category restrictions are a bit more complex. When you restrict access to a category, it also restricts access to any child categories it may have ( aka: sub-categories ). In other words, restricting a category protects that category archive, all of its child category archives, and any posts contained within the category or its child categories.</p>' . "\n";
749
  /**/
750
  echo '<table class="form-table">' . "\n";
751
  echo '<tbody>' . "\n";
@@ -827,7 +845,8 @@ echo '<div class="ws-menu-page-group" title="URI Access Restrictions">' . "\n";
827
  /**/
828
  echo '<div class="ws-menu-page-section ws-plugin--s2member-uri-level-access-section">' . "\n";
829
  echo '<h3>URI Level Access Restrictions ( optional )</h3>' . "\n";
830
- echo '<p>Here you can specify URIs ( or word fragments found in URIs ) that are restricted to certain membership access levels. The control over URIs is complex. This section is intended for advanced webmasters only. That being said, here are the basics... A REQUEST_URI, is the portion of the URL that comes after the domain. This is a URL <code>http://www.example.com/path/to/file.php</code>, and this is the URI: <code>/path/to/file.php</code>. In the fields below, you can provide a list ( one per line ) of URIs on your site that should be off-limits based on membership level. You can also use word fragments instead of a full URI. If a word fragment is found anywhere in the URI, it will be protected. Wildcards and other regex patterns are not supported here and therefore you don\'t need to escape special characters or anything. Please note, these ARE caSe sensitive. You must be specific with respect to case sensitivity. The word fragment <code>some-path/</code> would NOT match a URI that contains <code>some-Path/</code>.</p>' . "\n";
 
831
  /**/
832
  echo '<table class="form-table">' . "\n";
833
  echo '<tbody>' . "\n";
@@ -843,7 +862,7 @@ echo '</tr>' . "\n";
843
  echo '<tr>' . "\n";
844
  /**/
845
  echo '<td>' . "\n";
846
- echo '<textarea name="ws_plugin__s2member_level1_ruris" id="ws-plugin--s2member-level1-ruris" rows="3" wrap="off">' . format_to_edit ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["level1_ruris"]) . '</textarea><br />' . "\n";
847
  echo 'URIs and/or word fragments found in URIs. One per line please.' . "\n";
848
  echo '</td>' . "\n";
849
  /**/
@@ -860,7 +879,7 @@ echo '</tr>' . "\n";
860
  echo '<tr>' . "\n";
861
  /**/
862
  echo '<td>' . "\n";
863
- echo '<textarea name="ws_plugin__s2member_level2_ruris" id="ws-plugin--s2member-level2-ruris" rows="3" wrap="off">' . format_to_edit ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["level2_ruris"]) . '</textarea><br />' . "\n";
864
  echo 'URIs and/or word fragments found in URIs. One per line please.' . "\n";
865
  echo '</td>' . "\n";
866
  /**/
@@ -877,7 +896,7 @@ echo '</tr>' . "\n";
877
  echo '<tr>' . "\n";
878
  /**/
879
  echo '<td>' . "\n";
880
- echo '<textarea name="ws_plugin__s2member_level3_ruris" id="ws-plugin--s2member-level3-ruris" rows="3" wrap="off">' . format_to_edit ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["level3_ruris"]) . '</textarea><br />' . "\n";
881
  echo 'URIs and/or word fragments found in URIs. One per line please.' . "\n";
882
  echo '</td>' . "\n";
883
  /**/
@@ -894,7 +913,7 @@ echo '</tr>' . "\n";
894
  echo '<tr>' . "\n";
895
  /**/
896
  echo '<td>' . "\n";
897
- echo '<textarea name="ws_plugin__s2member_level4_ruris" id="ws-plugin--s2member-level4-ruris" rows="3" wrap="off">' . format_to_edit ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["level4_ruris"]) . '</textarea><br />' . "\n";
898
  echo 'URIs and/or word fragments found in URIs. One per line please.' . "\n";
899
  echo '</td>' . "\n";
900
  /**/
@@ -905,6 +924,90 @@ echo '</div>' . "\n";
905
  /**/
906
  echo '</div>' . "\n";
907
  /**/
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
908
  echo '<div class="ws-menu-page-group" title="De-Activation Safeguards">' . "\n";
909
  /**/
910
  echo '<div class="ws-menu-page-section ws-plugin--s2member-deactivation-section">' . "\n";
@@ -948,6 +1051,8 @@ echo '</td>' . "\n";
948
  /**/
949
  echo '<td class="ws-menu-page-table-r">' . "\n";
950
  /**/
 
 
951
  echo ($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["menu-r"]["tools"]) ? '<div class="ws-menu-page-tools"><img src="' . $GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["dir_url"] . '/images/brand-tools.png" alt="." /></div>' . "\n" : '';
952
  /**/
953
  echo ($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["menu-r"]["tips"]) ? '<div class="ws-menu-page-tips"><a href="' . ws_plugin__s2member_parse_readme_value ("Customization URI") . '"><img src="' . $GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["dir_url"] . '/images/brand-tips.png" alt="." /></a></div>' . "\n" : '';
83
  echo '<div class="ws-menu-page-group" title="Custom Registration Fields">' . "\n";
84
  /**/
85
  echo '<div class="ws-menu-page-section ws-plugin--s2member-custom-reg-fields-section">' . "\n";
86
+ echo '<h3>Custom Registration Fields ( optional, for further customization )</h3>' . "\n";
87
  echo '<p>This is a comma delimited list of additional form fields to collect during registration. By default, all of your Custom Fields will remain optional to the User. That is, the User will NOT be required to enter any of these values. If you want specific fields to be *required*, wrap those Custom Fields inside *asterisks*. Some fields are already built-in by default. The defaults are: <code>*Username*, *Email*, *First Name*, *Last Name*</code>. If you need to add other Custom Fields, in addition to these defaults, you can do that here.</p>' . "\n";
88
  if (defined ("BP_VERSION")) /* Notify the site owner about the conflict with Custom Fields and BuddyPress. */
89
  echo '<p><em class="ws-menu-page-error">* Custom Registration Fields are NOT applicable with BuddyPress. Instead, use <code>BuddyPress -> Profile Field Setup</code>.</em></p>' . "\n";
138
  /**/
139
  echo '<div class="ws-menu-page-section ws-plugin--s2member-login-registration-section">' . "\n";
140
  echo '<h3>Login/Registration Page Customization ( required )</h3>' . "\n";
141
+ echo '<p>These settings allow you to customize the user interface for your Login / Registration Pages:<br />( <a href="' . wp_login_url () . '" target="_blank" rel="xlink">' . esc_html (wp_login_url ()) . '</a> )</p>' . "\n";
142
  /**/
143
  echo '<table class="form-table">' . "\n";
144
  echo '<tbody>' . "\n";
145
  echo '<tr>' . "\n";
146
  /**/
147
+ echo '<td>' . "\n";
148
+ echo '<h3>Background Settings</h3>' . "\n";
149
+ echo '<p>These settings are all focused on your Login/Registration Background.</p>' . "\n";
150
+ echo '</td>' . "\n";
151
+ /**/
152
+ echo '</tr>' . "\n";
153
+ echo '<tr>' . "\n";
154
+ /**/
155
  echo '<th>' . "\n";
156
  echo '<label for="ws-plugin--s2member-login-reg-background-color">' . "\n";
157
+ echo 'Background Color:' . "\n";
158
  echo '</label>' . "\n";
159
  echo '</th>' . "\n";
160
  /**/
171
  /**/
172
  echo '<th>' . "\n";
173
  echo '<label for="ws-plugin--s2member-login-reg-background-image">' . "\n";
174
+ echo 'Seamless Tile Background Image:' . "\n";
175
  echo '</label>' . "\n";
176
  echo '</th>' . "\n";
177
  /**/
181
  echo '<td>' . "\n";
182
  echo '<input type="text" name="ws_plugin__s2member_login_reg_background_image" id="ws-plugin--s2member-login-reg-background-image" value="' . format_to_edit ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["login_reg_background_image"]) . '" /><br />' . "\n";
183
  echo '<input type="button" id="ws-plugin--s2member-login-reg-background-image-media-btn" value="Open Media Library" class="ws-menu-page-media-btn" rel="ws-plugin--s2member-login-reg-background-image" />' . "\n";
184
+ echo 'Set this to the URL of your Background Image. ( this is optional )<br />';
185
+ echo 'If supplied, your Background Image will be tiled.' . "\n";
186
  echo '</td>' . "\n";
187
  /**/
188
  echo '</tr>' . "\n";
190
  /**/
191
  echo '<th>' . "\n";
192
  echo '<label for="ws-plugin--s2member-login-reg-background-text-color">' . "\n";
193
+ echo 'Color of Text on top of your Background:' . "\n";
194
  echo '</label>' . "\n";
195
  echo '</th>' . "\n";
196
  /**/
207
  /**/
208
  echo '<th>' . "\n";
209
  echo '<label for="ws-plugin--s2member-login-reg-background-text-shadow-color">' . "\n";
210
+ echo 'Shadow Color for Text on top of your Background:' . "\n";
211
  echo '</label>' . "\n";
212
  echo '</th>' . "\n";
213
  /**/
224
  /**/
225
  echo '<th>' . "\n";
226
  echo '<label for="ws-plugin--s2member-login-reg-background-box-shadow-color">' . "\n";
227
+ echo 'Shadow Color for Boxes on top of your Background:' . "\n";
228
  echo '</label>' . "\n";
229
  echo '</th>' . "\n";
230
  /**/
239
  echo '</tr>' . "\n";
240
  echo '<tr>' . "\n";
241
  /**/
242
+ echo '<td>' . "\n";
243
+ echo '<h3>Logo Image Settings</h3>' . "\n";
244
+ echo '<p>These settings are all focused on your Login/Registration Logo.</p>' . "\n";
245
+ echo '</td>' . "\n";
246
+ /**/
247
+ echo '</tr>' . "\n";
248
+ echo '<tr>' . "\n";
249
+ /**/
250
  echo '<th>' . "\n";
251
  echo '<label for="ws-plugin--s2member-login-reg-logo-src">' . "\n";
252
+ echo 'Logo Image Location:' . "\n";
253
  echo '</label>' . "\n";
254
  echo '</th>' . "\n";
255
  /**/
259
  echo '<td>' . "\n";
260
  echo '<input type="text" name="ws_plugin__s2member_login_reg_logo_src" id="ws-plugin--s2member-login-reg-logo-src" value="' . format_to_edit ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["login_reg_logo_src"]) . '" /><br />' . "\n";
261
  echo '<input type="button" id="ws-plugin--s2member-login-reg-logo-src-media-btn" value="Open Media Library" class="ws-menu-page-media-btn" rel="ws-plugin--s2member-login-reg-logo-src" />' . "\n";
262
+ echo 'Set this to the URL of your Logo Image.<br />' . "\n";
263
+ echo 'Suggested size is around 500 x 100.' . "\n";
264
  echo '</td>' . "\n";
265
  /**/
266
  echo '</tr>' . "\n";
268
  /**/
269
  echo '<th>' . "\n";
270
  echo '<label for="ws-plugin--s2member-login-reg-logo-src-width">' . "\n";
271
+ echo 'Logo Image Width:' . "\n";
272
  echo '</label>' . "\n";
273
  echo '</th>' . "\n";
274
  /**/
277
  /**/
278
  echo '<td>' . "\n";
279
  echo '<input type="text" name="ws_plugin__s2member_login_reg_logo_src_width" id="ws-plugin--s2member-login-reg-logo-src-width" value="' . format_to_edit ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["login_reg_logo_src_width"]) . '" /><br />' . "\n";
280
+ echo 'The pixel Width of your Logo Image. <em>* This ALSO affects the overall width of your Login/Registration forms. If you want wider form fields, use a wider Logo.</em>' . "\n";
281
  echo '</td>' . "\n";
282
  /**/
283
  echo '</tr>' . "\n";
285
  /**/
286
  echo '<th>' . "\n";
287
  echo '<label for="ws-plugin--s2member-login-reg-logo-src-height">' . "\n";
288
+ echo 'Logo Image Height:' . "\n";
289
  echo '</label>' . "\n";
290
  echo '</th>' . "\n";
291
  /**/
294
  /**/
295
  echo '<td>' . "\n";
296
  echo '<input type="text" name="ws_plugin__s2member_login_reg_logo_src_height" id="ws-plugin--s2member-login-reg-logo-src-height" value="' . format_to_edit ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["login_reg_logo_src_height"]) . '" /><br />' . "\n";
297
+ echo 'The pixel Height of your Logo Image.' . "\n";
298
  echo '</td>' . "\n";
299
  /**/
300
  echo '</tr>' . "\n";
302
  /**/
303
  echo '<th>' . "\n";
304
  echo '<label for="ws-plugin--s2member-login-reg-logo-url">' . "\n";
305
+ echo 'Logo Image Click URL:' . "\n";
306
  echo '</label>' . "\n";
307
  echo '</th>' . "\n";
308
  /**/
311
  /**/
312
  echo '<td>' . "\n";
313
  echo '<input type="text" name="ws_plugin__s2member_login_reg_logo_url" id="ws-plugin--s2member-login-reg-logo-url" value="' . format_to_edit ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["login_reg_logo_url"]) . '" /><br />' . "\n";
314
+ echo 'Set this to the Click URL for your Logo Image.' . "\n";
315
  echo '</td>' . "\n";
316
  /**/
317
  echo '</tr>' . "\n";
319
  /**/
320
  echo '<th>' . "\n";
321
  echo '<label for="ws-plugin--s2member-login-reg-logo-title">' . "\n";
322
+ echo 'Logo Image Title Attribute:' . "\n";
323
  echo '</label>' . "\n";
324
  echo '</th>' . "\n";
325
  /**/
328
  /**/
329
  echo '<td>' . "\n";
330
  echo '<input type="text" name="ws_plugin__s2member_login_reg_logo_title" id="ws-plugin--s2member-login-reg-logo-title" value="' . format_to_edit ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["login_reg_logo_title"]) . '" /><br />' . "\n";
331
+ echo 'Used as the <code>title=""</code> attribute for your Logo Image.' . "\n";
332
  echo '</td>' . "\n";
333
  /**/
334
  echo '</tr>' . "\n";
342
  /**/
343
  echo '<div class="ws-menu-page-section ws-plugin--s2member-login-welcome-page-section">' . "\n";
344
  echo '<h3>Login Welcome Page ( required, please customize this )</h3>' . "\n";
345
+ echo '<p>Please create and/or choose an existing Page to use as the first page Members will see after logging in.</p>' . "\n";
346
  /**/
347
  echo '<table class="form-table">' . "\n";
348
  echo '<tbody>' . "\n";
363
  foreach (($ws_plugin__s2member_temp_a = array_merge ((array)get_pages ())) as $ws_plugin__s2member_temp_o)
364
  echo '<option value="' . esc_attr ($ws_plugin__s2member_temp_o->ID) . '"' . ((!$GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["login_redirection_override"] && $ws_plugin__s2member_temp_o->ID == $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["login_welcome_page"]) ? ' selected="selected"' : '') . '>' . esc_html ($ws_plugin__s2member_temp_o->post_title) . '</option>' . "\n";
365
  echo '</select><br />' . "\n";
366
+ echo 'Please choose a Page to be used as the first page Members will see after logging in. This Page can contain anything you like. We recommend the following title: <code>Welcome To Our Members Area</code>.<br /><br />' . "\n";
367
  echo '&darr; Or, you may configure a Special Redirection URL, if you prefer. You\'ll need to type in the full URL, starting with: <code>http://</code>' . "\n";
368
  echo '<input type="text" name="ws_plugin__s2member_login_redirection_override" id="ws-plugin--s2member-login-redirection-override" value="' . format_to_edit ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["login_redirection_override"]) . '" /><br />' . "\n";
369
  echo '</td>' . "\n";
383
  echo '<td>' . "\n";
384
  echo '<select name="ws_plugin__s2member_allow_subscribers_in" id="ws-plugin--s2member-allow-subscribers-in">' . "\n";
385
  echo '<option value="0"' . ((!$GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["allow_subscribers_in"]) ? ' selected="selected"' : '') . '>No ( only Members can access their Login Welcome Page )</option>' . "\n";
386
+ echo '<option value="1"' . (($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["allow_subscribers_in"]) ? ' selected="selected"' : '') . '>Yes ( if a Free Subscriber is logged in, they can also access this Page )</option>' . "\n";
387
  echo '</select><br />' . "\n";
388
+ echo 'If you set this to <code>Yes</code>, it means that you\'re giving Free Subscribers the ability to access this special Page that is normally intended only for Members. If you set this to <code>Yes</code>, you\'re also turning on the `Anyone Can Register` option that is built into WordPress®. So what this means, is that you\'re allowing people to signup for free, as a Free Subscriber, who will then have access to the Login Welcome Page, even though they\'re NOT a paid Member. This is only useful if you plan to let Users signup for free ( <a href="' . add_query_arg ("action", "register", wp_login_url ()) . '" target="_blank" rel="xlink">' . esc_html (add_query_arg ("action", "register", wp_login_url ())) . '</a> ). See <code>s2Member -> API Scripting -> Advanced Conditionals</code>, for details on how to customize your Login Welcome Page with Conditionals; based on Membership Level.' . "\n";
389
  echo '</td>' . "\n";
390
  /**/
391
  echo '</tr>' . "\n";
399
  /**/
400
  echo '<div class="ws-menu-page-section ws-plugin--s2member-membership-options-page-section">' . "\n";
401
  echo '<h3>Membership Options Page ( required, please customize this )</h3>' . "\n";
402
+ echo '<p>Please create and/or choose an existing Page that showcases your membership subscription options. This special Page is where you will insert the PayPal® Subscription Buttons generated for you by s2Member. This Page serves as your signup page. It should detail all of the features that come with membership to your site, and provide a PayPal® Subscription Button for each Level of access you plan to offer. This is also the page that Users will be redirected to, should they attempt to access an area of your site that requires membership.</p>' . "\n";
403
  /**/
404
  echo '<table class="form-table">' . "\n";
405
  echo '<tbody>' . "\n";
434
  /**/
435
  echo '<div class="ws-menu-page-section ws-plugin--s2member-membership-levels-section">' . "\n";
436
  echo '<h3>Membership Levels ( required, please customize these )</h3>' . "\n";
437
+ echo '<p>The default Membership Levels are labeled generically; feel free to modify them as needed. s2Member supports up to 4 Primary Levels of membership, and unlimited Custom Capabilities. However, you don\'t have to use all of the Membership Levels if you don\'t want to. To use only 1 or 2 of these Levels, just create and/or modify your Membership Options Page, so that it only includes PayPal® Subscription Buttons for the Levels you wish to use.</p>' . "\n";
438
+ echo '<p><em>Support for Custom Capabilities is available. If you\'re an advanced site owner, a theme designer, or a web developer integrating s2Member for a client, please see: <code>s2Member -> API Scripting -> Custom Capabilities</code></em></p>' . "\n";
439
  /**/
440
  echo '<table class="form-table">' . "\n";
441
  echo '<tbody>' . "\n";
452
  /**/
453
  echo '<td>' . "\n";
454
  echo '<input type="text" name="ws_plugin__s2member_level1_label" id="ws-plugin--s2member-level1-label" value="' . format_to_edit ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["level1_label"]) . '" /><br />' . "\n";
455
+ echo 'This is the Label for Membership Level 1.<br />' . "\n";
456
  echo '</td>' . "\n";
457
  /**/
458
  echo '</tr>' . "\n";
469
  /**/
470
  echo '<td>' . "\n";
471
  echo '<input type="text" name="ws_plugin__s2member_level2_label" id="ws-plugin--s2member-level2-label" value="' . format_to_edit ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["level2_label"]) . '" /><br />' . "\n";
472
+ echo 'This is the Label for Membership Level 2.<br />' . "\n";
473
  echo '</td>' . "\n";
474
  /**/
475
  echo '</tr>' . "\n";
486
  /**/
487
  echo '<td>' . "\n";
488
  echo '<input type="text" name="ws_plugin__s2member_level3_label" id="ws-plugin--s2member-level3-label" value="' . format_to_edit ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["level3_label"]) . '" /><br />' . "\n";
489
+ echo 'This is the Label for Membership Level 3.<br />' . "\n";
490
  echo '</td>' . "\n";
491
  /**/
492
  echo '</tr>' . "\n";
503
  /**/
504
  echo '<td>' . "\n";
505
  echo '<input type="text" name="ws_plugin__s2member_level4_label" id="ws-plugin--s2member-level4-label" value="' . format_to_edit ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["level4_label"]) . '" /><br />' . "\n";
506
+ echo 'This is the Label for Membership Level 4.<br />' . "\n";
507
  echo '</td>' . "\n";
508
  /**/
509
  echo '</tr>' . "\n";
517
  /**/
518
  echo '<div class="ws-menu-page-section ws-plugin--s2member-post-level-access-section">' . "\n";
519
  echo '<h3>Post Level Access Restrictions ( optional )</h3>' . "\n";
520
+ echo '<p>Here you can specify Posts that are restricted to certain Membership Access Levels.</p>' . "\n";
521
  /**/
522
  echo '<table class="form-table">' . "\n";
523
  echo '<tbody>' . "\n";
599
  /**/
600
  echo '<div class="ws-menu-page-section ws-plugin--s2member-page-level-access-section">' . "\n";
601
  echo '<h3>Page Level Access Restrictions ( optional )</h3>' . "\n";
602
+ echo '<p>Here you can specify Pages that are restricted to certain Membership Access Levels.</p>' . "\n";
603
  /**/
604
  echo '<table class="form-table">' . "\n";
605
  echo '<tbody>' . "\n";
681
  /**/
682
  echo '<div class="ws-menu-page-section ws-plugin--s2member-tag-level-access-section">' . "\n";
683
  echo '<h3>Tag Level Access Restrictions ( optional )</h3>' . "\n";
684
+ echo '<p>Here you can specify Tags that are restricted to certain Membership Access Levels. Tag restrictions are a bit more complex. When you restrict access to a Tag, it also restricts access to any Posts that may have the Tag. In other words, restricting a Tag protects that Tag Archive, and it also protects any Posts that have the Tag; even if they have other Tags.</p>' . "\n";
685
  /**/
686
  echo '<table class="form-table">' . "\n";
687
  echo '<tbody>' . "\n";
763
  /**/
764
  echo '<div class="ws-menu-page-section ws-plugin--s2member-category-level-access-section">' . "\n";
765
  echo '<h3>Category Level Access Restrictions ( optional )</h3>' . "\n";
766
+ echo '<p>Here you can specify Categories that are restricted to certain Membership Access Levels. Category restrictions are a bit more complex. When you restrict access to a Category, it also restricts access to any child Categories it may have ( aka: sub-Categories ). In other words, restricting a Category protects that Category Archive, all of its child Category Archives, and any Posts contained within the Category, or its child Categories.</p>' . "\n";
767
  /**/
768
  echo '<table class="form-table">' . "\n";
769
  echo '<tbody>' . "\n";
845
  /**/
846
  echo '<div class="ws-menu-page-section ws-plugin--s2member-uri-level-access-section">' . "\n";
847
  echo '<h3>URI Level Access Restrictions ( optional )</h3>' . "\n";
848
+ echo '<p>Here you can specify URIs ( or word fragments found in URIs ) that are restricted to certain Membership Access Levels. Control over URIs is a little more complex. This section is intended for advanced webmasters only. That being said, here are the basics... A REQUEST_URI, is the portion of the URL that comes after the domain. This is a URL <code>http://www.example.com/path/to/file.php</code>, and this is the URI: <code>/path/to/file.php</code>.</p>' . "\n";
849
+ echo '<p>In the fields below, you can provide a list ( one per line ) of URIs on your site that should be off-limits based on Membership Level. You can also use word fragments instead of a full URI. If a word fragment is found anywhere in the URI, it will be protected. Wildcards and other regex patterns are not supported here, and therefore you don\'t need to escape special characters or anything. Please note, these ARE caSe sensitive. You must be specific with respect to case sensitivity. The word fragment <code>some-path/</code> would NOT match a URI that contains <code>some-Path/</code>.</p>' . "\n";
850
  /**/
851
  echo '<table class="form-table">' . "\n";
852
  echo '<tbody>' . "\n";
862
  echo '<tr>' . "\n";
863
  /**/
864
  echo '<td>' . "\n";
865
+ echo '<textarea name="ws_plugin__s2member_level1_ruris" id="ws-plugin--s2member-level1-ruris" rows="3" wrap="off" spellcheck="false">' . format_to_edit ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["level1_ruris"]) . '</textarea><br />' . "\n";
866
  echo 'URIs and/or word fragments found in URIs. One per line please.' . "\n";
867
  echo '</td>' . "\n";
868
  /**/
879
  echo '<tr>' . "\n";
880
  /**/
881
  echo '<td>' . "\n";
882
+ echo '<textarea name="ws_plugin__s2member_level2_ruris" id="ws-plugin--s2member-level2-ruris" rows="3" wrap="off" spellcheck="false">' . format_to_edit ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["level2_ruris"]) . '</textarea><br />' . "\n";
883
  echo 'URIs and/or word fragments found in URIs. One per line please.' . "\n";
884
  echo '</td>' . "\n";
885
  /**/
896
  echo '<tr>' . "\n";
897
  /**/
898
  echo '<td>' . "\n";
899
+ echo '<textarea name="ws_plugin__s2member_level3_ruris" id="ws-plugin--s2member-level3-ruris" rows="3" wrap="off" spellcheck="false">' . format_to_edit ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["level3_ruris"]) . '</textarea><br />' . "\n";
900
  echo 'URIs and/or word fragments found in URIs. One per line please.' . "\n";
901
  echo '</td>' . "\n";
902
  /**/
913
  echo '<tr>' . "\n";
914
  /**/
915
  echo '<td>' . "\n";
916
+ echo '<textarea name="ws_plugin__s2member_level4_ruris" id="ws-plugin--s2member-level4-ruris" rows="3" wrap="off" spellcheck="false">' . format_to_edit ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["level4_ruris"]) . '</textarea><br />' . "\n";
917
  echo 'URIs and/or word fragments found in URIs. One per line please.' . "\n";
918
  echo '</td>' . "\n";
919
  /**/
924
  /**/
925
  echo '</div>' . "\n";
926
  /**/
927
+ echo '<div class="ws-menu-page-group" title="Single-Page Access Restrictions">' . "\n";
928
+ /**/
929
+ echo '<div class="ws-menu-page-section ws-plugin--s2member-spage-access-section">' . "\n";
930
+ echo '<h3>Single-Page Access Restrictions ( optional )</h3>' . "\n";
931
+ echo '<p>s2Member now supports an additional layer of functionality ( very powerful ), which allows you to sell access to specific Pages that you\'ve created in WordPress®. Single-Page Access works independently from Member Level Access. That is, you can sell an unlimited number of Pages using "Buy Now" Buttons, and your Customers will NOT be required to have a Membership Account with your site in order to receive access. If they are already a Member, that\'s fine, but they won\'t need to be. In other words, Customers will NOT need to login, just to receive access to the Single-Page they purchased access to. s2Member will immediately redirect the Customer to the Single-Page after checkout is completed successfully. An email is also sent to the Customer with a link ( see: <code>s2Member -> PayPal® Options -> Single-Page Email</code> ). Authentication is handled automatically through IP tracking and Cookies.</p>' . "\n";
932
+ echo '<p>Single-Page Access, is sort of like selling a product. Only, instead of shipping anything to the Customer, you just give them access to a specific Page on your site; one that you created in WordPress®. A Single-Page that is protected by s2Member, might contain a download link for your eBook, access to file &amp; music downloads, access to additional support services, and the list goes on and on. The possibilities with this are endless; as long as your digital product can be delivered through access to a WordPress® Page that you\'ve created.</p>' . "\n";
933
+ echo '<p>Very simple. All you do is protect the Single-Page IDs that are being sold on your site. Then, you can go to <code>s2Member -> PayPal® Buttons -> Single-Page</code> to generate "Buy Now" Buttons that you can insert into your WordPress® Editor, and make available on your site.</p>' . "\n";
934
+ /**/
935
+ echo '<table class="form-table">' . "\n";
936
+ echo '<tbody>' . "\n";
937
+ echo '<tr>' . "\n";
938
+ /**/
939
+ echo '<th>' . "\n";
940
+ echo '<label for="ws-plugin--s2member-single-pages">' . "\n";
941
+ echo 'Single-Page IDs Being Sold On Your Site:' . "\n";
942
+ echo '</label>' . "\n";
943
+ echo '</th>' . "\n";
944
+ /**/
945
+ echo '</tr>' . "\n";
946
+ echo '<tr>' . "\n";
947
+ /**/
948
+ echo '<td>' . "\n";
949
+ echo '<input type="text" name="ws_plugin__s2member_single_pages" id="ws-plugin--s2member-single-pages" value="' . format_to_edit ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["single_pages"]) . '" /><br />' . "\n";
950
+ echo 'Page IDs in comma delimited format. Example: <code>1,2,3,34,8,21</code> * Note... the word <code>all</code> does NOT work here. Also, please be careful not to create a conflict with other Access Restrictions. If you are going to sell Single-Page Access, you should enter specific Page IDs here; and <strong>make SURE that you\'ve NOT already protected any of these Pages</strong>. In other words, if you configure s2Member, in such as a way, that a Page requires Membership Level Access, you cannot sell that same Page through Single-Page Access. Doing so, would create a conflict. Customers that purchased Single-Page Access, would be unable to access the Page - without also having a Membership. Not good. So be careful with this.' . "\n";
951
+ echo '</td>' . "\n";
952
+ /**/
953
+ echo '</tr>' . "\n";
954
+ echo '</tbody>' . "\n";
955
+ echo '</table>' . "\n";
956
+ echo '</div>' . "\n";
957
+ /**/
958
+ echo '</div>' . "\n";
959
+ /**/
960
+ echo '<div class="ws-menu-page-group" title="Member Profile Modifications">' . "\n";
961
+ /**/
962
+ echo '<div class="ws-menu-page-section ws-plugin--s2member-profile-modifications-section">' . "\n";
963
+ echo '<h3>Giving Members The Ability To Modify Their Profile</h3>' . "\n";
964
+ echo '<p>s2Member can be configured to redirect Members away from the <a href="profile.php" target="_blank" rel="xlink">default Profile Editing Panel</a> that is built into WordPress®. When/if a Member attempts to access the default Profile Editing Panel, they\'ll instead, be redirected to the Login Welcome Page that you\'ve configured through s2Member. <strong>Why would I redirect?</strong> Unless you\'ve made some drastic modifications to your WordPress® installation, the default Profile Editing Panel that ships with WordPress®, is NOT really suited for public access, even by a Member.</p>' . "\n";
965
+ echo '<p>So instead of using this default Profile Editing Panel; s2Member creates an added layer of functionality, on top of WordPress®. It does this by providing you ( as the site owner ), with the ability to send your Members to a <a href="' . get_bloginfo ("url") . '/?s2member_profile=1" target="_blank" rel="xlink">special Stand-Alone page</a>, where your Members can modify their entire Profile, including all Custom Fields, and their Password. This special Stand-Alone Editing Panel, has been designed ( with a bare-bones format ), intentionally. This makes it possible for you to <a href="#" onclick="if(!window.open(\'' . get_bloginfo ("url") . '/?s2member_profile=1\', \'_popup\', \'height=350,width=400,left=100,screenX=100,top=100,screenY=100, location=0,menubar=0,toolbar=0,status=0,scrollbars=1,resizable=1\')) alert(\'Please disable popup blockers and try again!\'); return false;" rel="xlink">open it up in a popup window</a>, or embed it into your Login Welcome Page using an IFRAME. Code samples are provided below.</p>' . "\n";
966
+ /**/
967
+ echo '<div class="ws-menu-page-hr"></div>' . "\n";
968
+ /**/
969
+ echo '<p>Stand-Alone page where Members can modify their Profile:<br />' . "\n";
970
+ echo '<code><a href="' . get_bloginfo ("url") . '/?s2member_profile=1" target="_blank" rel="xlink">' . get_bloginfo ("url") . '/?s2member_profile=1</a></code></p>' . "\n";
971
+ /**/
972
+ echo '<div class="ws-menu-page-hr"></div>' . "\n";
973
+ /**/
974
+ echo '<p><strong>Code Sample #1</strong> ( standard link tag ):</p>' . "\n";
975
+ echo '<p>' . highlight_string (preg_replace ("/\<\?php echo S2MEMBER_CURRENT_USER_PROFILE_MODIFICATION_PAGE_URL; \?\>/", get_bloginfo ("url") . "/?s2member_profile=1", file_get_contents (dirname (__FILE__) . "/code-samples/current-user-profile-modification-page-url-1.php")), true) . '</p>' . "\n";
976
+ /**/
977
+ echo '<p><strong>Code Sample #2</strong> ( open the link in a popup window ):</p>' . "\n";
978
+ echo '<p>' . highlight_string (preg_replace ("/\<\?php echo S2MEMBER_CURRENT_USER_PROFILE_MODIFICATION_PAGE_URL; \?\>/", get_bloginfo ("url") . "/?s2member_profile=1", file_get_contents (dirname (__FILE__) . "/code-samples/current-user-profile-modification-page-url-2.php")), true) . '</p>' . "\n";
979
+ /**/
980
+ echo '<p><strong>Code Sample #3</strong> ( embed the form into a Post/Page using an IFRAME tag ):</p>' . "\n";
981
+ echo '<p>' . highlight_string (preg_replace ("/\<\?php echo S2MEMBER_CURRENT_USER_PROFILE_MODIFICATION_PAGE_URL; \?\>/", get_bloginfo ("url") . "/?s2member_profile=1", file_get_contents (dirname (__FILE__) . "/code-samples/current-user-profile-modification-page-url-3.php")), true) . '</p>' . "\n";
982
+ echo '<table class="form-table">' . "\n";
983
+ echo '<tbody>' . "\n";
984
+ echo '<tr>' . "\n";
985
+ /**/
986
+ echo '<th>' . "\n";
987
+ echo '<label for="ws-plugin--s2member-force-admin-lockouts">' . "\n";
988
+ echo 'Redirect Members away from the Default Profile Panel?' . "\n";
989
+ echo '</label>' . "\n";
990
+ echo '</th>' . "\n";
991
+ /**/
992
+ echo '</tr>' . "\n";
993
+ echo '<tr>' . "\n";
994
+ /**/
995
+ echo '<td>' . "\n";
996
+ echo '<select name="ws_plugin__s2member_force_admin_lockouts" id="ws-plugin--s2member-force-admin-lockouts">' . "\n";
997
+ echo '<option value="0"' . ((!$GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["force_admin_lockouts"]) ? ' selected="selected"' : '') . '>No ( I want to leave all options available to my Members )</option>' . "\n";
998
+ echo '<option value="1"' . (($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["force_admin_lockouts"]) ? ' selected="selected"' : '') . '>Yes ( redirect Members to their Login Welcome Page )</option>' . "\n";
999
+ echo '</select><br />' . "\n";
1000
+ echo 'Recommended setting ( <code>Yes</code> ). The Stand-Alone version is better.<br />' . "\n";
1001
+ echo 'You\'ll want to embed the Stand-Alone version into your Login Welcome Page.<br />' . "\n";
1002
+ echo '</td>' . "\n";
1003
+ /**/
1004
+ echo '</tr>' . "\n";
1005
+ echo '</tbody>' . "\n";
1006
+ echo '</table>' . "\n";
1007
+ echo '</div>' . "\n";
1008
+ /**/
1009
+ echo '</div>' . "\n";
1010
+ /**/
1011
  echo '<div class="ws-menu-page-group" title="De-Activation Safeguards">' . "\n";
1012
  /**/
1013
  echo '<div class="ws-menu-page-section ws-plugin--s2member-deactivation-section">' . "\n";
1051
  /**/
1052
  echo '<td class="ws-menu-page-table-r">' . "\n";
1053
  /**/
1054
+ echo ($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["menu-r"]["installation"]) ? '<div class="ws-menu-page-installation"><a href="' . ws_plugin__s2member_parse_readme_value ("Professional Installation URI") . '"><img src="' . $GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["dir_url"] . '/images/brand-installation.png" alt="." title="Contact PriMoThemes!" /></a></div>' . "\n" : '';
1055
+ /**/
1056
  echo ($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["menu-r"]["tools"]) ? '<div class="ws-menu-page-tools"><img src="' . $GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["dir_url"] . '/images/brand-tools.png" alt="." /></div>' . "\n" : '';
1057
  /**/
1058
  echo ($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["menu-r"]["tips"]) ? '<div class="ws-menu-page-tips"><a href="' . ws_plugin__s2member_parse_readme_value ("Customization URI") . '"><img src="' . $GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["dir_url"] . '/images/brand-tips.png" alt="." /></a></div>' . "\n" : '';
includes/menu-pages/paypal-ops.inc.php CHANGED
@@ -70,7 +70,7 @@ echo '<tr>' . "\n";
70
  /**/
71
  echo '<td>' . "\n";
72
  echo '<input type="radio" name="ws_plugin__s2member_paypal_sandbox" id="ws-plugin--s2member-paypal-sandbox-0" value="0"' . ((!$GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["paypal_sandbox"]) ? ' checked="checked"' : '') . ' /> <label for="ws-plugin--s2member-paypal-sandbox-0">No</label> &nbsp;&nbsp;&nbsp; <input type="radio" name="ws_plugin__s2member_paypal_sandbox" id="ws-plugin--s2member-paypal-sandbox-1" value="1"' . (($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["paypal_sandbox"]) ? ' checked="checked"' : '') . ' /> <label for="ws-plugin--s2member-paypal-sandbox-1">Yes, enable support for Sandbox testing.</label><br />' . "\n";
73
- echo '<em>Only enable this if you\'ve provided a Sandbox email address above. This puts the IPN, PDT and Button Generator into Sandbox mode. See: <a href="https://developer.paypal.com/" target="_blank" rel="xlink">https://developer.paypal.com/</a></em>' . "\n";
74
  echo '</td>' . "\n";
75
  /**/
76
  echo '</tr>' . "\n";
@@ -87,7 +87,7 @@ echo '<tr>' . "\n";
87
  /**/
88
  echo '<td>' . "\n";
89
  echo '<input type="radio" name="ws_plugin__s2member_paypal_debug" id="ws-plugin--s2member-paypal-debug-0" value="0"' . ((!$GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["paypal_debug"]) ? ' checked="checked"' : '') . ' /> <label for="ws-plugin--s2member-paypal-debug-0">No</label> &nbsp;&nbsp;&nbsp; <input type="radio" name="ws_plugin__s2member_paypal_debug" id="ws-plugin--s2member-paypal-debug-1" value="1"' . (($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["paypal_debug"]) ? ' checked="checked"' : '') . ' /> <label for="ws-plugin--s2member-paypal-debug-1">Yes, enable debugging, with IPN &amp; Return Page logging.</label><br />' . "\n";
90
- echo '<em>Only enable if you\'re debugging. This enables IPN and Return Page logging. The log files are stored here: <code>' . preg_replace ("/^" . preg_quote ($_SERVER["DOCUMENT_ROOT"], "/") . "/", "", $GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["logs_dir"]) . '</code></em>' . "\n";
91
  echo '</td>' . "\n";
92
  /**/
93
  echo '</tr>' . "\n";
@@ -97,26 +97,28 @@ echo '</div>' . "\n";
97
  /**/
98
  echo '</div>' . "\n";
99
  /**/
100
- echo '<div class="ws-menu-page-group" title="PayPal® IPN Integration">' . "\n";
101
  /**/
102
  echo '<div class="ws-menu-page-section ws-plugin--s2member-paypal-ipn-section">' . "\n";
103
  echo '<h3>PayPal® IPN / Instant Payment Notifications ( required, please enable )</h3>' . "\n";
104
  echo '<p>Log into your PayPal® account and navigate to this section:<br /><code>Account Profile -> Instant Payment Notification Preferences</code></p>' . "\n";
105
  echo '<p>Edit your IPN settings &amp; turn IPN Notifications: <strong><code>On</code></strong></p>' . "\n";
106
  echo '<p>You\'ll need your IPN URL, which is:<br /><code>' . get_bloginfo ("url") . '/?s2member_paypal_notify=1</code></p>' . "\n";
107
- echo '<p><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, which makes it easier to use one PayPal® account to handle multiple sites, all using different IPN URLs.' . "\n";
108
- echo '<p><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 User\'s subscription, or, if the User 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 scenes. The PayPal® IPN service will notify s2Member whenever a User\'s payments have been failing ( more than 2 times in a row ), and/or whenever a User\'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 be deleted automagically. The communication from PayPal® -> s2Member is seamless.</p>' . "\n";
109
  echo '</div>' . "\n";
110
  /**/
111
  echo '</div>' . "\n";
112
  /**/
113
- echo '<div class="ws-menu-page-group" title="PayPal® PDT/Auto-Return">' . "\n";
114
  /**/
115
  echo '<div class="ws-menu-page-section ws-plugin--s2member-paypal-pdt-section">' . "\n";
116
- echo '<h3>PayPal® PDT Identity Token ( required, if using PayPal® Auto-Return )</h3>' . "\n";
117
- echo '<p>Only fill this in if you\'re using PayPal\'s Auto-Return feature with PDT ( Payment Data Transfer ). Please note that Auto-Return w/PDT does <strong>NOT</strong> have to be enabled in your PayPal® account for s2Member to function. It is merely a way to bring visitors back to your site faster after completing checkout at PayPal®. That being said, <strong>if you enable Auto-Return, you MUST also enable PDT &amp; supply your Identity Token here</strong>. Auto-Return &amp; PDT ( Payment Data Transfer ) can both be enabled from within your PayPal® account. You\'ll need your Auto-Return URL, which is:<br /><code>' . get_bloginfo ("url") . '/?s2member_paypal_return=1</code></p>' . "\n";
118
- echo '<p>It is also worth noting that in addition to your default PayPal® account configuration, the Auto-Return URL is also set on a per-transaction basis from within the special PayPal® button code that s2Member provides you with. In other words, if you have multiple sites operating on one PayPal® account, that\'s OK. s2Member dynamically sets the Auto-Return URL for each transaction. The result is that the Auto-Return URL configured from within your PayPal® account, becomes the default, which is then overwritten on a per transaction basis.' . "\n";
119
- echo '<p>Once you\'ve enabled Auto-Return and PDT, PayPal® will issue your Identity Token.' . "\n";
 
 
120
  /**/
121
  echo '<table class="form-table">' . "\n";
122
  echo '<tbody>' . "\n";
@@ -133,7 +135,7 @@ echo '<tr>' . "\n";
133
  /**/
134
  echo '<td>' . "\n";
135
  echo '<input type="text" name="ws_plugin__s2member_paypal_identity_token" id="ws-plugin--s2member-paypal-identity-token" value="' . format_to_edit ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["paypal_identity_token"]) . '" /><br />' . "\n";
136
- echo 'You MUST fill this in if you\'ve enabled Auto-Return. Auto-Return &amp; PDT can both be enabled from within your PayPal® account.' . "\n";
137
  echo '</td>' . "\n";
138
  /**/
139
  echo '</tr>' . "\n";
@@ -147,7 +149,7 @@ echo '<div class="ws-menu-page-group" title="PayPal® Confirmation Email">' . "\
147
  /**/
148
  echo '<div class="ws-menu-page-section ws-plugin--s2member-signup-confirmation-email-section">' . "\n";
149
  echo '<h3>Signup Confirmation Email ( required, but the default works fine )</h3>' . "\n";
150
- echo '<p>This email is sent to new Customers after they return from a successful signup at PayPal®. The <strong>primary</strong> purpose of this email is to provide the Customer with instructions, along with a link to register a Username for their membership. You may also customize this further by providing details that are specifically geared to your site.</p>' . "\n";
151
  /**/
152
  echo '<table class="form-table">' . "\n";
153
  echo '<tbody>' . "\n";
@@ -186,25 +188,25 @@ echo '<strong>You can also use these special replacement codes if you need them:
186
  echo '<ul>' . "\n";
187
  echo '<li><code>%%registration_url%% = The full URL ( generated by s2Member ) where the Customer can get registered.</code></li>' . "\n";
188
  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 ( 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 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";
189
- echo '<li><code>%%initial%% = The initial fee charged during signup, in USD. If you offered a free trial, this will be 0.</code> [ <a href="#" onclick="alert(\'If no initial period was offered or required, this initial amount will be equal to the %%regular%% rate. In other words, this will always represent the amount of money the customer spent whenever they signed up, no matter what.\\n\\nIf a user signs up under the terms of a free trial period, this will be 0.\'); return false;">?</a> ]</li>' . "\n";
190
- echo '<li><code>%%regular%% = The regular amount of the subscription in USD. This dollar value is always > 0, no matter what.</code> [ <a href="#" onclick="alert(\'This is how much the subscription costs after an initial period expires. The %%regular%% rate is always > 0. If you did not offer an initial period, %%initial%% and %%regular%% will be equal to the same thing.\'); return false;">?</a> ]</li>' . "\n";
191
- echo '<li><code>%%recurring%% = This is the amount in USD that will be charged on a recurring basis, or 0 if non-recurring.</code> [ <a href="#" onclick="alert(\'If recurring payments have not been required, this will be equal to 0. That being said, %%regular%% &amp; %%recurring%% are usually the same value. This variable can be used in two different ways. You can use it to determine what the regular recurring rate is, or to determine whether the subscription will recur or not. If it is going to recur, %%recurring%% will be > 0.\\n\\nThe only time this is NOT equal to the %%regular%% rate, is when recurring payments are not required; and only a one-time regular rate applies.\'); return false;">?</a> ]</li>' . "\n";
192
- echo '<li><code>%%first_name%% = The first name of the customer who purchased the membership subscription through PayPal®.</code></li>' . "\n";
193
- echo '<li><code>%%last_name%% = The last name of the customer who purchased the membership subscription through PayPal®.</code></li>' . "\n";
194
- echo '<li><code>%%full_name%% = The full name ( first & last ) of the customer who purchased the membership subscription.</code></li>' . "\n";
195
- echo '<li><code>%%payer_email%% = The email address of the customer who purchased the membership subscription through PayPal®.</code></li>' . "\n";
196
- echo '<li><code>%%item_number%% = The item number ( in other words, the membership level: 1, 2, 3 or 4 ) that the subscription is for.</code></li>' . "\n";
197
- echo '<li><code>%%item_name%% = The item name ( in other words, the associated membership level label that briefly describes the item number ).</code></li>' . "\n";
198
  echo '<li><code>%%initial_term%% = This is the term length of the initial period. This will be a numeric value, followed by a space, then a single letter.</code> [ <a href="#" onclick="alert(\'Here are some examples:\\n\\n%%initial_term%% = 1 D ( this means 1 Day )\\n%%initial_term%% = 1 M ( this means 1 Month )\\n%%initial_term%% = 1 Y ( this means 1 Year )\\n\\nThe initial period never recurs, so this only lasts for the term length specified, then it is over. If no initial period was even offered, the value of %%initial_term%% will just be: 0 D, meaning zero days.\'); return false;">?</a> ]</li>' . "\n";
199
- echo '<li><code>%%regular_term%% = This is the term length of the regular period. This will be a numeric value, followed by a space, then a single letter.</code> [ <a href="#" onclick="alert(\'Here are some examples:\\n\\n%%regular_term%% = 1 D ( this means 1 Day )\\n%%regular_term%% = 1 M ( this means 1 Month )\\n%%regular_term%% = 1 Y ( this means 1 Year )\\n%%regular_term%% = 1 L ( this means 1 Lifetime )\\n\\nThe regular term is usually recurring. So the regular term value represents the period ( or duration ) of each recurring period. If %%recurring%% = 0, then the regular term only applies once, because it is not recurring. So if it is not recurring, the value of %%regular_term%% simply represents how long their membership priviledges are going to last after the %%initial_term%% has expired, if there was an initial term. The value of this variable ( %%regular_term%% ) will never be empty, it will always be at least: 1 D, meaning 1 day. No exceptions.\'); return false;">?</a> ]</li>' . "\n";
200
  echo '</ul>' . "\n";
201
  echo '<strong>Custom replacement codes can also be inserted using these instructions:</strong>' . "\n";
202
  echo '<ul>' . "\n";
203
- echo '<li><code>%%cv0%% = The domain of your site, which is passed through to PayPal® using the `custom` field in your PayPal® button code.</code></li>' . "\n";
204
- echo '<li><code>%%cv1%% = If you need to track additional custom variables, you can pipe delimit them into the `custom` field of your button code like this: &lt;input type="hidden" name="custom" value="' . $_SERVER["HTTP_HOST"] . '|cv1|cv2|cv3" /&gt;. You can have an unlimited number of custom variables that track IP addresses, affiliate IDs, etc. In some cases you may need to use PHP code to insert a value into the custom field dynamically. Obviously this is for advanced webmasters, but the functionality has been made available for those who need it.</li>' . "\n";
205
  echo '</ul>' . "\n";
206
  echo '<strong>This example uses cv1 to track a user\'s IP address:</strong><br />' . "\n";
207
- echo '<em>( The IP address can be referenced in your Signup Confirmation Email using %%cv1%% )</em><br />' . "\n";
208
  echo '<code>&lt;input type="hidden" name="custom" value="' . $_SERVER["HTTP_HOST"] . '|&lt;?php echo $_SERVER["REMOTE_ADDR"]; ?&gt;" /&gt;</code>' . "\n";
209
  echo '</td>' . "\n";
210
  /**/
@@ -215,6 +217,106 @@ echo '</div>' . "\n";
215
  /**/
216
  echo '</div>' . "\n";
217
  /**/
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
218
  echo '<div class="ws-menu-page-hr"></div>' . "\n";
219
  /**/
220
  echo '<p class="submit"><input type="submit" class="button-primary" value="Save Changes" /></p>' . "\n";
@@ -225,6 +327,8 @@ echo '</td>' . "\n";
225
  /**/
226
  echo '<td class="ws-menu-page-table-r">' . "\n";
227
  /**/
 
 
228
  echo ($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["menu-r"]["tools"]) ? '<div class="ws-menu-page-tools"><img src="' . $GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["dir_url"] . '/images/brand-tools.png" alt="." /></div>' . "\n" : '';
229
  /**/
230
  echo ($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["menu-r"]["tips"]) ? '<div class="ws-menu-page-tips"><a href="' . ws_plugin__s2member_parse_readme_value ("Customization URI") . '"><img src="' . $GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["dir_url"] . '/images/brand-tips.png" alt="." /></a></div>' . "\n" : '';
70
  /**/
71
  echo '<td>' . "\n";
72
  echo '<input type="radio" name="ws_plugin__s2member_paypal_sandbox" id="ws-plugin--s2member-paypal-sandbox-0" value="0"' . ((!$GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["paypal_sandbox"]) ? ' checked="checked"' : '') . ' /> <label for="ws-plugin--s2member-paypal-sandbox-0">No</label> &nbsp;&nbsp;&nbsp; <input type="radio" name="ws_plugin__s2member_paypal_sandbox" id="ws-plugin--s2member-paypal-sandbox-1" value="1"' . (($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["paypal_sandbox"]) ? ' checked="checked"' : '') . ' /> <label for="ws-plugin--s2member-paypal-sandbox-1">Yes, enable support for Sandbox testing.</label><br />' . "\n";
73
+ echo '<em>Only enable this if you\'ve provided a Sandbox email address above.<br />This puts the IPN, PDT and Button Generator into Sandbox mode.<br />See: <a href="https://developer.paypal.com/" target="_blank" rel="xlink">https://developer.paypal.com</a></em>' . "\n";
74
  echo '</td>' . "\n";
75
  /**/
76
  echo '</tr>' . "\n";
87
  /**/
88
  echo '<td>' . "\n";
89
  echo '<input type="radio" name="ws_plugin__s2member_paypal_debug" id="ws-plugin--s2member-paypal-debug-0" value="0"' . ((!$GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["paypal_debug"]) ? ' checked="checked"' : '') . ' /> <label for="ws-plugin--s2member-paypal-debug-0">No</label> &nbsp;&nbsp;&nbsp; <input type="radio" name="ws_plugin__s2member_paypal_debug" id="ws-plugin--s2member-paypal-debug-1" value="1"' . (($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["paypal_debug"]) ? ' checked="checked"' : '') . ' /> <label for="ws-plugin--s2member-paypal-debug-1">Yes, enable debugging, with IPN &amp; Return Page logging.</label><br />' . "\n";
90
+ echo '<em>This enables IPN and Return Page logging. The log files are stored here:<br /><code>' . preg_replace ("/^" . preg_quote ($_SERVER["DOCUMENT_ROOT"], "/") . "/", "", $GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["logs_dir"]) . '</code></em>' . "\n";
91
  echo '</td>' . "\n";
92
  /**/
93
  echo '</tr>' . "\n";
97
  /**/
98
  echo '</div>' . "\n";
99
  /**/
100
+ echo '<div class="ws-menu-page-group" title="PayPal® IPN->s2Member Integration">' . "\n";
101
  /**/
102
  echo '<div class="ws-menu-page-section ws-plugin--s2member-paypal-ipn-section">' . "\n";
103
  echo '<h3>PayPal® IPN / Instant Payment Notifications ( required, please enable )</h3>' . "\n";
104
  echo '<p>Log into your PayPal® account and navigate to this section:<br /><code>Account Profile -> Instant Payment Notification Preferences</code></p>' . "\n";
105
  echo '<p>Edit your IPN settings &amp; turn IPN Notifications: <strong><code>On</code></strong></p>' . "\n";
106
  echo '<p>You\'ll need your IPN URL, which is:<br /><code>' . get_bloginfo ("url") . '/?s2member_paypal_notify=1</code></p>' . "\n";
107
+ echo '<p><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.' . "\n";
108
+ echo '<p><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 scenes. 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 demote to a Free Subscriber, or deleted automatically ( based on your configuration ). The communication from PayPal® -> s2Member is seamless.</p>' . "\n";
109
  echo '</div>' . "\n";
110
  /**/
111
  echo '</div>' . "\n";
112
  /**/
113
+ echo '<div class="ws-menu-page-group" title="PayPal® PDT/Auto-Return Integration">' . "\n";
114
  /**/
115
  echo '<div class="ws-menu-page-section ws-plugin--s2member-paypal-pdt-section">' . "\n";
116
+ echo '<h3>PayPal® PDT Identity Token ( required, please enable )</h3>' . "\n";
117
+ echo '<p>Log into your PayPal® account and navigate to this section:<br /><code>Account Profile -> Website Payment Preferences</code></p>' . "\n";
118
+ echo '<p>Turn the Auto-Return feature: <strong><code>On</code></strong></p>' . "\n";
119
+ echo '<p>You\'ll need your Auto-Return URL, which is:<br /><code>' . get_bloginfo ("url") . '/?s2member_paypal_return=1</code></p>' . "\n";
120
+ echo '<p>You MUST also enable PDT ( Payment Data Transfer ): <strong><code>On</code></strong><br /><em>You\'ll be issued an Identity Token that you MUST enter below.</em></p>' . "\n";
121
+ echo '<p><strong>Quick tip:</strong> In addition to your default PayPal® account configuration, the Auto-Return URL is also set on a per-transaction basis from within the special PayPal® Button Code that s2Member provides you with. In other words, if you have multiple sites operating on one PayPal® account, that\'s OK. s2Member dynamically sets the Auto-Return URL for each transaction. The result is that the Auto-Return URL configured from within your PayPal® account, becomes the default, which is then overwritten on a per transaction basis.' . "\n";
122
  /**/
123
  echo '<table class="form-table">' . "\n";
124
  echo '<tbody>' . "\n";
135
  /**/
136
  echo '<td>' . "\n";
137
  echo '<input type="text" name="ws_plugin__s2member_paypal_identity_token" id="ws-plugin--s2member-paypal-identity-token" value="' . format_to_edit ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["paypal_identity_token"]) . '" /><br />' . "\n";
138
+ echo 'Your PDT Identity Token will appear under <em>Profile -> Website Payment Preferences</em> in your PayPal® account.' . "\n";
139
  echo '</td>' . "\n";
140
  /**/
141
  echo '</tr>' . "\n";
149
  /**/
150
  echo '<div class="ws-menu-page-section ws-plugin--s2member-signup-confirmation-email-section">' . "\n";
151
  echo '<h3>Signup Confirmation Email ( required, but the default works fine )</h3>' . "\n";
152
+ echo '<p>This email is sent to new Customers after they return from a successful signup at PayPal®. The <strong>primary</strong> purpose of this email, is to provide the Customer with instructions, along with a link to register a Username for their Membership. You may also customize this further by providing details that are specifically geared to your site.</p>' . "\n";
153
  /**/
154
  echo '<table class="form-table">' . "\n";
155
  echo '<tbody>' . "\n";
188
  echo '<ul>' . "\n";
189
  echo '<li><code>%%registration_url%% = The full URL ( generated by s2Member ) where the Customer can get registered.</code></li>' . "\n";
190
  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 ( 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 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";
191
+ echo '<li><code>%%initial%% = The Initial Fee charged during signup. If you offered a free trial, this will be 0.</code> [ <a href="#" onclick="alert(\'If no initial period was offered or required, this initial amount will be equal to the %%regular%% rate. In other words, this will always represent the amount of money the Customer spent whenever they signed up, no matter what.\\n\\nIf a user signs up under the terms of a free trial period, this will be 0.\'); return false;">?</a> ]</li>' . "\n";
192
+ echo '<li><code>%%regular%% = The Regular Amount of the subscription. This value is always > 0, no matter what.</code> [ <a href="#" onclick="alert(\'This is how much the subscription costs after an initial period expires. The %%regular%% rate is always > 0. If you did not offer an initial period, %%initial%% and %%regular%% will be equal to the same thing.\'); return false;">?</a> ]</li>' . "\n";
193
+ echo '<li><code>%%recurring%% = This is the amount that will be charged on a Recurring basis, or 0 if non-Recurring.</code> [ <a href="#" onclick="alert(\'If recurring payments have not been required, this will be equal to 0. That being said, %%regular%% &amp; %%recurring%% are usually the same value. This variable can be used in two different ways. You can use it to determine what the regular recurring rate is, or to determine whether the subscription will recur or not. If it is going to recur, %%recurring%% will be > 0.\\n\\nThe only time this is NOT equal to the %%regular%% rate, is when recurring payments are not required; and only a one-time regular rate applies.\'); return false;">?</a> ]</li>' . "\n";
194
+ echo '<li><code>%%first_name%% = The First Name of the Customer who purchased the membership subscription through PayPal®.</code></li>' . "\n";
195
+ echo '<li><code>%%last_name%% = The Last Name of the Customer who purchased the membership subscription through PayPal®.</code></li>' . "\n";
196
+ echo '<li><code>%%full_name%% = The Full Name ( First & Last ) of the Customer who purchased the membership subscription.</code></li>' . "\n";
197
+ echo '<li><code>%%payer_email%% = The Email Address of the Customer who purchased the membership subscription through PayPal®.</code></li>' . "\n";
198
+ echo '<li><code>%%item_number%% = The Item Number ( colon separated <em>level:custom_capabilities</em> ) that the subscription is for.</code></li>' . "\n";
199
+ echo '<li><code>%%item_name%% = The Item Name ( in other words, the associated membership Level Label that briefly describes the item number ).</code></li>' . "\n";
200
  echo '<li><code>%%initial_term%% = This is the term length of the initial period. This will be a numeric value, followed by a space, then a single letter.</code> [ <a href="#" onclick="alert(\'Here are some examples:\\n\\n%%initial_term%% = 1 D ( this means 1 Day )\\n%%initial_term%% = 1 M ( this means 1 Month )\\n%%initial_term%% = 1 Y ( this means 1 Year )\\n\\nThe initial period never recurs, so this only lasts for the term length specified, then it is over. If no initial period was even offered, the value of %%initial_term%% will just be: 0 D, meaning zero days.\'); return false;">?</a> ]</li>' . "\n";
201
+ echo '<li><code>%%regular_term%% = This is the term length of the regular period. This will be a numeric value, followed by a space, then a single letter.</code> [ <a href="#" onclick="alert(\'Here are some examples:\\n\\n%%regular_term%% = 1 D ( this means 1 Day )\\n%%regular_term%% = 1 M ( this means 1 Month )\\n%%regular_term%% = 1 Y ( this means 1 Year )\\n%%regular_term%% = 1 L ( this means 1 Lifetime )\\n\\nThe regular term is usually recurring. So the regular term value represents the period ( or duration ) of each recurring period. If %%recurring%% = 0, then the regular term only applies once, because it is not recurring. So if it is not recurring, the value of %%regular_term%% simply represents how long their membership privileges are going to last after the %%initial_term%% has expired, if there was an initial term. The value of this variable ( %%regular_term%% ) will never be empty, it will always be at least: 1 D, meaning 1 day. No exceptions.\'); return false;">?</a> ]</li>' . "\n";
202
  echo '</ul>' . "\n";
203
  echo '<strong>Custom replacement codes can also be inserted using these instructions:</strong>' . "\n";
204
  echo '<ul>' . "\n";
205
+ echo '<li><code>%%cv0%% = The domain of your site, which is passed through to PayPal® using the `custom` field in your PayPal® Button Code.</code></li>' . "\n";
206
+ echo '<li><code>%%cv1%% = If you need to track additional custom variables, you can pipe delimit them into the `custom` field of your Button Code like this: &lt;input type="hidden" name="custom" value="' . $_SERVER["HTTP_HOST"] . '|cv1|cv2|cv3" /&gt;. You can have an unlimited number of custom variables that track IP addresses, affiliate IDs, etc. In some cases you may need to use PHP code to insert a value into the custom field dynamically. Obviously this is for advanced webmasters, but the functionality has been made available for those who need it.</li>' . "\n";
207
  echo '</ul>' . "\n";
208
  echo '<strong>This example uses cv1 to track a user\'s IP address:</strong><br />' . "\n";
209
+ echo '<em>( The IP address can be referenced in your Confirmation Email using %%cv1%% )</em><br />' . "\n";
210
  echo '<code>&lt;input type="hidden" name="custom" value="' . $_SERVER["HTTP_HOST"] . '|&lt;?php echo $_SERVER["REMOTE_ADDR"]; ?&gt;" /&gt;</code>' . "\n";
211
  echo '</td>' . "\n";
212
  /**/
217
  /**/
218
  echo '</div>' . "\n";
219
  /**/
220
+ echo '<div class="ws-menu-page-group" title="PayPal® Single-Page Email">' . "\n";
221
+ /**/
222
+ echo '<div class="ws-menu-page-section ws-plugin--s2member-single-page-email-section">' . "\n";
223
+ echo '<h3>Single-Page Confirmation Email ( required, but the default works fine )</h3>' . "\n";
224
+ echo '<p>This email is sent to new Customers after they return from a successful purchase at PayPal®, specifically for Single-Page Access. ( see: <code>s2Member -> General Options -> Single-Page Access</code> ). This is NOT used for Membership sales, only for Single-Page Access. The <strong>primary</strong> purpose of this email, is to provide the Customer with instructions, along with a link to access the Page they\'ve obtained access to. You may also customize this further by providing details that are specifically geared to your site.</p>' . "\n";
225
+ /**/
226
+ echo '<table class="form-table">' . "\n";
227
+ echo '<tbody>' . "\n";
228
+ echo '<tr>' . "\n";
229
+ /**/
230
+ echo '<th>' . "\n";
231
+ echo '<label for="ws-plugin--s2member-single-page-email-subject">' . "\n";
232
+ echo 'Single-Page Confirmation Email Subject:' . "\n";
233
+ echo '</label>' . "\n";
234
+ echo '</th>' . "\n";
235
+ /**/
236
+ echo '</tr>' . "\n";
237
+ echo '<tr>' . "\n";
238
+ /**/
239
+ echo '<td>' . "\n";
240
+ echo '<input type="text" name="ws_plugin__s2member_single_page_email_subject" id="ws-plugin--s2member-single-page-email-subject" value="' . format_to_edit ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["single_page_email_subject"]) . '" /><br />' . "\n";
241
+ echo 'Subject Line used in the email sent to a Customer after a successful purchase has occurred through PayPal® for Single-Page Access.' . "\n";
242
+ echo '</td>' . "\n";
243
+ /**/
244
+ echo '</tr>' . "\n";
245
+ echo '<tr>' . "\n";
246
+ /**/
247
+ echo '<th>' . "\n";
248
+ echo '<label for="ws-plugin--s2member-single-page-email-message">' . "\n";
249
+ echo 'Single-Page Confirmation Email Message:' . "\n";
250
+ echo '</label>' . "\n";
251
+ echo '</th>' . "\n";
252
+ /**/
253
+ echo '</tr>' . "\n";
254
+ echo '<tr>' . "\n";
255
+ /**/
256
+ echo '<td>' . "\n";
257
+ echo '<textarea name="ws_plugin__s2member_single_page_email_message" id="ws-plugin--s2member-single-page-email-message" rows="10">' . format_to_edit ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["single_page_email_message"]) . '</textarea><br />' . "\n";
258
+ echo 'Message Body used in the email sent to a Customer after a successful purchase has occurred through PayPal® for Single-Page Access.<br /><br />' . "\n";
259
+ echo '<strong>You can also use these special replacement codes if you need them:</strong>' . "\n";
260
+ echo '<ul>' . "\n";
261
+ echo '<li><code>%%sp_access_url%% = The full URL ( generated by s2Member ) where the Customer can gain access. Valid for 72 hours.</code></li>' . "\n";
262
+ echo '<li><code>%%txn_id%% = The PayPal® Transaction ID. PayPal® assigns a unique identifier for every purchase.</code></li>' . "\n";
263
+ echo '<li><code>%%amount%% = The full Amount that you charged for Single-Page Access. This value will always be > 0.</code></li>' . "\n";
264
+ echo '<li><code>%%first_name%% = The First Name of the Customer who purchased Single-Page Access through PayPal®.</code></li>' . "\n";
265
+ echo '<li><code>%%last_name%% = The Last Name of the Customer who purchased Single-Page Access through PayPal®.</code></li>' . "\n";
266
+ echo '<li><code>%%full_name%% = The Full Name ( First & Last ) of the Customer who purchased Single-Page Access.</code></li>' . "\n";
267
+ echo '<li><code>%%payer_email%% = The Email Address of the Customer who purchased Single-Page Access through PayPal®.</code></li>' . "\n";
268
+ echo '<li><code>%%item_number%% = The Item Number. Ex: <em>sp:13</em> ( the numerical portion is a Single-Page ID ).</code></li>' . "\n";
269
+ echo '<li><code>%%item_name%% = The Item Name. In other words, a brief description, detailing what this purchase was for.</code></li>' . "\n";
270
+ echo '</ul>' . "\n";
271
+ echo '<strong>Custom replacement codes can also be inserted using these instructions:</strong>' . "\n";
272
+ echo '<ul>' . "\n";
273
+ echo '<li><code>%%cv0%% = The domain of your site, which is passed through to PayPal® using the `custom` field in your PayPal® Button Code.</code></li>' . "\n";
274
+ echo '<li><code>%%cv1%% = If you need to track additional custom variables, you can pipe delimit them into the `custom` field of your Button Code like this: &lt;input type="hidden" name="custom" value="' . $_SERVER["HTTP_HOST"] . '|cv1|cv2|cv3" /&gt;. You can have an unlimited number of custom variables that track IP addresses, affiliate IDs, etc. In some cases you may need to use PHP code to insert a value into the custom field dynamically. Obviously this is for advanced webmasters, but the functionality has been made available for those who need it.</li>' . "\n";
275
+ echo '</ul>' . "\n";
276
+ echo '<strong>This example uses cv1 to track a user\'s IP address:</strong><br />' . "\n";
277
+ echo '<em>( The IP address can be referenced in your Confirmation Email using %%cv1%% )</em><br />' . "\n";
278
+ echo '<code>&lt;input type="hidden" name="custom" value="' . $_SERVER["HTTP_HOST"] . '|&lt;?php echo $_SERVER["REMOTE_ADDR"]; ?&gt;" /&gt;</code>' . "\n";
279
+ echo '</td>' . "\n";
280
+ /**/
281
+ echo '</tr>' . "\n";
282
+ echo '</tbody>' . "\n";
283
+ echo '</table>' . "\n";
284
+ echo '</div>' . "\n";
285
+ /**/
286
+ echo '</div>' . "\n";
287
+ /**/
288
+ echo '<div class="ws-menu-page-group" title="PayPal® EOT Behavior">' . "\n";
289
+ /**/
290
+ echo '<div class="ws-menu-page-section ws-plugin--s2member-eot-behavior-section">' . "\n";
291
+ echo '<h3>PayPal® EOT Behavior ( required, please choose )</h3>' . "\n";
292
+ echo '<p>EOT = End Of Term. By default, s2Member will demote a paid Member to a Free Subscriber whenever their subscription term has ended, been canceled, 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.</p>' . "\n";
293
+ echo '<table class="form-table">' . "\n";
294
+ echo '<tbody>' . "\n";
295
+ echo '<tr>' . "\n";
296
+ /**/
297
+ echo '<th>' . "\n";
298
+ echo '<label for="ws-plugin--s2member-membership-eot-behavior">' . "\n";
299
+ echo 'Membership EOT Behavior ( demote or delete )?' . "\n";
300
+ echo '</label>' . "\n";
301
+ echo '</th>' . "\n";
302
+ /**/
303
+ echo '</tr>' . "\n";
304
+ echo '<tr>' . "\n";
305
+ /**/
306
+ echo '<td>' . "\n";
307
+ echo '<select name="ws_plugin__s2member_membership_eot_behavior" id="ws-plugin--s2member-membership-eot-behavior">' . "\n";
308
+ echo '<option value="demote"' . (($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["membership_eot_behavior"] === "demote") ? ' selected="selected"' : '') . '>Demote ( convert them to a Free Subscriber )</option>' . "\n";
309
+ echo '<option value="delete"' . (($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["membership_eot_behavior"] === "delete") ? ' selected="selected"' : '') . '>Delete ( erase their account completely )</option>' . "\n";
310
+ echo '</select>' . "\n";
311
+ echo '</td>' . "\n";
312
+ /**/
313
+ echo '</tr>' . "\n";
314
+ echo '</tbody>' . "\n";
315
+ echo '</table>' . "\n";
316
+ echo '</div>' . "\n";
317
+ /**/
318
+ echo '</div>' . "\n";
319
+ /**/
320
  echo '<div class="ws-menu-page-hr"></div>' . "\n";
321
  /**/
322
  echo '<p class="submit"><input type="submit" class="button-primary" value="Save Changes" /></p>' . "\n";
327
  /**/
328
  echo '<td class="ws-menu-page-table-r">' . "\n";
329
  /**/
330
+ echo ($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["menu-r"]["installation"]) ? '<div class="ws-menu-page-installation"><a href="' . ws_plugin__s2member_parse_readme_value ("Professional Installation URI") . '"><img src="' . $GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["dir_url"] . '/images/brand-installation.png" alt="." title="Contact PriMoThemes!" /></a></div>' . "\n" : '';
331
+ /**/
332
  echo ($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["menu-r"]["tools"]) ? '<div class="ws-menu-page-tools"><img src="' . $GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["dir_url"] . '/images/brand-tools.png" alt="." /></div>' . "\n" : '';
333
  /**/
334
  echo ($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["menu-r"]["tips"]) ? '<div class="ws-menu-page-tips"><a href="' . ws_plugin__s2member_parse_readme_value ("Customization URI") . '"><img src="' . $GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["dir_url"] . '/images/brand-tips.png" alt="." /></a></div>' . "\n" : '';
includes/menu-pages/s2m-samps.php DELETED
@@ -1,33 +0,0 @@
1
- <form action="https://www.paypal.com/cgi-bin/webscr" method="post">
2
- <input type="hidden" name="business" value="paypal@example.com">
3
- <input type="hidden" name="cmd" value="_xclick-subscriptions">
4
- <!-- Instant Payment Notification / Return Details -->
5
- <input type="hidden" name="notify_url" value="http://www.example.com/?s2member_paypal_notify=1">
6
- <input type="hidden" name="cancel_return" value="http://www.example.com">
7
- <input type="hidden" name="return" value="http://www.example.com/?s2member_paypal_return=1">
8
- <input type="hidden" name="rm" value="2">
9
- <!-- Identify / Customize The Checkout Fields. -->
10
- <input type="hidden" name="no_shipping" value="1">
11
- <input type="hidden" name="no_note" value="1">
12
- <input type="hidden" name="custom" value="www.example.com">
13
- <input type="hidden" name="currency_code" value="USD">
14
- <input type="hidden" name="page_style" value="paypal">
15
- <input type="hidden" name="item_name" value="Paid Membership ( $25/mo )">
16
- <input type="hidden" name="item_number" value="1">
17
- <!-- Identify / Update An Existing Free Subscriber After Checkout. -->
18
- <input type="hidden" name="on0" value="Update Subscriber ID">
19
- <input type="hidden" name="os0" value="<?php echo S2MEMBER_CURRENT_USER_SUBSCR_ID; ?>">
20
- <!-- Set The Terms Of The New Subscription. -->
21
- <input type="hidden" name="modify" value="0">
22
- <input type="hidden" name="src" value="1">
23
- <input type="hidden" name="sra" value="1">
24
- <input type="hidden" name="a3" value="25">
25
- <input type="hidden" name="p3" value="1">
26
- <input type="hidden" name="t3" value="M">
27
- <!-- Display The Subscription Button. -->
28
- <input type="image" alt="PayPal®" style="border:0;" src="https://www.paypal.com/en_GB/i/btn/btn_xpressCheckout.gif">
29
- </form>
30
- -------------------------------------------------------------------------------------------------
31
- SO THE RELEVANT SECTION IN THE EXAMPLE GIVEN ABOVE IS:
32
- <input type="hidden" name="on0" value="Update Subscriber ID">
33
- <input type="hidden" name="os0" value="<?php echo S2MEMBER_CURRENT_USER_SUBSCR_ID; ?>">
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
includes/menu-pages/scripting.inc.php CHANGED
@@ -32,7 +32,7 @@ echo '<div class="ws-menu-page-group" title="The Extremely Easy Way">' . "\n";
32
  /**/
33
  echo '<div class="ws-menu-page-section ws-plugin--s2member-api-easy-way-section">' . "\n";
34
  echo '<h3>The Extremely Easy Way ( no scripting required )</h3>' . "\n";
35
- echo '<p>From your s2Member General Options panel, you may restrict access to certain Posts, Pages, Tags, Categories, and/or URIs based on a Member\'s level. The s2Member Options panel makes it easy for you. All you do is type in the basics of what you want to restrict access to, and those sections of your site will be off limits to non-Members. That being said, there are times when you might need to have greater control over which portions of your site can be viewed by non-Members, or Members at different levels. This is where API Scripting with Advanced Conditionals comes in.</p>' . "\n";
36
  echo '</div>' . "\n";
37
  /**/
38
  echo '</div>' . "\n";
@@ -41,9 +41,43 @@ echo '<div class="ws-menu-page-group" title="Using Advanced Conditionals">' . "\
41
  /**/
42
  echo '<div class="ws-menu-page-section ws-plugin--s2member-api-advanced-way-section">' . "\n";
43
  echo '<h3>The Advanced Way ( some PHP scripting required )</h3>' . "\n";
44
- echo '<p>In an effort to give you even more control over access restrictions, s2Member makes a special PHP function available to you from within WordPress®. The function is named <strong>current_user_can()</strong>. To make use of this function, please follow our PHP code samples below. Using PHP, you can control access to certain portions of your content, and even build Advanced Conditionals within your content based on a Members\'s level. If you\'re unable to use PHP scripting inside your Posts or Pages, you might want to install this handy plugin ( <a href="http://wordpress.org/extend/plugins/exec-php/" target="_blank" rel="xlink">Exec-PHP</a> ).</p>' . "\n";
45
- echo '<p><strong>Here are some examples of how you could use the `current_user_can` function in PHP scripting:</strong></p>' . "\n";
46
- echo '<p>' . highlight_string (file_get_contents (dirname (__FILE__) . "/cur-samps.php"), true) . '</p>' . "\n";
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
47
  echo '</div>' . "\n";
48
  /**/
49
  echo '</div>' . "\n";
@@ -52,9 +86,35 @@ echo '<div class="ws-menu-page-group" title="s2Member Content Dripping">' . "\n"
52
  /**/
53
  echo '<div class="ws-menu-page-section ws-plugin--s2member-api-advanced-dripping-section">' . "\n";
54
  echo '<h3>Dripping Content ( some PHP scripting required )</h3>' . "\n";
55
- echo '<p>Content Dripping is the gradual, pre-scheduled release of premium website content to paying members. This has become increasingly popular, because it allows older Members; those who have paid you more due to recurring charges; to acquire access to more content progressively; based on their original registration date. It also gives you ( as the site owner ), the ability to launch multiple membership site portals operating on autopilot without any direct day to day involvement in a content release process. This requires some PHP scripting. If you\'re unable to use PHP scripting inside your Posts or Pages, you might want to install this handy plugin ( <a href="http://wordpress.org/extend/plugins/exec-php/" target="_blank" rel="xlink">Exec-PHP</a> ).</p>' . "\n";
56
- echo '<p><strong>To drip content, use <code>S2MEMBER_CURRENT_USER_REGISTRATION_DAYS</code> in your PHP scripting:</strong></p>' . "\n";
57
- echo '<p>' . highlight_string (file_get_contents (dirname (__FILE__) . "/drip-samps.php"), true) . '</p>' . "\n";
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
58
  echo '</div>' . "\n";
59
  /**/
60
  echo '</div>' . "\n";
@@ -63,227 +123,262 @@ echo '<div class="ws-menu-page-group" title="s2Member PHP/API Constants">' . "\n
63
  /**/
64
  echo '<div class="ws-menu-page-section ws-plugin--s2member-api-constants-section">' . "\n";
65
  echo '<h3>You Have Access To PHP Constants ( some PHP scripting required )</h3>' . "\n";
66
- echo '<p>A constant is an identifier ( name ) for a simple value in PHP scripting. Below is a comprehensive list that includes all PHP defined constants that are available to you. All of these Constants are also available through JavaScript as global variables. Example code has been provided in the documenation below. If you\'re a web developer, we suggest using some of these Constants in the creation of the Login Welcome Page described in the s2Member General Options panel. It is not required mind you, but you can get pretty creative with the Login Welcome Page if you know a little PHP. For example, you might use `S2MEMBER_CURRENT_USER_ACCESS_LABEL` to display the type of membership the User currently has. Or you could use `S2MEMBER_CURRENT_USER_PROFILE_MODIFICATION_PAGE_URL` to provide the user with a really easy way to update their Membership Profile. If you get stuck on this, you might want to check out Elance.com. You can hire a freelancer to do this for you. It\'s about a $100 job. There are many other possibilities available as well; <em>limitless actually!</em></p>' . "\n";
 
67
  /**/
68
  echo '<div class="ws-menu-page-hr"></div>' . "\n";
69
  /**/
70
- echo '<p><strong>S2MEMBER_CURRENT_USER_IS_LOGGED_IN</strong> = This will always be (bool) true or false. True if a user is currently logged in with a level of 1 or higher.</p>' . "\n";
71
- echo '<p>' . highlight_string (file_get_contents (dirname (__FILE__) . "/con-samps/current_user_is_logged_in.php"), true) . '</p>' . "\n";
72
  /**/
73
  echo '<div class="ws-menu-page-hr"></div>' . "\n";
74
  /**/
75
- echo '<p><strong>S2MEMBER_CURRENT_USER_ACCESS_LEVEL</strong> = This will always be (int) -1 thru 4. -1 if not logged in. 0 if logged in without access.</p>' . "\n";
76
- echo '<p>' . highlight_string (file_get_contents (dirname (__FILE__) . "/con-samps/current_user_access_level.php"), true) . '</p>' . "\n";
 
77
  /**/
78
  echo '<div class="ws-menu-page-hr"></div>' . "\n";
79
  /**/
80
- echo '<p><strong>S2MEMBER_CURRENT_USER_ACCESS_LABEL</strong> = This will always be a (string). Empty if not logged in.</p>' . "\n";
81
- echo '<p>' . highlight_string (file_get_contents (dirname (__FILE__) . "/con-samps/current_user_access_label.php"), true) . '</p>' . "\n";
 
82
  /**/
83
  echo '<div class="ws-menu-page-hr"></div>' . "\n";
84
  /**/
85
- echo '<p><strong>S2MEMBER_CURRENT_USER_SUBSCR_ID</strong> = This will always be a (string). Empty if not logged in.</p>' . "\n";
86
- echo '<p>' . highlight_string (file_get_contents (dirname (__FILE__) . "/con-samps/current_user_subscr_id.php"), true) . '</p>' . "\n";
 
 
 
 
87
  /**/
88
  echo '<div class="ws-menu-page-hr"></div>' . "\n";
89
  /**/
90
- echo '<p><strong>S2MEMBER_CURRENT_USER_CUSTOM</strong> = This will always be a (string). Empty if not logged in.</p>' . "\n";
91
- echo '<p>' . highlight_string (file_get_contents (dirname (__FILE__) . "/con-samps/current_user_custom.php"), true) . '</p>' . "\n";
92
  /**/
93
  echo '<div class="ws-menu-page-hr"></div>' . "\n";
94
  /**/
95
- echo '<p><strong>S2MEMBER_CURRENT_USER_REGISTRATION_TIME</strong> = This will always be an (int); in the form of a Unix timestamp. 0 if not logged in. This holds the recorded time at which the Member originally registered their Username for access to your site. This is useful if you want to drip content over an extended period of time, based on how long someone has been a Member.</p>' . "\n";
96
- echo '<p>' . highlight_string (file_get_contents (dirname (__FILE__) . "/con-samps/current_user_registration_time.php"), true) . '</p>' . "\n";
97
  /**/
98
  echo '<div class="ws-menu-page-hr"></div>' . "\n";
99
  /**/
100
- echo '<p><strong>S2MEMBER_CURRENT_USER_REGISTRATION_DAYS</strong> = This will always be an (int). 0 if not logged in. This is the number of days that have passed since the Member originally registered their Username for access to your site. This is useful if you want to drip content over an extended period of time, based on how long someone has been a Member.</p>' . "\n";
101
- echo '<p>' . highlight_string (file_get_contents (dirname (__FILE__) . "/con-samps/current_user_registration_days.php"), true) . '</p>' . "\n";
102
  /**/
103
  echo '<div class="ws-menu-page-hr"></div>' . "\n";
104
  /**/
105
- echo '<p><strong>S2MEMBER_CURRENT_USER_DISPLAY_NAME</strong> = This will always be a (string). Empty if not logged in.</p>' . "\n";
106
- echo '<p>' . highlight_string (file_get_contents (dirname (__FILE__) . "/con-samps/current_user_display_name.php"), true) . '</p>' . "\n";
107
  /**/
108
  echo '<div class="ws-menu-page-hr"></div>' . "\n";
109
  /**/
110
- echo '<p><strong>S2MEMBER_CURRENT_USER_FIRST_NAME</strong> = This will always be a (string). Empty if not logged in.</p>' . "\n";
111
- echo '<p>' . highlight_string (file_get_contents (dirname (__FILE__) . "/con-samps/current_user_first_name.php"), true) . '</p>' . "\n";
112
  /**/
113
  echo '<div class="ws-menu-page-hr"></div>' . "\n";
114
  /**/
115
- echo '<p><strong>S2MEMBER_CURRENT_USER_LAST_NAME</strong> = This will always be a (string). Empty if not logged in.</p>' . "\n";
116
- echo '<p>' . highlight_string (file_get_contents (dirname (__FILE__) . "/con-samps/current_user_last_name.php"), true) . '</p>' . "\n";
117
  /**/
118
  echo '<div class="ws-menu-page-hr"></div>' . "\n";
119
  /**/
120
- echo '<p><strong>S2MEMBER_CURRENT_USER_LOGIN</strong> = This will always be a (string). Empty if not logged in.</p>' . "\n";
121
- echo '<p>' . highlight_string (file_get_contents (dirname (__FILE__) . "/con-samps/current_user_login.php"), true) . '</p>' . "\n";
122
  /**/
123
  echo '<div class="ws-menu-page-hr"></div>' . "\n";
124
  /**/
125
- echo '<p><strong>S2MEMBER_CURRENT_USER_EMAIL</strong> = This will always be a (string). Empty if not logged in.</p>' . "\n";
126
- echo '<p>' . highlight_string (file_get_contents (dirname (__FILE__) . "/con-samps/current_user_email.php"), true) . '</p>' . "\n";
127
  /**/
128
  echo '<div class="ws-menu-page-hr"></div>' . "\n";
129
  /**/
130
- echo '<p><strong>S2MEMBER_CURRENT_USER_IP</strong> = This will always be a (string). Empty if browsing anonymously.</p>' . "\n";
131
- echo '<p>' . highlight_string (file_get_contents (dirname (__FILE__) . "/con-samps/current_user_ip.php"), true) . '</p>' . "\n";
132
  /**/
133
  echo '<div class="ws-menu-page-hr"></div>' . "\n";
134
  /**/
135
- echo '<p><strong>S2MEMBER_CURRENT_USER_ID</strong> = This will always be an (int). However, it will be 0 if not logged in.</p>' . "\n";
136
- echo '<p>' . highlight_string (file_get_contents (dirname (__FILE__) . "/con-samps/current_user_id.php"), true) . '</p>' . "\n";
137
  /**/
138
  echo '<div class="ws-menu-page-hr"></div>' . "\n";
139
  /**/
140
- echo '<p><strong>S2MEMBER_CURRENT_USER_FIELDS</strong> = This will always be a serialized array (string). An empty serialized array (string) if not logged in. This serialized array will contain the following fields: <code>id, ip, email, login, first_name, last_name, display_name, subscr_id, custom</code>. If you\'ve configured additional Custom Fields, those Custom Fields will also be added to this array. For example, if you configured the Custom Field: <code>Street Address</code>, it would be included in this array as: <code>street_address</code>. Custom Field references are converted to lowercase format, and spaces are replaced by underscores. You can do <code>print_r(unserialize(S2MEMBER_CURRENT_USER_FIELDS));</code> to get a full list for testing.</p>' . "\n";
 
 
 
 
 
 
 
 
 
 
141
  if (defined ("BP_VERSION"))
142
  echo '<p><em class="ws-menu-page-error">* Custom Fields are N/A when running together with BuddyPress. Instead, use <code>BuddyPress -> Profile Field Setup</code>.</em></p>' . "\n";
143
- echo '<p>' . highlight_string (file_get_contents (dirname (__FILE__) . "/con-samps/current_user_fields.php"), true) . '</p>' . "\n";
144
  /**/
145
  echo '<div class="ws-menu-page-hr"></div>' . "\n";
146
  /**/
147
- echo '<p><strong>S2MEMBER_CURRENT_USER_DOWNLOADS_ALLOWED</strong> = This will always be an (int) value >= 0 where 0 means no access.</p>' . "\n";
148
- echo '<p>' . highlight_string (file_get_contents (dirname (__FILE__) . "/con-samps/current_user_downloads_allowed.php"), true) . '</p>' . "\n";
149
  /**/
150
  echo '<div class="ws-menu-page-hr"></div>' . "\n";
151
  /**/
152
- echo '<p><strong>S2MEMBER_CURRENT_USER_DOWNLOADS_ALLOWED_IS_UNLIMITED</strong> = This will always be (bool) true or false. A value of true means their allowed downloads are >= 999999999, and false means it is not. This is useful if you are allowing unlimited ( 999999999 ) downloads on some membership levels. You can display `Unlimited` instead of a number.</p>' . "\n";
153
- echo '<p>' . highlight_string (file_get_contents (dirname (__FILE__) . "/con-samps/current_user_downloads_allowed_is_unlimited.php"), true) . '</p>' . "\n";
154
  /**/
155
  echo '<div class="ws-menu-page-hr"></div>' . "\n";
156
  /**/
157
- echo '<p><strong>S2MEMBER_CURRENT_USER_DOWNLOADS_CURRENTLY</strong> = This will always be an (int) value >= 0 where 0 means none.</p>' . "\n";
158
- echo '<p>' . highlight_string (file_get_contents (dirname (__FILE__) . "/con-samps/current_user_downloads_currently.php"), true) . '</p>' . "\n";
159
  /**/
160
  echo '<div class="ws-menu-page-hr"></div>' . "\n";
161
  /**/
162
- echo '<p><strong>S2MEMBER_CURRENT_USER_DOWNLOADS_ALLOWED_DAYS</strong> = This will always be an (int) value >= 0 where 0 means no access.</p>' . "\n";
163
- echo '<p>' . highlight_string (file_get_contents (dirname (__FILE__) . "/con-samps/current_user_downloads_allowed_days.php"), true) . '</p>' . "\n";
164
  /**/
165
  echo '<div class="ws-menu-page-hr"></div>' . "\n";
166
  /**/
167
- echo '<p><strong>S2MEMBER_CURRENT_USER_PROFILE_MODIFICATION_PAGE_URL</strong> = This is where a user can modify their profile. ( window.open is suggested ).</p>' . "\n";
168
- echo '<p>' . highlight_string (file_get_contents (dirname (__FILE__) . "/con-samps/current_user_profile_modification_page_url.php"), true) . '</p>' . "\n";
 
 
 
 
 
169
  /**/
170
  echo '<div class="ws-menu-page-hr"></div>' . "\n";
171
  /**/
172
- echo '<p><strong>S2MEMBER_FILE_DOWNLOAD_LIMIT_EXCEEDED_PAGE_URL</strong> = This is the full URL to the Limit Exceeded Page ( informational ).<br />' . "\n";
173
- echo '<strong>S2MEMBER_FILE_DOWNLOAD_LIMIT_EXCEEDED_PAGE_ID</strong> = This is the Page ID that was used to generate the full URL.</p>' . "\n";
174
- echo '<p>' . highlight_string (file_get_contents (dirname (__FILE__) . "/con-samps/file_download_limit_exceeded_page_url.php"), true) . '</p>' . "\n";
175
  /**/
176
  echo '<div class="ws-menu-page-hr"></div>' . "\n";
177
  /**/
178
- echo '<p><strong>S2MEMBER_MEMBERSHIP_OPTIONS_PAGE_URL</strong> = This is the full URL to the Membership Options Page ( the signup page ).<br />' . "\n";
179
- echo '<strong>S2MEMBER_MEMBERSHIP_OPTIONS_PAGE_ID</strong> = This is the Page ID that was used to generate the full URL.</p>' . "\n";
180
- echo '<p>' . highlight_string (file_get_contents (dirname (__FILE__) . "/con-samps/membership_options_page_url.php"), true) . '</p>' . "\n";
181
  /**/
182
  echo '<div class="ws-menu-page-hr"></div>' . "\n";
183
  /**/
184
- echo '<p><strong>S2MEMBER_LOGIN_WELCOME_PAGE_URL</strong> = This is the full URL to the Login Welcome Page ( the user\'s account page ). * This could also be the full URL to a Special Redirection URL ( if you configured one ). See <code>s2Member -> General Options -> Login Welcome Page</code>.<br />' . "\n";
185
- echo '<strong>S2MEMBER_LOGIN_WELCOME_PAGE_ID</strong> = This is the Page ID that was used to generate the full URL. * In the case of a Special Redirection URL, this ID is not really applicable.</p>' . "\n";
186
- echo '<p>' . highlight_string (file_get_contents (dirname (__FILE__) . "/con-samps/login_welcome_page_url.php"), true) . '</p>' . "\n";
187
  /**/
188
  echo '<div class="ws-menu-page-hr"></div>' . "\n";
189
  /**/
190
- echo '<p><strong>S2MEMBER_LOGIN_PAGE_URL</strong> = This is the full URL to the Membership Login Page ( the wordpress login page ).</p>' . "\n";
191
- echo '<p>' . highlight_string (file_get_contents (dirname (__FILE__) . "/con-samps/login_page_url.php"), true) . '</p>' . "\n";
192
  /**/
193
  echo '<div class="ws-menu-page-hr"></div>' . "\n";
194
  /**/
195
- echo '<p><strong>S2MEMBER_LOGOUT_PAGE_URL</strong> = This is the full URL to the Membership Logout Page ( the wordpress logout page ).</p>' . "\n";
196
- echo '<p>' . highlight_string (file_get_contents (dirname (__FILE__) . "/con-samps/logout_page_url.php"), true) . '</p>' . "\n";
197
  /**/
198
  echo '<div class="ws-menu-page-hr"></div>' . "\n";
199
  /**/
200
- echo '<p><strong>S2MEMBER_LEVEL1_LABEL</strong> = This is the (string) label that you created for membership level number 1.</p>' . "\n";
201
- echo '<p>' . highlight_string (file_get_contents (dirname (__FILE__) . "/con-samps/level1_label.php"), true) . '</p>' . "\n";
202
  /**/
203
  echo '<div class="ws-menu-page-hr"></div>' . "\n";
204
  /**/
205
- echo '<p><strong>S2MEMBER_LEVEL2_LABEL</strong> = This is the (string) label that you created for membership level number 2.</p>' . "\n";
206
- echo '<p>' . highlight_string (file_get_contents (dirname (__FILE__) . "/con-samps/level2_label.php"), true) . '</p>' . "\n";
207
  /**/
208
  echo '<div class="ws-menu-page-hr"></div>' . "\n";
209
  /**/
210
- echo '<p><strong>S2MEMBER_LEVEL3_LABEL</strong> = This is the (string) label that you created for membership level number 3.</p>' . "\n";
211
- echo '<p>' . highlight_string (file_get_contents (dirname (__FILE__) . "/con-samps/level3_label.php"), true) . '</p>' . "\n";
212
  /**/
213
  echo '<div class="ws-menu-page-hr"></div>' . "\n";
214
  /**/
215
- echo '<p><strong>S2MEMBER_LEVEL4_LABEL</strong> = This is the (string) label that you created for membership level number 4.</p>' . "\n";
216
- echo '<p>' . highlight_string (file_get_contents (dirname (__FILE__) . "/con-samps/level4_label.php"), true) . '</p>' . "\n";
217
  /**/
218
  echo '<div class="ws-menu-page-hr"></div>' . "\n";
219
  /**/
220
- echo '<p><strong>S2MEMBER_LEVEL1_FILE_DOWNLOADS_ALLOWED</strong> = This is the (int) allowed downloads for level number 1.</p>' . "\n";
221
- echo '<p>' . highlight_string (file_get_contents (dirname (__FILE__) . "/con-samps/level1_file_downloads_allowed.php"), true) . '</p>' . "\n";
222
  /**/
223
  echo '<div class="ws-menu-page-hr"></div>' . "\n";
224
  /**/
225
- echo '<p><strong>S2MEMBER_LEVEL2_FILE_DOWNLOADS_ALLOWED</strong> = This is the (int) allowed downloads for level number 2.</p>' . "\n";
226
- echo '<p>' . highlight_string (file_get_contents (dirname (__FILE__) . "/con-samps/level2_file_downloads_allowed.php"), true) . '</p>' . "\n";
227
  /**/
228
  echo '<div class="ws-menu-page-hr"></div>' . "\n";
229
  /**/
230
- echo '<p><strong>S2MEMBER_LEVEL3_FILE_DOWNLOADS_ALLOWED</strong> = This is the (int) allowed downloads for level number 3.</p>' . "\n";
231
- echo '<p>' . highlight_string (file_get_contents (dirname (__FILE__) . "/con-samps/level3_file_downloads_allowed.php"), true) . '</p>' . "\n";
232
  /**/
233
  echo '<div class="ws-menu-page-hr"></div>' . "\n";
234
  /**/
235
- echo '<p><strong>S2MEMBER_LEVEL4_FILE_DOWNLOADS_ALLOWED</strong> = This is the (int) allowed downloads for level number 4.</p>' . "\n";
236
- echo '<p>' . highlight_string (file_get_contents (dirname (__FILE__) . "/con-samps/level4_file_downloads_allowed.php"), true) . '</p>' . "\n";
237
  /**/
238
  echo '<div class="ws-menu-page-hr"></div>' . "\n";
239
  /**/
240
- echo '<p><strong>S2MEMBER_LEVEL1_FILE_DOWNLOADS_ALLOWED_DAYS</strong> = This is the (int) allowed download days for level number 1.</p>' . "\n";
241
- echo '<p>' . highlight_string (file_get_contents (dirname (__FILE__) . "/con-samps/level1_file_downloads_allowed_days.php"), true) . '</p>' . "\n";
242
  /**/
243
  echo '<div class="ws-menu-page-hr"></div>' . "\n";
244
  /**/
245
- echo '<p><strong>S2MEMBER_LEVEL2_FILE_DOWNLOADS_ALLOWED_DAYS</strong> = This is the (int) allowed download days for level number 2.</p>' . "\n";
246
- echo '<p>' . highlight_string (file_get_contents (dirname (__FILE__) . "/con-samps/level2_file_downloads_allowed_days.php"), true) . '</p>' . "\n";
247
  /**/
248
  echo '<div class="ws-menu-page-hr"></div>' . "\n";
249
  /**/
250
- echo '<p><strong>S2MEMBER_LEVEL3_FILE_DOWNLOADS_ALLOWED_DAYS</strong> = This is the (int) allowed download days for level number 3.</p>' . "\n";
251
- echo '<p>' . highlight_string (file_get_contents (dirname (__FILE__) . "/con-samps/level3_file_downloads_allowed_days.php"), true) . '</p>' . "\n";
252
  /**/
253
  echo '<div class="ws-menu-page-hr"></div>' . "\n";
254
  /**/
255
- echo '<p><strong>S2MEMBER_LEVEL4_FILE_DOWNLOADS_ALLOWED_DAYS</strong> = This is the (int) allowed download days for level number 4.</p>' . "\n";
256
- echo '<p>' . highlight_string (file_get_contents (dirname (__FILE__) . "/con-samps/level4_file_downloads_allowed_days.php"), true) . '</p>' . "\n";
257
  /**/
258
  echo '<div class="ws-menu-page-hr"></div>' . "\n";
259
  /**/
260
- echo '<p><strong>S2MEMBER_REG_EMAIL_FROM_NAME</strong> = This is the name that outgoing email messages are sent by.</p>' . "\n";
261
- echo '<p>' . highlight_string (file_get_contents (dirname (__FILE__) . "/con-samps/reg_email_from_name.php"), true) . '</p>' . "\n";
262
  /**/
263
  echo '<div class="ws-menu-page-hr"></div>' . "\n";
264
  /**/
265
- echo '<p><strong>S2MEMBER_REG_EMAIL_FROM_EMAIL</strong> = This is the email address that outgoing messages are sent by.</p>' . "\n";
266
- echo '<p>' . highlight_string (file_get_contents (dirname (__FILE__) . "/con-samps/reg_email_from_email.php"), true) . '</p>' . "\n";
267
  /**/
268
  echo '<div class="ws-menu-page-hr"></div>' . "\n";
269
  /**/
270
- echo '<p><strong>S2MEMBER_PAYPAL_NOTIFY_URL</strong> = This is the URL on your system that receives PayPal IPN responses.</p>' . "\n";
271
- echo '<p>' . highlight_string (file_get_contents (dirname (__FILE__) . "/con-samps/paypal_notify_url.php"), true) . '</p>' . "\n";
272
  /**/
273
  echo '<div class="ws-menu-page-hr"></div>' . "\n";
274
  /**/
275
- echo '<p><strong>S2MEMBER_PAYPAL_RETURN_URL</strong> = This is the URL on your system that receives PayPal return variables.</p>' . "\n";
276
- echo '<p>' . highlight_string (file_get_contents (dirname (__FILE__) . "/con-samps/paypal_return_url.php"), true) . '</p>' . "\n";
277
  /**/
278
  echo '<div class="ws-menu-page-hr"></div>' . "\n";
279
  /**/
280
- echo '<p><strong>S2MEMBER_PAYPAL_ENDPOINT</strong> = This is the endpoint domain to the paypal server.</p>' . "\n";
281
- echo '<p>' . highlight_string (file_get_contents (dirname (__FILE__) . "/con-samps/paypal_endpoint.php"), true) . '</p>' . "\n";
282
  /**/
283
  echo '<div class="ws-menu-page-hr"></div>' . "\n";
284
  /**/
285
- echo '<p><strong>S2MEMBER_PAYPAL_BUSINESS</strong> = This is the email address that identifies your paypal business.</p>' . "\n";
286
- echo '<p>' . highlight_string (file_get_contents (dirname (__FILE__) . "/con-samps/paypal_business.php"), true) . '</p>' . "\n";
 
 
 
 
 
 
 
 
 
 
 
 
 
287
  /**/
288
  echo '</div>' . "\n";
289
  /**/
@@ -292,8 +387,8 @@ echo '</div>' . "\n";
292
  echo '<div class="ws-menu-page-group" title="s2Member JS/API Globals">' . "\n";
293
  /**/
294
  echo '<div class="ws-menu-page-section ws-plugin--s2member-api-js-globals-section">' . "\n";
295
- echo '<h3>You Also Have Access To JS Globals ( some scripting required )</h3>' . "\n";
296
- echo '<p>All of the PHP Constants are also available through JavaScript as global variables.</p>' . "\n";
297
  echo '</div>' . "\n";
298
  /**/
299
  echo '</div>' . "\n";
@@ -302,6 +397,8 @@ echo '</td>' . "\n";
302
  /**/
303
  echo '<td class="ws-menu-page-table-r">' . "\n";
304
  /**/
 
 
305
  echo ($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["menu-r"]["tools"]) ? '<div class="ws-menu-page-tools"><img src="' . $GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["dir_url"] . '/images/brand-tools.png" alt="." /></div>' . "\n" : '';
306
  /**/
307
  echo ($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["menu-r"]["tips"]) ? '<div class="ws-menu-page-tips"><a href="' . ws_plugin__s2member_parse_readme_value ("Customization URI") . '"><img src="' . $GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["dir_url"] . '/images/brand-tips.png" alt="." /></a></div>' . "\n" : '';
32
  /**/
33
  echo '<div class="ws-menu-page-section ws-plugin--s2member-api-easy-way-section">' . "\n";
34
  echo '<h3>The Extremely Easy Way ( no scripting required )</h3>' . "\n";
35
+ echo '<p>From your s2Member General Options Panel, you may restrict access to certain Posts, Pages, Tags, Categories, and/or URIs based on a Member\'s Level. The s2Member Options Panel makes it easy for you. All you do is type in the basics of what you want to restrict access to, and those sections of your site will be off limits to non-Members. That being said, there are times when you might need to have greater control over which portions of your site can be viewed by non-Members, or Members at different Levels. This is where API Scripting with Advanced Conditionals comes in.</p>' . "\n";
36
  echo '</div>' . "\n";
37
  /**/
38
  echo '</div>' . "\n";
41
  /**/
42
  echo '<div class="ws-menu-page-section ws-plugin--s2member-api-advanced-way-section">' . "\n";
43
  echo '<h3>The Advanced Way ( some PHP scripting required )</h3>' . "\n";
44
+ echo '<p>In an effort to give you even more control over access restrictions, s2Member makes some PHP functions, and also some PHP Constants, available to you from within WordPress®. In this section, we\'ll demonstrate two functions: <strong><code>is_user_logged_in()</code></strong> &amp; <strong><code>current_user_can()</code></strong>. To make use of these functions, please follow our PHP code samples below. Using PHP, you can control access to certain portions of your content, and even build Advanced Conditionals within your content, based on a Members\'s Level. In order to use PHP scripting inside your Posts/Pages, you\'ll need to install this handy plugin ( <a href="http://wordpress.org/extend/plugins/exec-php/" target="_blank" rel="xlink">Exec-PHP</a> ).</p>' . "\n";
45
+ echo '<p><strong>Example #1:</strong> Full access for anyone that is logged in.</strong></p>' . "\n";
46
+ echo '<p>' . highlight_string (file_get_contents (dirname (__FILE__) . "/code-samples/is-user-logged-in.php"), true) . '</p>' . "\n";
47
+ echo '<p><strong>Example #2:</strong> Full access for any Member with a Level >= 1.</strong></p>' . "\n";
48
+ echo '<p>' . highlight_string (file_get_contents (dirname (__FILE__) . "/code-samples/current-user-can-full-access.php"), true) . '</p>' . "\n";
49
+ echo '<p><strong>Example #3:</strong> Specific content for each different Member Level.</strong></p>' . "\n";
50
+ echo '<p>' . highlight_string (file_get_contents (dirname (__FILE__) . "/code-samples/current-user-can-specific-content.php"), true) . '</p>' . "\n";
51
+ echo '<p><strong>Example #4:</strong> Uses s2Member API Constants, instead of functions.</strong></p>' . "\n";
52
+ echo '<p>' . highlight_string (file_get_contents (dirname (__FILE__) . "/code-samples/current-user-can-constants-1.php"), true) . '</p>' . "\n";
53
+ echo '<p><strong>Example #5:</strong> Uses s2Member API Constants, instead of functions.</strong></p>' . "\n";
54
+ echo '<p>' . highlight_string (file_get_contents (dirname (__FILE__) . "/code-samples/current-user-can-constants-2.php"), true) . '</p>' . "\n";
55
+ echo '<p><strong>Membership Levels provide incremental access:</strong></p>' . "\n";
56
+ echo '<p>* A Member with Level 4 access, will also be able to access Levels 1, 2 &amp; 3.<br />* A Member with Level 3 access, will also be able to access Levels 1 &amp; 2.<br />* A Member with Level 2 access, will also be able to access Level 1.<br />* A Member with Level 1 access, will ONLY be able to access Level 1.</p>' . "\n";
57
+ echo '<p><em>* WordPress® Administrators, Editors, Authors, and Contributors have Level 4 access, with respect to s2Member. All of their other Roles/Capabilities are left untouched.</em></p>' . "\n";
58
+ echo '<p><em>* WordPress® Subscribers are NOT allowed Membership access, with respect to s2Member. They must be promoted to a Member. However, if you set `Allow Free Subscribers` to <code>Yes</code>, then Free Subscribers WILL be allowed to access your Login Welcome Page, <strong>but that is all</strong>. See `s2Member -> General Options -> Login Welcome Page` to learn more about this option. If you would like to extend additional access to Free Subscribers ( and/or other Levels ), use the examples above, to customize your Login Welcome Page; based on Membership Level.</em></p>' . "\n";
59
+ echo '</div>' . "\n";
60
+ /**/
61
+ echo '</div>' . "\n";
62
+ /**/
63
+ echo '<div class="ws-menu-page-group" title="Packaging Custom Capabilities">' . "\n";
64
+ /**/
65
+ echo '<div class="ws-menu-page-section ws-plugin--s2member-custom-capabilities-section">' . "\n";
66
+ echo '<h3>Packaging Together Custom Capabilities w/ Membership</h3>' . "\n";
67
+ echo '<p>Using the PayPal® Button Generator for s2Member, you can add Custom Capabilities in comma delimited format. s2Member builds upon existing functionality offered by WordPress® Roles/Capabilities. s2Member supports up to four Primary Roles ( i.e. s2Member Levels 1-4 ). Each s2Member Level provides <code>current_user_can("access_s2member_level1"), 2, 3, 4</code>. These are the default Capabilities that come with each Membership Level. Now... If you\'d like to package together some variations of each Membership Level that you\'re selling, you can! All you do is add some Custom Capabilities whenever you create your PayPal® Button Code ( <em>there is a field in the Button Generator where you can enter Custom Capabilities</em> ). You can sell membership packages that come with Custom Capabilities, and even with custom prices.</p>' . "\n";
68
+ echo '<p>Custom Capabilities are an extension to a feature that already exists in WordPress®. The <code>current_user_can()</code> function, can be used to test for these additional Capabilities that you allow. Whenever a Member completes the checkout process, after having purchased a Membership from you ( one that included Custom Capabilities ), s2Member will add those Custom Capabilities to the account for that specific Member.</p>' . "\n";
69
+ echo '<p>Custom Capabilities are always prepended with <code>access_s2member_ccap_</code>. You fill in the last part, with ONLY lowercase alpha-numerics and/or underscores. For example, let\'s say you want to sell Membership Level #1, as is. But, you also want to sell a slight variation of Membership Level #1, that includes the ability to access the Music &amp; Video sections of your site. So, instead of selling this additional access under a whole new Membership Level, you could just sell a modified version of Membership Level #1. Add the the Custom Capabilities: <code>music,videos</code>. Once a Member has these Capabilities, you can test for these Capabilities using <code>current_user_can("access_s2member_ccap_music")</code> and <code>current_user_can("access_s2member_ccap_videos")</code>.</p>' . "\n";
70
+ /**/
71
+ echo '<div class="ws-menu-page-hr"></div>' . "\n";
72
+ /**/
73
+ echo '<p><strong>Custom Capabilities:</strong> ( music,videos ):</p>' . "\n";
74
+ echo '<p>' . highlight_string (file_get_contents (dirname (__FILE__) . "/code-samples/current-user-can-ccaps-1.php"), true) . '</p>' . "\n";
75
+ /**/
76
+ echo '<p><strong>Custom Capabilities:</strong> ( ebooks,reports,tips ):</p>' . "\n";
77
+ echo '<p>' . highlight_string (file_get_contents (dirname (__FILE__) . "/code-samples/current-user-can-ccaps-2.php"), true) . '</p>' . "\n";
78
+ echo '<div class="ws-menu-page-hr"></div>' . "\n";
79
+ /**/
80
+ echo '<p>The important thing to realize, is that Custom Capabilities, are just that. They\'re custom. s2Member only deals with the default Capabilities that it uses. If you start using Custom Capabilities, you MUST use Advanced Conditionals ( <em>i.e. the <code>current_user_can()</code> function</em> ) to test for them. Either in your theme files, or in Posts/Pages using the <a href="http://wordpress.org/extend/plugins/exec-php/" target="_blank" rel="xlink">Exec-PHP</a> plugin.</p>' . "\n";
81
  echo '</div>' . "\n";
82
  /**/
83
  echo '</div>' . "\n";
86
  /**/
87
  echo '<div class="ws-menu-page-section ws-plugin--s2member-api-advanced-dripping-section">' . "\n";
88
  echo '<h3>Dripping Content ( some PHP scripting required )</h3>' . "\n";
89
+ echo '<p>Content Dripping is the gradual, pre-scheduled release of premium website content to paying Members. This has become increasingly popular, because it allows older Members; those who have paid you more, due to recurring charges; to acquire access to more content progressively; based on their original registration date. It also gives you ( as the site owner ), the ability to launch multiple membership site portals, operating on autopilot, without any direct day-to-day involvement in a content release process. This requires some PHP scripting. In order to use PHP scripting inside your Posts/Pages, you\'ll need to install this handy plugin ( <a href="http://wordpress.org/extend/plugins/exec-php/" target="_blank" rel="xlink">Exec-PHP</a> ).</p>' . "\n";
90
+ echo '<p><strong>To drip content, use <code>S2MEMBER_CURRENT_USER_REGISTRATION_DAYS</code>:</strong></p>' . "\n";
91
+ echo '<p>' . highlight_string (file_get_contents (dirname (__FILE__) . "/code-samples/current-user-registration-days-dripping.php"), true) . '</p>' . "\n";
92
+ echo '</div>' . "\n";
93
+ /**/
94
+ echo '</div>' . "\n";
95
+ /**/
96
+ echo '<div class="ws-menu-page-group" title="Member Profile Modifications">' . "\n";
97
+ /**/
98
+ echo '<div class="ws-menu-page-section ws-plugin--s2member-profile-modifications-section">' . "\n";
99
+ echo '<h3>Giving Members The Ability To Modify Their Profile</h3>' . "\n";
100
+ echo '<p>s2Member can be configured to redirect Members away from the <a href="profile.php" target="_blank" rel="xlink">default Profile Editing Panel</a> that is built into WordPress®. <em>See: <code>s2Member -> General Options -> Profile Modifications</code>.</em> When/if a Member attempts to access the default Profile Editing Panel, they\'ll instead, be redirected to the Login Welcome Page that you\'ve configured through s2Member. <strong>Why would I redirect?</strong> Unless you\'ve made some drastic modifications to your WordPress® installation, the default Profile Editing Panel that ships with WordPress®, is NOT really suited for public access, even by a Member.</p>' . "\n";
101
+ echo '<p>So instead of using this default Profile Editing Panel; s2Member creates an added layer of functionality, on top of WordPress®. It does this by providing you ( as the site owner ), with the ability to send your Members to a <a href="' . get_bloginfo ("url") . '/?s2member_profile=1" target="_blank" rel="xlink">special Stand-Alone page</a>, where your Members can modify their entire Profile, including all Custom Fields, and their Password. This special Stand-Alone Editing Panel, has been designed ( with a bare-bones format ), intentionally. This makes it possible for you to <a href="#" onclick="if(!window.open(\'' . get_bloginfo ("url") . '/?s2member_profile=1\', \'_popup\', \'height=350,width=400,left=100,screenX=100,top=100,screenY=100, location=0,menubar=0,toolbar=0,status=0,scrollbars=1,resizable=1\')) alert(\'Please disable popup blockers and try again!\'); return false;" rel="xlink">open it up in a popup window</a>, or embed it into your Login Welcome Page using an IFRAME. Code samples are provided below.</p>' . "\n";
102
+ /**/
103
+ echo '<div class="ws-menu-page-hr"></div>' . "\n";
104
+ /**/
105
+ echo '<p><strong>S2MEMBER_CURRENT_USER_PROFILE_MODIFICATION_PAGE_URL</strong> = URL to a Stand-Alone Profile Editing Panel.</p>' . "\n";
106
+ echo '<p>Copy &amp; Paste one of the code snippets below, into your Login Welcome Page, so Members can click a link to Edit their Profile. This requires some PHP scripting. In order to use PHP scripting inside your Posts/Pages, you\'ll need to install this handy plugin ( <a href="http://wordpress.org/extend/plugins/exec-php/" target="_blank" rel="xlink">Exec-PHP</a> ).</p>' . "\n";
107
+ /**/
108
+ echo '<div class="ws-menu-page-hr"></div>' . "\n";
109
+ /**/
110
+ echo '<p><strong>Code Sample #1</strong> ( standard link tag ):</p>' . "\n";
111
+ echo '<p>' . highlight_string (file_get_contents (dirname (__FILE__) . "/code-samples/current-user-profile-modification-page-url-1.php"), true) . '</p>' . "\n";
112
+ /**/
113
+ echo '<p><strong>Code Sample #2</strong> ( open the link in a popup window ):</p>' . "\n";
114
+ echo '<p>' . highlight_string (file_get_contents (dirname (__FILE__) . "/code-samples/current-user-profile-modification-page-url-2.php"), true) . '</p>' . "\n";
115
+ /**/
116
+ echo '<p><strong>Code Sample #3</strong> ( embed the form into a Post/Page using an IFRAME tag ):</p>' . "\n";
117
+ echo '<p>' . highlight_string (file_get_contents (dirname (__FILE__) . "/code-samples/current-user-profile-modification-page-url-3.php"), true) . '</p>' . "\n";
118
  echo '</div>' . "\n";
119
  /**/
120
  echo '</div>' . "\n";
123
  /**/
124
  echo '<div class="ws-menu-page-section ws-plugin--s2member-api-constants-section">' . "\n";
125
  echo '<h3>You Have Access To PHP Constants ( some PHP scripting required )</h3>' . "\n";
126
+ echo '<p>A Constant, is an identifier ( name ) for a simple value in PHP scripting. Below is a comprehensive list that includes all of the PHP defined Constants available to you. All of these Constants are also available through JavaScript as Global Variables. Example code has been provided in the documentation below. If you\'re a web developer, we suggest using some of these Constants in the creation of your Login Welcome Page; which is described in the s2Member General Options Panel. It is not required mind you, but you can get pretty creative with the Login Welcome Page, if you know a little PHP.</p>' . "\n";
127
+ echo '<p>For example, you might use `S2MEMBER_CURRENT_USER_ACCESS_LABEL` to display the type of membership the Customer has. Or, you could use `S2MEMBER_CURRENT_USER_PROFILE_MODIFICATION_PAGE_URL` to provide Customers\' with an easy way to update their Membership Profile. If you get stuck on this, you might want to check out Elance.com. You can hire a freelancer to do this for you. It\'s about a $100 job. There are many other possibilities; <em>limitless actually!</em></p>' . "\n";
128
  /**/
129
  echo '<div class="ws-menu-page-hr"></div>' . "\n";
130
  /**/
131
+ echo '<p>Before you read any further, you should install this handy plugin: <a href="http://wordpress.org/extend/plugins/exec-php/" target="_blank" rel="xlink">Exec-PHP</a>.<br />' . "\n";
132
+ echo 'You\'ll need to have this plugin installed to use PHP code in Posts/Pages.</p>' . "\n";
133
  /**/
134
  echo '<div class="ws-menu-page-hr"></div>' . "\n";
135
  /**/
136
+ echo '<p><strong>S2MEMBER_CURRENT_USER_IS_LOGGED_IN</strong><br />This will always be (bool) true or false. True if a User/Member is currently logged in with an Access Level >= 0.</p>' . "\n";
137
+ echo '<p>' . highlight_string (file_get_contents (dirname (__FILE__) . "/code-samples/current-user-is-logged-in.php"), true) . '</p>' . "\n";
138
+ echo '<p><em>See <code>S2MEMBER_CURRENT_USER_ACCESS_LEVEL</code> below for a full explanation.</em></p>' . "\n";
139
  /**/
140
  echo '<div class="ws-menu-page-hr"></div>' . "\n";
141
  /**/
142
+ echo '<p><strong>S2MEMBER_CURRENT_USER_IS_LOGGED_IN_AS_MEMBER</strong><br />This will always be (bool) true or false. True if a Member is currently logged in with an Access Level >= 1.</p>' . "\n";
143
+ echo '<p>' . highlight_string (file_get_contents (dirname (__FILE__) . "/code-samples/current-user-is-logged-in-as-member.php"), true) . '</p>' . "\n";
144
+ echo '<p><em>See <code>S2MEMBER_CURRENT_USER_ACCESS_LEVEL</code> below for a full explanation.</em></p>' . "\n";
145
  /**/
146
  echo '<div class="ws-menu-page-hr"></div>' . "\n";
147
  /**/
148
+ echo '<p><strong>S2MEMBER_CURRENT_USER_ACCESS_LEVEL</strong><br />This will always be (int) -1 thru 4. -1 if not logged in. 0 if logged in as a Free Subscriber.</p>' . "\n";
149
+ echo '<p>' . highlight_string (file_get_contents (dirname (__FILE__) . "/code-samples/current-user-access-level.php"), true) . '</p>' . "\n";
150
+ echo '<p><strong>Membership Levels provide incremental access:</strong></p>' . "\n";
151
+ echo '<p>* A Member with Level 4 access, will also be able to access Levels 1, 2 &amp; 3.<br />* A Member with Level 3 access, will also be able to access Levels 1 &amp; 2.<br />* A Member with Level 2 access, will also be able to access Level 1.<br />* A Member with Level 1 access, will ONLY be able to access Level 1.</p>' . "\n";
152
+ echo '<p><em>* WordPress® Administrators, Editors, Authors, and Contributors have Level 4 access, with respect to s2Member. All of their other Roles/Capabilities are left untouched.</em></p>' . "\n";
153
+ echo '<p><em>* WordPress® Subscribers are NOT allowed Membership access, with respect to s2Member. They must be promoted to a Member. However, if you set `Allow Free Subscribers` to <code>Yes</code>, then Free Subscribers WILL be allowed to access your Login Welcome Page, <strong>but that is all</strong>. See `s2Member -> General Options -> Login Welcome Page` to learn more about this option. If you would like to extend additional access to Free Subscribers ( and/or other Levels ), see: <code>s2Member -> API Scripting -> Advanced Conditionals</code>, for details on how to customize your Login Welcome Page with Conditionals; based on Membership Level.</em></p>' . "\n";
154
  /**/
155
  echo '<div class="ws-menu-page-hr"></div>' . "\n";
156
  /**/
157
+ echo '<p><strong>S2MEMBER_CURRENT_USER_ACCESS_LABEL</strong><br />This will always be a (string). Empty if not logged in.</p>' . "\n";
158
+ echo '<p>' . highlight_string (file_get_contents (dirname (__FILE__) . "/code-samples/current-user-access-label.php"), true) . '</p>' . "\n";
159
  /**/
160
  echo '<div class="ws-menu-page-hr"></div>' . "\n";
161
  /**/
162
+ echo '<p><strong>S2MEMBER_CURRENT_USER_SUBSCR_ID</strong><br />This will always be a (string). Empty if not logged in.</p>' . "\n";
163
+ echo '<p>' . highlight_string (file_get_contents (dirname (__FILE__) . "/code-samples/current-user-subscr-id.php"), true) . '</p>' . "\n";
164
  /**/
165
  echo '<div class="ws-menu-page-hr"></div>' . "\n";
166
  /**/
167
+ echo '<p><strong>S2MEMBER_CURRENT_USER_CUSTOM</strong><br />This will always be a (string). Empty if not logged in.</p>' . "\n";
168
+ echo '<p>' . highlight_string (file_get_contents (dirname (__FILE__) . "/code-samples/current-user-custom.php"), true) . '</p>' . "\n";
169
  /**/
170
  echo '<div class="ws-menu-page-hr"></div>' . "\n";
171
  /**/
172
+ echo '<p><strong>S2MEMBER_CURRENT_USER_REGISTRATION_TIME</strong><br />This will always be an (int); in the form of a Unix timestamp. 0 if not logged in. This holds the recorded time at which the Member originally registered their Username for access to your site. This is useful if you want to drip content over an extended period of time, based on how long someone has been a Member.</p>' . "\n";
173
+ echo '<p>' . highlight_string (file_get_contents (dirname (__FILE__) . "/code-samples/current-user-registration-time.php"), true) . '</p>' . "\n";
174
  /**/
175
  echo '<div class="ws-menu-page-hr"></div>' . "\n";
176
  /**/
177
+ echo '<p><strong>S2MEMBER_CURRENT_USER_REGISTRATION_DAYS</strong><br />This will always be an (int). 0 if not logged in. This is the number of days that have passed since the Member originally registered their Username for access to your site. This is useful if you want to drip content over an extended period of time, based on how long someone has been a Member.</p>' . "\n";
178
+ echo '<p>' . highlight_string (file_get_contents (dirname (__FILE__) . "/code-samples/current-user-registration-days.php"), true) . '</p>' . "\n";
179
  /**/
180
  echo '<div class="ws-menu-page-hr"></div>' . "\n";
181
  /**/
182
+ echo '<p><strong>S2MEMBER_CURRENT_USER_DISPLAY_NAME</strong><br />This will always be a (string). Empty if not logged in.</p>' . "\n";
183
+ echo '<p>' . highlight_string (file_get_contents (dirname (__FILE__) . "/code-samples/current-user-display-name.php"), true) . '</p>' . "\n";
184
  /**/
185
  echo '<div class="ws-menu-page-hr"></div>' . "\n";
186
  /**/
187
+ echo '<p><strong>S2MEMBER_CURRENT_USER_FIRST_NAME</strong><br />This will always be a (string). Empty if not logged in.</p>' . "\n";
188
+ echo '<p>' . highlight_string (file_get_contents (dirname (__FILE__) . "/code-samples/current-user-first-name.php"), true) . '</p>' . "\n";
189
  /**/
190
  echo '<div class="ws-menu-page-hr"></div>' . "\n";
191
  /**/
192
+ echo '<p><strong>S2MEMBER_CURRENT_USER_LAST_NAME</strong><br />This will always be a (string). Empty if not logged in.</p>' . "\n";
193
+ echo '<p>' . highlight_string (file_get_contents (dirname (__FILE__) . "/code-samples/current-user-last-name.php"), true) . '</p>' . "\n";
194
  /**/
195
  echo '<div class="ws-menu-page-hr"></div>' . "\n";
196
  /**/
197
+ echo '<p><strong>S2MEMBER_CURRENT_USER_LOGIN</strong><br />This will always be a (string). Empty if not logged in.</p>' . "\n";
198
+ echo '<p>' . highlight_string (file_get_contents (dirname (__FILE__) . "/code-samples/current-user-login.php"), true) . '</p>' . "\n";
199
  /**/
200
  echo '<div class="ws-menu-page-hr"></div>' . "\n";
201
  /**/
202
+ echo '<p><strong>S2MEMBER_CURRENT_USER_EMAIL</strong><br />This will always be a (string). Empty if not logged in.</p>' . "\n";
203
+ echo '<p>' . highlight_string (file_get_contents (dirname (__FILE__) . "/code-samples/current-user-email.php"), true) . '</p>' . "\n";
204
  /**/
205
  echo '<div class="ws-menu-page-hr"></div>' . "\n";
206
  /**/
207
+ echo '<p><strong>S2MEMBER_CURRENT_USER_IP</strong><br />This will always be a (string). Empty if browsing anonymously.</p>' . "\n";
208
+ echo '<p>' . highlight_string (file_get_contents (dirname (__FILE__) . "/code-samples/current-user-ip.php"), true) . '</p>' . "\n";
209
+ /**/
210
+ echo '<div class="ws-menu-page-hr"></div>' . "\n";
211
+ /**/
212
+ echo '<p><strong>S2MEMBER_CURRENT_USER_ID</strong><br />This will always be an (int). However, it will be 0 if not logged in.</p>' . "\n";
213
+ echo '<p>' . highlight_string (file_get_contents (dirname (__FILE__) . "/code-samples/current-user-id.php"), true) . '</p>' . "\n";
214
+ /**/
215
+ echo '<div class="ws-menu-page-hr"></div>' . "\n";
216
+ /**/
217
+ echo '<p><strong>S2MEMBER_CURRENT_USER_FIELDS</strong><br />This will always be a JSON encoded array, in (string) format. An empty JSON encoded array, in (string) format, if not logged in. This JSON encoded array will contain the following fields: <code>id, ip, email, login, first_name, last_name, display_name, subscr_id, custom</code>. If you\'ve configured additional Custom Fields, those Custom Fields will also be added to this array. For example, if you configured the Custom Field: <code>Street Address</code>, it would be included in this array as: <code>street_address</code>. Custom Field references are converted to lowercase format, and spaces are replaced by underscores. You can do <code>print_r(json_decode(S2MEMBER_CURRENT_USER_FIELDS, true));</code> to get a full list for testing.</p>' . "\n";
218
  if (defined ("BP_VERSION"))
219
  echo '<p><em class="ws-menu-page-error">* Custom Fields are N/A when running together with BuddyPress. Instead, use <code>BuddyPress -> Profile Field Setup</code>.</em></p>' . "\n";
220
+ echo '<p>' . highlight_string (file_get_contents (dirname (__FILE__) . "/code-samples/current-user-fields.php"), true) . '</p>' . "\n";
221
  /**/
222
  echo '<div class="ws-menu-page-hr"></div>' . "\n";
223
  /**/
224
+ echo '<p><strong>S2MEMBER_CURRENT_USER_DOWNLOADS_ALLOWED</strong><br />This will always be an (int) value >= 0 where 0 means no access.</p>' . "\n";
225
+ echo '<p>' . highlight_string (file_get_contents (dirname (__FILE__) . "/code-samples/current-user-downloads-allowed.php"), true) . '</p>' . "\n";
226
  /**/
227
  echo '<div class="ws-menu-page-hr"></div>' . "\n";
228
  /**/
229
+ echo '<p><strong>S2MEMBER_CURRENT_USER_DOWNLOADS_ALLOWED_IS_UNLIMITED</strong><br />This will always be (bool) true or false. A value of true means their allowed downloads are >= 999999999, and false means it is not. This is useful if you are allowing unlimited ( 999999999 ) downloads on some membership levels. You can display `Unlimited` instead of a number.</p>' . "\n";
230
+ echo '<p>' . highlight_string (file_get_contents (dirname (__FILE__) . "/code-samples/current-user-downloads-allowed-is-unlimited.php"), true) . '</p>' . "\n";
231
  /**/
232
  echo '<div class="ws-menu-page-hr"></div>' . "\n";
233
  /**/
234
+ echo '<p><strong>S2MEMBER_CURRENT_USER_DOWNLOADS_CURRENTLY</strong><br />This will always be an (int) value >= 0 where 0 means none.</p>' . "\n";
235
+ echo '<p>' . highlight_string (file_get_contents (dirname (__FILE__) . "/code-samples/current-user-downloads-currently.php"), true) . '</p>' . "\n";
236
  /**/
237
  echo '<div class="ws-menu-page-hr"></div>' . "\n";
238
  /**/
239
+ echo '<p><strong>S2MEMBER_CURRENT_USER_DOWNLOADS_ALLOWED_DAYS</strong><br />This will always be an (int) value >= 0 where 0 means no access.</p>' . "\n";
240
+ echo '<p>' . highlight_string (file_get_contents (dirname (__FILE__) . "/code-samples/current-user-downloads-allowed-days.php"), true) . '</p>' . "\n";
241
  /**/
242
  echo '<div class="ws-menu-page-hr"></div>' . "\n";
243
  /**/
244
+ echo '<p><strong>S2MEMBER_CURRENT_USER_PROFILE_MODIFICATION_PAGE_URL</strong><br />This is where a Member can modify their Profile.</p>' . "\n";
245
+ echo '<p><strong>Code Sample #1</strong> ( standard link ):</p>' . "\n";
246
+ echo '<p>' . highlight_string (file_get_contents (dirname (__FILE__) . "/code-samples/current-user-profile-modification-page-url-1.php"), true) . '</p>' . "\n";
247
+ echo '<p><strong>Code Sample #2</strong> ( open the link in a popup window ):</p>' . "\n";
248
+ echo '<p>' . highlight_string (file_get_contents (dirname (__FILE__) . "/code-samples/current-user-profile-modification-page-url-2.php"), true) . '</p>' . "\n";
249
+ echo '<p><strong>Code Sample #3</strong> ( embed the form into a Post/Page using an IFRAME tag ):</p>' . "\n";
250
+ echo '<p>' . highlight_string (file_get_contents (dirname (__FILE__) . "/code-samples/current-user-profile-modification-page-url-3.php"), true) . '</p>' . "\n";
251
  /**/
252
  echo '<div class="ws-menu-page-hr"></div>' . "\n";
253
  /**/
254
+ echo '<p><strong>S2MEMBER_FILE_DOWNLOAD_LIMIT_EXCEEDED_PAGE_URL</strong><br />This is the full URL to the Limit Exceeded Page ( informational ).</p>' . "\n";
255
+ echo '<p><strong>S2MEMBER_FILE_DOWNLOAD_LIMIT_EXCEEDED_PAGE_ID</strong><br />This is the Page ID that was used to generate the full URL.</p>' . "\n";
256
+ echo '<p>' . highlight_string (file_get_contents (dirname (__FILE__) . "/code-samples/file-download-limit-exceeded-page-url.php"), true) . '</p>' . "\n";
257
  /**/
258
  echo '<div class="ws-menu-page-hr"></div>' . "\n";
259
  /**/
260
+ echo '<p><strong>S2MEMBER_MEMBERSHIP_OPTIONS_PAGE_URL</strong><br />This is the full URL to the Membership Options Page ( the signup page ).</p>' . "\n";
261
+ echo '<p><strong>S2MEMBER_MEMBERSHIP_OPTIONS_PAGE_ID</strong><br />This is the Page ID that was used to generate the full URL.</p>' . "\n";
262
+ echo '<p>' . highlight_string (file_get_contents (dirname (__FILE__) . "/code-samples/membership-options-page-url.php"), true) . '</p>' . "\n";
263
  /**/
264
  echo '<div class="ws-menu-page-hr"></div>' . "\n";
265
  /**/
266
+ echo '<p><strong>S2MEMBER_LOGIN_WELCOME_PAGE_URL</strong><br />This is the full URL to the Login Welcome Page ( the user\'s account page ). * This could also be the full URL to a Special Redirection URL ( if you configured one ). See <code>s2Member -> General Options -> Login Welcome Page</code>.</p>' . "\n";
267
+ echo '<p><strong>S2MEMBER_LOGIN_WELCOME_PAGE_ID</strong><br />This is the Page ID that was used to generate the full URL. * In the case of a Special Redirection URL, this ID is not really applicable.</p>' . "\n";
268
+ echo '<p>' . highlight_string (file_get_contents (dirname (__FILE__) . "/code-samples/login-welcome-page-url.php"), true) . '</p>' . "\n";
269
  /**/
270
  echo '<div class="ws-menu-page-hr"></div>' . "\n";
271
  /**/
272
+ echo '<p><strong>S2MEMBER_LOGIN_PAGE_URL</strong><br />This is the full URL to the Membership Login Page ( the WordPress® login page ).</p>' . "\n";
273
+ echo '<p>' . highlight_string (file_get_contents (dirname (__FILE__) . "/code-samples/login-page-url.php"), true) . '</p>' . "\n";
274
  /**/
275
  echo '<div class="ws-menu-page-hr"></div>' . "\n";
276
  /**/
277
+ echo '<p><strong>S2MEMBER_LOGOUT_PAGE_URL</strong><br />This is the full URL to the Membership Logout Page ( the WordPress® logout page ).</p>' . "\n";
278
+ echo '<p>' . highlight_string (file_get_contents (dirname (__FILE__) . "/code-samples/logout-page-url.php"), true) . '</p>' . "\n";
279
  /**/
280
  echo '<div class="ws-menu-page-hr"></div>' . "\n";
281
  /**/
282
+ echo '<p><strong>S2MEMBER_LEVEL1_LABEL</strong><br />This is the (string) Label that you created for Membership Level 1.</p>' . "\n";
283
+ echo '<p>' . highlight_string (file_get_contents (dirname (__FILE__) . "/code-samples/level1-label.php"), true) . '</p>' . "\n";
284
  /**/
285
  echo '<div class="ws-menu-page-hr"></div>' . "\n";
286
  /**/
287
+ echo '<p><strong>S2MEMBER_LEVEL2_LABEL</strong><br />This is the (string) Label that you created for Membership Level 2.</p>' . "\n";
288
+ echo '<p>' . highlight_string (file_get_contents (dirname (__FILE__) . "/code-samples/level2-label.php"), true) . '</p>' . "\n";
289
  /**/
290
  echo '<div class="ws-menu-page-hr"></div>' . "\n";
291
  /**/
292
+ echo '<p><strong>S2MEMBER_LEVEL3_LABEL</strong><br />This is the (string) Label that you created for Membership Level 3.</p>' . "\n";
293
+ echo '<p>' . highlight_string (file_get_contents (dirname (__FILE__) . "/code-samples/level3-label.php"), true) . '</p>' . "\n";
294
  /**/
295
  echo '<div class="ws-menu-page-hr"></div>' . "\n";
296
  /**/
297
+ echo '<p><strong>S2MEMBER_LEVEL4_LABEL</strong><br />This is the (string) Label that you created for Membership Level 4.</p>' . "\n";
298
+ echo '<p>' . highlight_string (file_get_contents (dirname (__FILE__) . "/code-samples/level4-label.php"), true) . '</p>' . "\n";
299
  /**/
300
  echo '<div class="ws-menu-page-hr"></div>' . "\n";
301
  /**/
302
+ echo '<p><strong>S2MEMBER_LEVEL1_FILE_DOWNLOADS_ALLOWED</strong><br />This is the (int) allowed downloads for Level 1.</p>' . "\n";
303
+ echo '<p>' . highlight_string (file_get_contents (dirname (__FILE__) . "/code-samples/level1-file-downloads-allowed.php"), true) . '</p>' . "\n";
304
  /**/
305
  echo '<div class="ws-menu-page-hr"></div>' . "\n";
306
  /**/
307
+ echo '<p><strong>S2MEMBER_LEVEL2_FILE_DOWNLOADS_ALLOWED</strong><br />This is the (int) allowed downloads for Level 2.</p>' . "\n";
308
+ echo '<p>' . highlight_string (file_get_contents (dirname (__FILE__) . "/code-samples/level2-file-downloads-allowed.php"), true) . '</p>' . "\n";
309
  /**/
310
  echo '<div class="ws-menu-page-hr"></div>' . "\n";
311
  /**/
312
+ echo '<p><strong>S2MEMBER_LEVEL3_FILE_DOWNLOADS_ALLOWED</strong><br />This is the (int) allowed downloads for Level 3.</p>' . "\n";
313
+ echo '<p>' . highlight_string (file_get_contents (dirname (__FILE__) . "/code-samples/level3-file-downloads-allowed.php"), true) . '</p>' . "\n";
314
  /**/
315
  echo '<div class="ws-menu-page-hr"></div>' . "\n";
316
  /**/
317
+ echo '<p><strong>S2MEMBER_LEVEL4_FILE_DOWNLOADS_ALLOWED</strong><br />This is the (int) allowed downloads for Level 4.</p>' . "\n";
318
+ echo '<p>' . highlight_string (file_get_contents (dirname (__FILE__) . "/code-samples/level4-file-downloads-allowed.php"), true) . '</p>' . "\n";
319
  /**/
320
  echo '<div class="ws-menu-page-hr"></div>' . "\n";
321
  /**/
322
+ echo '<p><strong>S2MEMBER_LEVEL1_FILE_DOWNLOADS_ALLOWED_DAYS</strong><br />This is the (int) allowed download days for Level 1.</p>' . "\n";
323
+ echo '<p>' . highlight_string (file_get_contents (dirname (__FILE__) . "/code-samples/level1-file-downloads-allowed-days.php"), true) . '</p>' . "\n";
324
  /**/
325
  echo '<div class="ws-menu-page-hr"></div>' . "\n";
326
  /**/
327
+ echo '<p><strong>S2MEMBER_LEVEL2_FILE_DOWNLOADS_ALLOWED_DAYS</strong><br />This is the (int) allowed download days for Level 2.</p>' . "\n";
328
+ echo '<p>' . highlight_string (file_get_contents (dirname (__FILE__) . "/code-samples/level2-file-downloads-allowed-days.php"), true) . '</p>' . "\n";
329
  /**/
330
  echo '<div class="ws-menu-page-hr"></div>' . "\n";
331
  /**/
332
+ echo '<p><strong>S2MEMBER_LEVEL3_FILE_DOWNLOADS_ALLOWED_DAYS</strong><br />This is the (int) allowed download days for Level 3.</p>' . "\n";
333
+ echo '<p>' . highlight_string (file_get_contents (dirname (__FILE__) . "/code-samples/level3-file-downloads-allowed-days.php"), true) . '</p>' . "\n";
334
  /**/
335
  echo '<div class="ws-menu-page-hr"></div>' . "\n";
336
  /**/
337
+ echo '<p><strong>S2MEMBER_LEVEL4_FILE_DOWNLOADS_ALLOWED_DAYS</strong><br />This is the (int) allowed download days for Level 4.</p>' . "\n";
338
+ echo '<p>' . highlight_string (file_get_contents (dirname (__FILE__) . "/code-samples/level4-file-downloads-allowed-days.php"), true) . '</p>' . "\n";
339
  /**/
340
  echo '<div class="ws-menu-page-hr"></div>' . "\n";
341
  /**/
342
+ echo '<p><strong>S2MEMBER_REG_EMAIL_FROM_NAME</strong><br />This is the Name that outgoing email messages are sent by.</p>' . "\n";
343
+ echo '<p>' . highlight_string (file_get_contents (dirname (__FILE__) . "/code-samples/reg-email-from-name.php"), true) . '</p>' . "\n";
344
  /**/
345
  echo '<div class="ws-menu-page-hr"></div>' . "\n";
346
  /**/
347
+ echo '<p><strong>S2MEMBER_REG_EMAIL_FROM_EMAIL</strong><br />This is the Email Address that outgoing messages are sent by.</p>' . "\n";
348
+ echo '<p>' . highlight_string (file_get_contents (dirname (__FILE__) . "/code-samples/reg-email-from-email.php"), true) . '</p>' . "\n";
349
  /**/
350
  echo '<div class="ws-menu-page-hr"></div>' . "\n";
351
  /**/
352
+ echo '<p><strong>S2MEMBER_PAYPAL_NOTIFY_URL</strong><br />This is the URL on your system that receives PayPal® IPN responses.</p>' . "\n";
353
+ echo '<p>' . highlight_string (file_get_contents (dirname (__FILE__) . "/code-samples/paypal-notify-url.php"), true) . '</p>' . "\n";
354
  /**/
355
  echo '<div class="ws-menu-page-hr"></div>' . "\n";
356
  /**/
357
+ echo '<p><strong>S2MEMBER_PAYPAL_RETURN_URL</strong><br />This is the URL on your system that receives PayPal® return variables.</p>' . "\n";
358
+ echo '<p>' . highlight_string (file_get_contents (dirname (__FILE__) . "/code-samples/paypal-return-url.php"), true) . '</p>' . "\n";
359
  /**/
360
  echo '<div class="ws-menu-page-hr"></div>' . "\n";
361
  /**/
362
+ echo '<p><strong>S2MEMBER_PAYPAL_ENDPOINT</strong><br />This is the Endpoint Domain to the PayPal® server.</p>' . "\n";
363
+ echo '<p>' . highlight_string (file_get_contents (dirname (__FILE__) . "/code-samples/paypal-endpoint.php"), true) . '</p>' . "\n";
364
  /**/
365
  echo '<div class="ws-menu-page-hr"></div>' . "\n";
366
  /**/
367
+ echo '<p><strong>S2MEMBER_PAYPAL_BUSINESS</strong><br />This is the Email Address that identifies your PayPal® Business.</p>' . "\n";
368
+ echo '<p>' . highlight_string (file_get_contents (dirname (__FILE__) . "/code-samples/paypal-business.php"), true) . '</p>' . "\n";
369
+ /**/
370
+ echo '<div class="ws-menu-page-hr"></div>' . "\n";
371
+ /**/
372
+ echo '<p><strong>S2MEMBER_CURRENT_USER_VALUE_FOR_PP_ON0</strong><br />This auto-fills the <code>on0</code> value in PayPal® Button Codes.<br />If a Button Code is presented to a logged-in Member, this will auto-fill the value for the <code>on0</code> input variable, with the string: <code>"Updating Subscr"</code>. Otherwise, it will be an empty string.</p>' . "\n";
373
+ echo '<p><strong>S2MEMBER_CURRENT_USER_VALUE_FOR_PP_OS0</strong><br />This auto-fills the <code>os0</code> value in PayPal® Button Codes.<br />If a Button Code is presented to a logged-in Member, this will auto-fill the value for the <code>os0</code> input variable, with the value of <code>S2MEMBER_CURRENT_USER_SUBSCR_ID</code>. Otherwise, it will be an empty string.</p>' . "\n";
374
+ echo '<p>These two Constants are special. They are used by the PayPal® Button Generator for s2Member. This is how s2Member identifies an existing Member ( and/or a Free Subscriber ), who is already logged in when they click a PayPal® Modification Button that was generated for you by s2Member. Instead of forcing a Member ( and/or a Free Subscriber ) to re-register for a new account, s2Member can identify their existing account, and update it, according to the modified terms in your Button Code. These three Button Code parameters: <code>on0, os0, modify</code>, work together in harmony. If you\'re using the Shortcode Format for PayPal® Buttons ( recommended ), you won\'t even see these, because they\'re added internally by the Shortcode processor. Anyway, they\'re just documented here for clarity; you probably won\'t use these directly; the Button Code Generator pops them in.</p>' . "\n";
375
+ echo '<p><em>' . highlight_string (file_get_contents (dirname (__FILE__) . "/code-samples/current-user-value-for-pp-on0-os0.php"), true) . '</em></p>' . "\n";
376
+ echo '<p>If you\'d like to give your Members ( and/or your Free Subscribers ) the ability to modify their billing plan, by switching to a more expensive option, or a less expensive option; generate a new PayPal® Modification Button, using the s2Member PayPal® Button Generator. Configure the updated Level, pricing, terms, etc. Then, make that new Modification Button available to Members who are logged into their existing account with you. For example, you might want to insert a "Level #2" Upgrade Button into your Login Welcome Page, which would up-sell existing Level #1 Members to a more expensive plan that you offer.</p>' . "\n";
377
+ echo '<p><em><strong>*Modification Process*</strong> When you send a Member to PayPal® using a Subscription Modification Button, PayPal® will ask them to login. Once they\'re logged in, instead of being able to signup for a new membership, PayPal® will provide them with the ability to upgrade and/or downgrade their existing membership with you, by allowing them to switch to the Membership Plan that was specified in the Subscription Modification Button. PayPal® handles this nicely, and you\'ll be happy to know that s2Member has been pre-configured to deal with this scenario as well, so that everything remains automated. Their Membership Access Level will either be promoted, or demoted, based on the actions they took at PayPal® during the modification process. Once an existing Member completes their Subscription Modification at PayPal®, they\'ll be brought back to their Login Welcome Page, instead of the registration screen.</em></p>' . "\n";
378
+ echo '<p><em><strong>*Also Works For Free Subscribers*</strong> Although a Free Subscriber does not have an existing PayPal® subscription, s2Member is capable of adapting to this scenario gracefully. Just make sure that your existing Free Subscribers ( the ones who wish to upgrade ) pay for their Membership through a Modification Button generated by s2Member. That will allow them to continue using their existing account with you. In other words, they can keep their existing Username ( and anything already associated with that Username ), rather than being forced to re-register after checkout.</em></p>' . "\n";
379
+ echo '<p><em><strong>*Make It More User-Friendly*</strong> You can make the Subscription Modification Process, more user-friendly, by setting up a <a href="#" onclick="alert(\'Optional. This can be configured inside your PayPal® account. PayPal® allows you to create Custom Page Styles, and assign a unique name to them. You can add your own header image and color selection to the checkout form. Once you\\\'ve created a Custom Page Style at PayPal®, you can tell s2Member to use that Page Style whenever you generate your Button Code. See: s2Member® -> PayPal Buttons.\'); return false;">Custom Page Style at PayPal®</a>, specifically for Subscription Modification Buttons. Use a custom header image, with a brief explanation to the Customer. Something like, "Log into PayPal®", "You can Modify your Subscription!".</em></p>' . "\n";
380
+ echo '<p><em><strong>*Conditional Upgrades*</strong> You could also use the API Constant <code>S2MEMBER_CURRENT_USER_ACCESS_LEVEL</code> to build Conditionals that display a specific Modification Button, based on the Membership Level of the currently logged-in Member. This can help you maximize your marketing efforts. In other words, instead of just throwing a single Modification Button out there to everyone, get specific if you need to!</em></p>' . "\n";
381
+ echo '<p>' . highlight_string (file_get_contents (dirname (__FILE__) . "/code-samples/current-user-access-level-conditional-upgrades.php"), true) . '</p>' . "\n";
382
  /**/
383
  echo '</div>' . "\n";
384
  /**/
387
  echo '<div class="ws-menu-page-group" title="s2Member JS/API Globals">' . "\n";
388
  /**/
389
  echo '<div class="ws-menu-page-section ws-plugin--s2member-api-js-globals-section">' . "\n";
390
+ echo '<h3>You Also Have Access To JS Globals ( some JavaScript knowledge required )</h3>' . "\n";
391
+ echo '<p>All of the PHP Constants, are also available through JavaScript, as Global Variables ( with the exact same names/types as their PHP counterparts ). s2Member automatically loads it\'s compressed JavaScript API ( only 2kbs ) into your theme for WordPress®. s2Member is very intelligent about the way it loads ( and maintains ) it\'s JavaScript API. You can rely on the JavaScript Globals, the same way you rely on PHP Constants.</p>' . "\n";
392
  echo '</div>' . "\n";
393
  /**/
394
  echo '</div>' . "\n";
397
  /**/
398
  echo '<td class="ws-menu-page-table-r">' . "\n";
399
  /**/
400
+ echo ($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["menu-r"]["installation"]) ? '<div class="ws-menu-page-installation"><a href="' . ws_plugin__s2member_parse_readme_value ("Professional Installation URI") . '"><img src="' . $GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["dir_url"] . '/images/brand-installation.png" alt="." title="Contact PriMoThemes!" /></a></div>' . "\n" : '';
401
+ /**/
402
  echo ($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["menu-r"]["tools"]) ? '<div class="ws-menu-page-tools"><img src="' . $GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["dir_url"] . '/images/brand-tools.png" alt="." /></div>' . "\n" : '';
403
  /**/
404
  echo ($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["menu-r"]["tips"]) ? '<div class="ws-menu-page-tips"><a href="' . ws_plugin__s2member_parse_readme_value ("Customization URI") . '"><img src="' . $GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["dir_url"] . '/images/brand-tips.png" alt="." /></a></div>' . "\n" : '';
includes/menu-pages/shortcode.html CHANGED
@@ -1 +1 @@
1
- [s2Member-PayPal-Button level="%%level%%" ps="paypal" cc="USD" on0="" os0="" modify="0" custom="%%domain%%" tp="0" tt="D" ra="0.01" rp="1" rt="M" rr="1" /]
1
+ [s2Member-PayPal-Button level="%%level%%" ccaps="" desc="%%level_label%%" ps="paypal" cc="USD" custom="%%domain%%" tp="0" tt="D" ra="0.01" rp="1" rt="M" rr="1" /]
includes/menu-pages/sp-button.html ADDED
@@ -0,0 +1,20 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <form action="https://%%endpoint%%/cgi-bin/webscr" method="post">
2
+ <input type="hidden" name="business" value="%%paypal_business%%" />
3
+ <input type="hidden" name="cmd" value="_xclick" />
4
+ <!-- Instant Payment Notification & Return Page Details -->
5
+ <input type="hidden" name="notify_url" value="%%notify_url%%" />
6
+ <input type="hidden" name="cancel_return" value="%%cancel_return%%" />
7
+ <input type="hidden" name="return" value="%%return%%" />
8
+ <input type="hidden" name="rm" value="2" />
9
+ <!-- Configures All Of The Checkout Fields -->
10
+ <input type="hidden" name="no_shipping" value="1" />
11
+ <input type="hidden" name="no_note" value="1" />
12
+ <input type="hidden" name="custom" value="%%domain%%" />
13
+ <input type="hidden" name="currency_code" value="USD" />
14
+ <input type="hidden" name="page_style" value="paypal" />
15
+ <input type="hidden" name="item_name" value="Single-Page Access" />
16
+ <input type="hidden" name="item_number" value="sp:0" />
17
+ <input type="hidden" name="amount" value="0.01" />
18
+ <!-- Displays The PayPal® Image Button -->
19
+ <input type="image" alt="PayPal®" style="border:0;" src="https://www.paypal.com/en_US/i/btn/btn_xpressCheckout.gif" />
20
+ </form>
includes/menu-pages/sp-shortcode.html ADDED
@@ -0,0 +1 @@
 
1
+ [s2Member-PayPal-Button page="0" desc="Single-Page Access" ps="paypal" cc="USD" custom="%%domain%%" ra="0.01" sp="1" /]
includes/menu-pages/start.inc.php ADDED
@@ -0,0 +1,147 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /*
3
+ Copyright: © 2009 WebSharks, Inc. ( coded in the USA )
4
+ <mailto:support@websharks-inc.com> <http://www.websharks-inc.com/>
5
+
6
+ Released under the terms of the GNU General Public License.
7
+ You should have received a copy of the GNU General Public License,
8
+ along with this software. In the main directory, see: /licensing/
9
+ If not, see: <http://www.gnu.org/licenses/>.
10
+ */
11
+ /*
12
+ Direct access denial.
13
+ */
14
+ if (realpath (__FILE__) === realpath ($_SERVER["SCRIPT_FILENAME"]))
15
+ exit;
16
+ /*
17
+ Flow Of Events page.
18
+ */
19
+ echo '<div class="wrap ws-menu-page">' . "\n";
20
+ /**/
21
+ echo '<div id="icon-plugins" class="icon32"><br /></div>' . "\n";
22
+ echo '<h2><div>Developed by <a href="' . ws_plugin__s2member_parse_readme_value ("Plugin URI") . '"><img src="' . $GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["dir_url"] . '/images/brand-light.png" alt="." /></a></div>s2Member / Quick Start Guide</h2>' . "\n";
23
+ /**/
24
+ echo '<div class="ws-menu-page-hr"></div>' . "\n";
25
+ /**/
26
+ echo '<table class="ws-menu-page-table">' . "\n";
27
+ echo '<tbody class="ws-menu-page-table-tbody">' . "\n";
28
+ echo '<tr class="ws-menu-page-table-tr">' . "\n";
29
+ echo '<td class="ws-menu-page-table-l">' . "\n";
30
+ /**/
31
+ echo '<div class="ws-menu-page-group" title="The Registration Process" default-state="open">' . "\n";
32
+ /**/
33
+ echo '<div class="ws-menu-page-section ws-plugin--s2member-registration-process-section">' . "\n";
34
+ echo '<h3>The Subscription Signup/Registration Process</h3>' . "\n";
35
+ echo '<p>1. Internet Users will go to your Membership Options Page ( which you\'ll need to configure on the s2Member General Options panel ). On this Membership Options Page, that YOU will create in WordPress®, you\'ll insert the PayPal® Subscription Buttons that were generated for you by s2Member.</p>' . "\n";
36
+ echo '<p>2. An Internet User will click on a PayPal® Subscription Button from your Membership Options Page. They will be transferred over to PayPal® in order to agree to your membership terms and pricing. You can customize the Checkout Page Style, Pricing, Payment Periods, and more whenever you generate your PayPal® Buttons through s2Member.</p>' . "\n";
37
+ echo '<p>3. Once a User has completed the Subscription Signup Process at PayPal®, they\'ll be returned to your site, where they\'ll be activated by s2Member instantly, and given the opportunity to register a Username &amp; Password for their membership. ( Note: they\'ll be allowed to register a Username &amp; Password, even if you\'ve set \'Anyone Can Register\' to `Off` in your General WordPress® options; because s2Member identifies the User as having paid for membership access through PayPal® ). s2Member will also send the User an email with instructions on how to register their Username &amp; Password, just in case they missed the instructions after checkout. That email will be sent to their PayPal® email address; and it will be sent even if they never returned to your site after checkout for some reason. Much of this is handled through the PayPal® IPN service behind the scenes, where PayPal® and s2Member communicate with each other.</p>' . "\n";
38
+ echo '<p>4. Once a User has completed checkout and registered a Username &amp; Password, they\'ll be able to login. The first page they\'ll see after logging in, will be your Login Welcome Page ( which you\'ll need to configure on the s2Member General Options panel ). Your Login Welcome Page can contain whatever you like. You\'ll need to design this Page in WordPress®, and be creative!</p>' . "\n";
39
+ echo '</div>' . "\n";
40
+ /**/
41
+ echo '</div>' . "\n";
42
+ /**/
43
+ echo '<div class="ws-menu-page-group" title="Your Login/Registration Form">' . "\n";
44
+ /**/
45
+ echo '<div class="ws-menu-page-section ws-plugin--s2member-login-reg-form-section">' . "\n";
46
+ echo '<h3>Your Login/Registration Form ( already built-in )</h3>' . "\n";
47
+ echo '<p>s2Member uses the existing WordPress® Login/Registration system. This is the same Login/Registration Form that you use to access your WP® Dashboard. However, with s2Member installed, your Login/Registration forms can be customized. <em>See: <code>s2Member -> General Options -> Login/Registration Design</code>.</em> With s2Member installed, you can make the default Login/Registration forms, more presentable, for public access. Change the background color/image, your logo image, add Custom Fields, and more<em>!</em></p>' . "\n";
48
+ echo '<p>Since s2Member uses the default Login/Registration system for WordPress®, s2Member is also compatible with themes, and other plugins ( such as BuddyPress ). If your theme has a Login form built-in already, chances are, it\'s perfectly compatible with s2Member.</p>' . "\n";
49
+ echo '</div>' . "\n";
50
+ /**/
51
+ echo '</div>' . "\n";
52
+ /**/
53
+ echo '<div class="ws-menu-page-group" title="Your Login Welcome Page">' . "\n";
54
+ /**/
55
+ echo '<div class="ws-menu-page-section ws-plugin--s2member-login-welcome-page-section">' . "\n";
56
+ echo '<h3>Your Login Welcome Page ( you create this in WordPress® )</h3>' . "\n";
57
+ echo '<p>YOU, will create this special Page in WordPress®. This is a "Page", not a Post. This is the first page Members will see after logging into your site. You should go ahead and create an empty Page now, before you start configuring everything. Title it: <code>My Login Welcome Page</code>, and then click Publish. Once you have your s2Member -> General Options configured, and you\'ve got a good understanding for how things work, go back and customize the title and content for this Page. You\'ll want to be creative with your Login Welcome Page. However, you should configure your General Options first, and test things out. That way you\'ll understand why this Page is important.</p>' . "\n";
58
+ echo '</div>' . "\n";
59
+ /**/
60
+ echo '</div>' . "\n";
61
+ /**/
62
+ echo '<div class="ws-menu-page-group" title="Your Membership Options Page">' . "\n";
63
+ /**/
64
+ echo '<div class="ws-menu-page-section ws-plugin--s2member-membership-options-page-section">' . "\n";
65
+ echo '<h3>Your Membership Options Page ( you create this in WordPress® )</h3>' . "\n";
66
+ echo '<p>YOU, will create this special Page in WordPress®. This is a "Page", not a Post. s2Member comes with a PayPal® Button Generator. You will generate PayPal® Buttons with s2Member, for each Membership Level that you plan to offer. Those buttons will be inserted into your Membership Options Page. If a User in the general public, attempts to access an area of your site that is being protected by s2Member ( based on your configuration ), s2Member will redirect the User to your Membership Options Page, where they can signup through PayPal® and become a Member.</p>' . "\n";
67
+ echo '<p>You should go ahead and create an empty Page now, before you start configuring everything. Title it: <code>My Membership Options Page</code>, and then click Publish. Once you have your s2Member -> General Options configured, and you\'ve got a good understanding for how things work, go back and customize the title and content for this Page. You\'ll want to be creative with your Membership Options Page. However, you should configure your General Options first, and test things out. That way you\'ll understand why this Page is important.</p>' . "\n";
68
+ echo '</div>' . "\n";
69
+ /**/
70
+ echo '</div>' . "\n";
71
+ /**/
72
+ echo '<div class="ws-menu-page-group" title="Your s2Member -> General Options">' . "\n";
73
+ /**/
74
+ echo '<div class="ws-menu-page-section ws-plugin--s2member-general-options-section">' . "\n";
75
+ echo '<h3>Your s2Member -> General Options ( basic configuration )</h3>' . "\n";
76
+ echo '<p>Once you have a Login Welcome Page, and a Membership Options Page. Go to: <code>s2Member -> General Options</code>.</p>' . "\n";
77
+ echo '<p>From your s2Member General Options Panel, you may restrict access to certain Posts, Pages, Tags, Categories, and/or URIs based on a Member\'s Level. The s2Member Options Panel makes it easy for you. All you do is type in the basics of what you want to restrict access to, and those sections of your site will be off limits to non-Members. That being said, there are times when you might need to have greater control over which portions of your site can be viewed by non-Members, or Members at different Levels. This is where API Scripting with Advanced Conditionals comes in. <em>For more information, see: <code>s2Member -> API Scripting</code></em>.</p>' . "\n";
78
+ echo '</div>' . "\n";
79
+ /**/
80
+ echo '</div>' . "\n";
81
+ /**/
82
+ 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 scenes.</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>You may also want to 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 `Single-Page` notifications that are available to you through the s2Member API. These make it possible to integrate with 3rd party applications; like affiliate programs, list servers, and other back-office routines.</p>' . "\n";
89
+ echo '</div>' . "\n";
90
+ /**/
91
+ echo '<div class="ws-menu-page-hr ws-plugin--s2member-automation-hairy-details-section-hr"></div>' . "\n";
92
+ /**/
93
+ echo '<div class="ws-menu-page-section ws-plugin--s2member-automation-hairy-details-section">' . "\n";
94
+ echo '<h3>Subscription Cancellations / Some Hairy Details With Dates</h3>' . "\n";
95
+ echo '<p>There might be times whenever you notice that a Members\'s subscription has been canceled through PayPal®... but, s2Member continues to allow the User to access 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 the SUBSCR_EOT notification via the IPN service. PayPal® will sometimes wait to send this SUBSCR_EOT notification 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, and PayPal® will send the SUBSCR_EOT notification to s2Member. 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 ).</p>' . "\n";
96
+ echo '</div>' . "\n";
97
+ /**/
98
+ echo '</div>' . "\n";
99
+ /**/
100
+ echo '<div class="ws-menu-page-group" title="Upgrading/Downgrading Accounts">' . "\n";
101
+ /**/
102
+ echo '<div class="ws-menu-page-section ws-plugin--s2member-upgrading-downgrading-section">' . "\n";
103
+ echo '<h3>Upgrading And/Or Downgrading User Accounts</h3>' . "\n";
104
+ echo '<p>s2Member builds upon existing functionality offered through WordPress® Roles and Capabilities. From your WordPress® Dashboard, go to: <code>Users -> Authors &amp; Users</code>. You can use the bulk actions to modify Member Access Levels all at once, or click on an individual Member account to modify only their specific Access Level. If you want to temporarily demote a Member so they cannot access membership privileges, set their Role to Subscriber. When you\'re ready to give them their membership privileges back, change their Role back to one of the s2Member Levels.</p>' . "\n";
105
+ echo '<p>All financial details, such as pricing, trial periods, subscription lengths, refunds, and other Customer service issues; should be handled by YOU, through your PayPal® account, and NOT through WordPress®. Feel free to modify your Members\' Subscriptions via PayPal® as often as you like. s2Member will be notified through the PayPal® IPN service behind the scenes automatically. For example... If you log into PayPal® and cancel a Members\'s paid Subscription, s2Member will be notified by PayPal® behind the scenes, and s2Member will remove their membership privileges at the correct point in time.</p>' . "\n";
106
+ echo '<p>That being said, if you log into your WordPress® Dashboard and delete a Member\'s account, you will still need to log into PayPal® and cancel billing for the account you deleted. In other words, s2Member can be notified automatically about actions you take inside PayPal\'s interface, but PayPal® CANNOT be notified of actions you take inside your WordPress® Dashboard. At least, not in an automated fashion, as that would create a security issue for PayPal®. So... automation works seamlessly from PayPal® -> to s2Member, but NOT the other way around.</p>' . "\n";
107
+ echo '</div>' . "\n";
108
+ /**/
109
+ echo '<div class="ws-menu-page-hr ws-plugin--s2member-subscription-modification-section-hr"></div>' . "\n";
110
+ /**/
111
+ echo '<div class="ws-menu-page-section ws-plugin--s2member-subscription-modification-section">' . "\n";
112
+ echo '<h3>Giving Members The Ability To Modify Their Own Subscription</h3>' . "\n";
113
+ echo '<p>If you\'d like to give your Members ( and/or your Free Subscribers ) the ability to modify their billing plan, by switching to a more expensive option, or a less expensive option; generate a new PayPal® Modification Button, using the s2Member PayPal® Button Generator. Configure the updated Level, pricing, terms, etc. Then, make that new Modification Button available to Members who are logged into their existing account with you. For example, you might want to insert a "Level #2" Upgrade Button into your Login Welcome Page, which would up-sell existing Level #1 Members to a more expensive plan that you offer.</p>' . "\n";
114
+ echo '<p><em><strong>*Modification Process*</strong> When you send a Member to PayPal® using a Subscription Modification Button, PayPal® will ask them to login. Once they\'re logged in, instead of being able to signup for a new membership, PayPal® will provide them with the ability to upgrade and/or downgrade their existing membership with you, by allowing them to switch to the Membership Plan that was specified in the Subscription Modification Button. PayPal® handles this nicely, and you\'ll be happy to know that s2Member has been pre-configured to deal with this scenario as well, so that everything remains automated. Their Membership Access Level will either be promoted, or demoted, based on the actions they took at PayPal® during the modification process. Once an existing Member completes their Subscription Modification at PayPal®, they\'ll be brought back to their Login Welcome Page, instead of the registration screen.</em></p>' . "\n";
115
+ echo '<p><em><strong>*Also Works For Free Subscribers*</strong> Although a Free Subscriber does not have an existing PayPal® subscription, s2Member is capable of adapting to this scenario gracefully. Just make sure that your existing Free Subscribers ( the ones who wish to upgrade ) pay for their Membership through a Modification Button generated by s2Member. That will allow them to continue using their existing account with you. In other words, they can keep their existing Username ( and anything already associated with that Username ), rather than being forced to re-register after checkout.</em></p>' . "\n";
116
+ echo '<p><em><strong>*Make It More User-Friendly*</strong> You can make the Subscription Modification Process, more user-friendly, by setting up a <a href="#" onclick="alert(\'Optional. This can be configured inside your PayPal® account. PayPal® allows you to create Custom Page Styles, and assign a unique name to them. You can add your own header image and color selection to the checkout form. Once you\\\'ve created a Custom Page Style at PayPal®, you can tell s2Member to use that Page Style whenever you generate your Button Code. See: s2Member® -> PayPal Buttons.\'); return false;">Custom Page Style at PayPal®</a>, specifically for Subscription Modification Buttons. Use a custom header image, with a brief explanation to the Customer. Something like, "Log into PayPal®", "You can Modify your Subscription!".</em></p>' . "\n";
117
+ echo '</div>' . "\n";
118
+ /**/
119
+ echo '<div class="ws-menu-page-hr ws-plugin--s2member-subscription-modification-section-hr"></div>' . "\n";
120
+ /**/
121
+ echo '<div class="ws-menu-page-section ws-plugin--s2member-subscription-modification-section">' . "\n";
122
+ echo '<h3>Upgrading Free Subscribers To Paid Members ( same technique )</h3>' . "\n";
123
+ echo '<p>Same technique as above. This also works for Free Subscribers. Although a Free Subscriber does not have an existing PayPal® subscription, s2Member is capable of adapting to this scenario gracefully. Just make sure that your existing Free Subscribers ( the ones who wish to upgrade ) pay for their Membership through a Modification Button generated by s2Member. That will allow them to continue using their existing account with you. In other words, they can keep their existing Username ( and anything already associated with that Username ), rather than being forced to re-register after checkout.</p>' . "\n";
124
+ echo '</div>' . "\n";
125
+ /**/
126
+ echo '</div>' . "\n";
127
+ /**/
128
+ echo '</td>' . "\n";
129
+ /**/
130
+ echo '<td class="ws-menu-page-table-r">' . "\n";
131
+ /**/
132
+ echo ($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["menu-r"]["installation"]) ? '<div class="ws-menu-page-installation"><a href="' . ws_plugin__s2member_parse_readme_value ("Professional Installation URI") . '"><img src="' . $GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["dir_url"] . '/images/brand-installation.png" alt="." title="Contact PriMoThemes!" /></a></div>' . "\n" : '';
133
+ /**/
134
+ echo ($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["menu-r"]["tools"]) ? '<div class="ws-menu-page-tools"><img src="' . $GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["dir_url"] . '/images/brand-tools.png" alt="." /></div>' . "\n" : '';
135
+ /**/
136
+ echo ($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["menu-r"]["tips"]) ? '<div class="ws-menu-page-tips"><a href="' . ws_plugin__s2member_parse_readme_value ("Customization URI") . '"><img src="' . $GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["dir_url"] . '/images/brand-tips.png" alt="." /></a></div>' . "\n" : '';
137
+ /**/
138
+ echo ($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["menu-r"]["donations"]) ? '<div class="ws-menu-page-donations"><a href="' . ws_plugin__s2member_parse_readme_value ("Donate link") . '"><img src="' . $GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["dir_url"] . '/images/brand-donations.jpg" alt="." /></a></div>' . "\n" : '';
139
+ /**/
140
+ echo '</td>' . "\n";
141
+ /**/
142
+ echo '</tr>' . "\n";
143
+ echo '</tbody>' . "\n";
144
+ echo '</table>' . "\n";
145
+ /**/
146
+ echo '</div>' . "\n";
147
+ ?>
includes/menu-pages/trk-ops.inc.php CHANGED
@@ -32,20 +32,20 @@ echo '<form method="post" name="ws_plugin__s2member_options_form" id="ws-plugin-
32
  echo '<input type="hidden" name="ws_plugin__s2member_options_save" id="ws-plugin--s2member-options-save" value="' . esc_attr (wp_create_nonce ("ws-plugin--s2member-options-save")) . '" />' . "\n";
33
  echo '<input type="hidden" name="ws_plugin__s2member_configured" id="ws-plugin--s2member-configured" value="1" />' . "\n";
34
  /**/
35
- echo '<div class="ws-menu-page-group" title="Pixel Tracking Code Snippets">' . "\n";
36
  /**/
37
- echo '<div class="ws-menu-page-section ws-plugin--s2member-pixel-tracking-section">' . "\n";
38
- echo '<h3>Pixel Tracking Codes ( optional, these will be injected into the Signup Confirmation Page )</h3>' . "\n";
39
- echo '<p>If you use affiliate software, have tracking codes from advertising networks, or the like, you\'ll want to read this section. The HTML code that you enter below, will be loaded up in a web browser, whenever a Customer lands on the Signup Confirmation Page after checkout. The s2Member (built-in) Signup Confirmation Page ( also known as a Thank-You Page ), is really just a blank page that alerts the Customer via JavaScript. It says: `Thank You! Your membership has been approved.`. Then it says: `The next step is to Register a Username. Please click OK to be redirected.`. After they\'ve clicked OK on this alert, and after everything ( if there is anything ) on the blank page has finished loading, they\'ll be redirected to the Registration system, where they will be able to setup their Username and login for the first time. This process has been fully automated, very simple.</p>' . "\n";
40
- echo '<p>Now, if you want to track the performance of your marketing efforts using Google® Analytics, affiliate software or advertising networks, you can place the code for those in the field below. All of the code in the field below, will be injected into the Signup Confirmation Page, between the <code>&lt;body&gt;&lt;/body&gt;</code> tags. After everything in your code has finished loading, the new Member will be redirected to the Registration system, so they can setup their Username and login. In other words, the Signup Confirmation Page ensures that all 1x1 pixel images and/or other data from your Pixel Tracking Code ( in the field below ) has finished loading, before it redirects the Member away from the page. This way you can be sure that all of your tracking statistics, and other marketing efforts, remain accurate. This is handled through the magic of the <code>window.onload</code> event, compatible in all major browsers.</p>' . "\n";
41
  /**/
42
  echo '<table class="form-table">' . "\n";
43
  echo '<tbody>' . "\n";
44
  echo '<tr>' . "\n";
45
  /**/
46
  echo '<th>' . "\n";
47
- echo '<label for="ws-plugin--s2member-signup-pixel-tracking-codes">' . "\n";
48
- echo 'Pixel Tracking Codes:' . "\n";
49
  echo '</label>' . "\n";
50
  echo '</th>' . "\n";
51
  /**/
@@ -53,26 +53,26 @@ echo '</tr>' . "\n";
53
  echo '<tr>' . "\n";
54
  /**/
55
  echo '<td>' . "\n";
56
- echo '<textarea name="ws_plugin__s2member_signup_pixel_tracking_codes" id="ws-plugin--s2member-signup-pixel-tracking-codes" rows="8">' . format_to_edit ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["signup_pixel_tracking_codes"]) . '</textarea><br />' . "\n";
57
- echo 'Any valid XHTML or JavaScript code will work just fine here. Just try not to put anything here that would actually be visible to the user. They won\'t see it anyway, because they\'re going to be redirected as soon as it loads up. Things like 1x1 pixel images that load up silently and/or JavaScript tracking routines will be fine though. 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";
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 ( 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 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";
61
- echo '<li><code>%%initial%% = The initial fee charged during signup, in USD. If you offered a free trial, this will be 0.</code> [ <a href="#" onclick="alert(\'If no initial period was offered or required, this initial amount will be equal to the regular subscription rate. In other words, this will always represent the amount of money the customer spent whenever they signed up, no matter what.\\n\\nIf a user signs up under the terms of a free trial period, this will be 0. So be careful using this value with 3rd party affiliate integrations because a $0 sale amount could cause havoc. If you have a lot of trouble, try using the more advanced `Payment` notifications available in the API Notifications panel for s2Member.\'); return false;">?</a> ]</li>' . "\n";
62
- echo '<li><code>%%first_name%% = The first name of the customer who purchased the membership subscription through PayPal®.</code></li>' . "\n";
63
- echo '<li><code>%%last_name%% = The last name of the customer who purchased the membership subscription through PayPal®.</code></li>' . "\n";
64
- echo '<li><code>%%full_name%% = The full name ( first & last ) of the customer who purchased the membership subscription.</code></li>' . "\n";
65
- echo '<li><code>%%payer_email%% = The email address of the customer who purchased the membership subscription through PayPal®.</code></li>' . "\n";
66
- echo '<li><code>%%item_number%% = The item number ( in other words, the membership level: 1, 2, 3 or 4 ) that the subscription is for.</code></li>' . "\n";
67
- echo '<li><code>%%item_name%% = The item name ( in other words, the associated membership level label that briefly describes the item number ).</code></li>' . "\n";
68
  echo '</ul>' . "\n";
69
  echo '<strong>Custom replacement codes can also be inserted using these instructions:</strong>' . "\n";
70
  echo '<ul>' . "\n";
71
- echo '<li><code>%%cv0%% = The domain of your site, which is passed through to PayPal® using the `custom` field in your PayPal® button code.</code></li>' . "\n";
72
- echo '<li><code>%%cv1%% = If you need to track additional custom variables, you can pipe delimit them into the `custom` field of your button code like this: &lt;input type="hidden" name="custom" value="' . $_SERVER["HTTP_HOST"] . '|cv1|cv2|cv3" /&gt;. You can have an unlimited number of custom variables that track IP addresses, affiliate IDs, etc. In some cases you may need to use PHP code to insert a value into the custom field dynamically. Obviously this is for advanced webmasters, but the functionality has been made available for those who need it.</code></li>' . "\n";
73
  echo '</ul>' . "\n";
74
  echo '<strong>This example uses cv1 to track a user\'s IP address:</strong><br />' . "\n";
75
- echo '<em>( The IP address can be referenced in your Pixel Code using %%cv1%% )</em><br />' . "\n";
76
  echo '<code>&lt;input type="hidden" name="custom" value="' . $_SERVER["HTTP_HOST"] . '|&lt;?php echo $_SERVER["REMOTE_ADDR"]; ?&gt;" /&gt;</code>' . "\n";
77
  echo '</td>' . "\n";
78
  /**/
@@ -83,11 +83,20 @@ echo '</div>' . "\n";
83
  /**/
84
  echo '</div>' . "\n";
85
  /**/
86
- echo '<div class="ws-menu-page-group" title="Other Methods Available">' . "\n";
 
 
 
 
 
 
 
 
 
87
  /**/
88
  echo '<div class="ws-menu-page-section ws-plugin--s2member-other-methods-section">' . "\n";
89
- echo '<h3>Other Methods Are Available As Well</h3>' . "\n";
90
- echo '<p>You may also want to check the s2Member API Notifications panel. You\'ll find additional layers of automation available through the use of the `Signup`, `Payment`, `EOT/Deletion` and `Refund/Reversal` notifications that are available to you through the s2Member API. These make it easy to integrate with 3rd party applications like affiliate programs and other back-office routines. 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 really replaces the simplicity of using Pixel Tracking, and the s2Member API Notifications are not necessarily the best tool for the job in all cases. For instance, API Notifications will NOT work with Google® Analytics, or 1 pixel &lt;img&gt; tags. They operate silently behind-the-scenes, using cURL connections, as opposed to being loaded in a browser.</p>' . "\n";
91
  echo '</div>' . "\n";
92
  /**/
93
  echo '</div>' . "\n";
@@ -102,6 +111,8 @@ echo '</td>' . "\n";
102
  /**/
103
  echo '<td class="ws-menu-page-table-r">' . "\n";
104
  /**/
 
 
105
  echo ($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["menu-r"]["tools"]) ? '<div class="ws-menu-page-tools"><img src="' . $GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["dir_url"] . '/images/brand-tools.png" alt="." /></div>' . "\n" : '';
106
  /**/
107
  echo ($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["menu-r"]["tips"]) ? '<div class="ws-menu-page-tips"><a href="' . ws_plugin__s2member_parse_readme_value ("Customization URI") . '"><img src="' . $GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["dir_url"] . '/images/brand-tips.png" alt="." /></a></div>' . "\n" : '';
32
  echo '<input type="hidden" name="ws_plugin__s2member_options_save" id="ws-plugin--s2member-options-save" value="' . esc_attr (wp_create_nonce ("ws-plugin--s2member-options-save")) . '" />' . "\n";
33
  echo '<input type="hidden" name="ws_plugin__s2member_configured" id="ws-plugin--s2member-configured" value="1" />' . "\n";
34
  /**/
35
+ echo '<div class="ws-menu-page-group" title="Integrate Custom Tracking Codes">' . "\n";
36
  /**/
37
+ echo '<div class="ws-menu-page-section ws-plugin--s2member-tracking-section">' . "\n";
38
+ echo '<h3>Tracking Codes ( optional, these will be injected into the Signup Confirmation Page )</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"]) ? ' and/or PHP' : '') . ' code that you enter below, will be loaded up in a web browser, whenever a Customer lands on the Signup Confirmation Page after checkout. The s2Member (built-in) Signup Confirmation Page ( also known as a Thank-You Page ), is really just a blank page that alerts the Customer via JavaScript. It says: <em>`Thank You! Your account has been approved.`</em>. Then it says: <em>`The next step is to Register a Username. Please click OK to be redirected.`</em>. After they\'ve clicked OK on this alert, and after everything ( if there is anything ) on the blank page has finished loading, they\'ll be redirected to the registration system, where they will be able to setup their Username and login for the first time. This process has been fully automated, very simple.</p>' . "\n";
40
+ echo '<p>Now, if you want to track the performance of your marketing efforts using Google® Analytics, affiliate software or advertising networks, you can place the code for those in the field below. All of the code in the field below, will be injected into the Signup Confirmation Page, between the <code>&lt;body&gt;&lt;/body&gt;</code> tags. After everything in your code has finished loading, the new Member will be redirected to the registration system, so they can setup their Username and login. In other words, the Signup Confirmation Page ensures that all 1x1 pixel images and/or other data from your Tracking Codes ( in the field below ) has finished loading, before it redirects the Member away from the page. This way you can be sure that all of your tracking statistics, and other marketing efforts, remain accurate. This is handled through the magic of the <code>window.onload</code> event, compatible in all major browsers.</p>' . "\n";
41
  /**/
42
  echo '<table class="form-table">' . "\n";
43
  echo '<tbody>' . "\n";
44
  echo '<tr>' . "\n";
45
  /**/
46
  echo '<th>' . "\n";
47
+ echo '<label for="ws-plugin--s2member-signup-tracking-codes">' . "\n";
48
+ echo 'Integrate Custom Tracking Codes:' . "\n";
49
  echo '</label>' . "\n";
50
  echo '</th>' . "\n";
51
  /**/
53
  echo '<tr>' . "\n";
54
  /**/
55
  echo '<td>' . "\n";
56
+ 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";
57
+ echo 'Any valid XHTML / JavaScript' . ((!$GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["is_wpmu"]) ? ' ( or even PHP )' : '') . ' code will work just fine here. Just try not to put anything here that would actually be visible to the user. They won\'t see it anyway, because they\'re going to be redirected as soon as it loads up. 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";
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 ( 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 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";
61
+ echo '<li><code>%%initial%% = The Initial Fee charged during signup. If you offered a free trial, this will be 0.</code> [ <a href="#" onclick="alert(\'If no initial period was offered or required, this initial amount will be equal to the regular subscription rate. In other words, this will always represent the amount of money the Customer spent whenever they signed up, no matter what.\\n\\nIf a user signs up under the terms of a free trial period, this will be 0. So be careful using this value with 3rd party affiliate integrations because a $0 sale amount could cause havoc. If you have a lot of trouble, try using the more advanced `Payment` notifications available in the API Notifications panel for s2Member.\'); return false;">?</a> ]</li>' . "\n";
62
+ echo '<li><code>%%first_name%% = The First Name of the Customer who purchased the membership subscription through PayPal®.</code></li>' . "\n";
63
+ echo '<li><code>%%last_name%% = The Last Name of the Customer who purchased the membership subscription through PayPal®.</code></li>' . "\n";
64
+ echo '<li><code>%%full_name%% = The Full Name ( First & Last ) of the Customer who purchased the membership subscription.</code></li>' . "\n";
65
+ echo '<li><code>%%payer_email%% = The Email Address of the Customer who purchased the membership subscription through PayPal®.</code></li>' . "\n";
66
+ echo '<li><code>%%item_number%% = The Item Number ( colon separated <em>level:custom_capabilities</em> ) that the subscription is for.</code></li>' . "\n";
67
+ echo '<li><code>%%item_name%% = The Item Name ( in other words, the associated membership Level Label that briefly describes the item number ).</code></li>' . "\n";
68
  echo '</ul>' . "\n";
69
  echo '<strong>Custom replacement codes can also be inserted using these instructions:</strong>' . "\n";
70
  echo '<ul>' . "\n";
71
+ echo '<li><code>%%cv0%% = The domain of your site, which is passed through to PayPal® using the `custom` field in your PayPal® Button Code.</code></li>' . "\n";
72
+ echo '<li><code>%%cv1%% = If you need to track additional custom variables, you can pipe delimit them into the `custom` field of your Button Code like this: &lt;input type="hidden" name="custom" value="' . $_SERVER["HTTP_HOST"] . '|cv1|cv2|cv3" /&gt;. You can have an unlimited number of custom variables that track IP addresses, affiliate IDs, etc. In some cases you may need to use PHP code to insert a value into the custom field dynamically. Obviously this is for advanced webmasters, but the functionality has been made available for those who need it.</code></li>' . "\n";
73
  echo '</ul>' . "\n";
74
  echo '<strong>This example uses cv1 to track a user\'s IP address:</strong><br />' . "\n";
75
+ echo '<em>( The IP address can be referenced in your Tracking Code using %%cv1%% )</em><br />' . "\n";
76
  echo '<code>&lt;input type="hidden" name="custom" value="' . $_SERVER["HTTP_HOST"] . '|&lt;?php echo $_SERVER["REMOTE_ADDR"]; ?&gt;" /&gt;</code>' . "\n";
77
  echo '</td>' . "\n";
78
  /**/
83
  /**/
84
  echo '</div>' . "\n";
85
  /**/
86
+ echo '<div class="ws-menu-page-group" title="Tracking Single-Page Access">' . "\n";
87
+ /**/
88
+ echo '<div class="ws-menu-page-section ws-plugin--s2member-sp-access-section">' . "\n";
89
+ echo '<h3>Tracking Single-Page Access ( this is different )</h3>' . "\n";
90
+ echo '<p>Single-Page Access works independently from Member Level Access. For full details, see: <code>s2Member -> General Options -> Single-Page Access</code>. If you need to track Single-Page Access, you will need to insert separate Tracking Codes yourself, on a Page-by-Page basis; into each Page you\'re selling access to. The Signup Confirmation Page is NOT loaded for Single-Page transactions. Instead, Customers are immediately redirected to the Page you sold them access to. Again, just to be clear... The Signup Confirmation Page ( and the Custom Tracking Codes in the section above ) are NOT injected for Single-Page Access, only for Member Level Access.</p>' . "\n";
91
+ echo '</div>' . "\n";
92
+ /**/
93
+ echo '</div>' . "\n";
94
+ /**/
95
+ echo '<div class="ws-menu-page-group" title="Other Tracking Methods Available">' . "\n";
96
  /**/
97
  echo '<div class="ws-menu-page-section ws-plugin--s2member-other-methods-section">' . "\n";
98
+ echo '<h3>Other Tracking Methods Are Available ( there\'s always a way )</h3>' . "\n";
99
+ 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 `Single-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-scenes, using cURL connections, as opposed to being loaded in a browser.</p>' . "\n";
100
  echo '</div>' . "\n";
101
  /**/
102
  echo '</div>' . "\n";
111
  /**/
112
  echo '<td class="ws-menu-page-table-r">' . "\n";
113
  /**/
114
+ echo ($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["menu-r"]["installation"]) ? '<div class="ws-menu-page-installation"><a href="' . ws_plugin__s2member_parse_readme_value ("Professional Installation URI") . '"><img src="' . $GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["dir_url"] . '/images/brand-installation.png" alt="." title="Contact PriMoThemes!" /></a></div>' . "\n" : '';
115
+ /**/
116
  echo ($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["menu-r"]["tools"]) ? '<div class="ws-menu-page-tools"><img src="' . $GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["dir_url"] . '/images/brand-tools.png" alt="." /></div>' . "\n" : '';
117
  /**/
118
  echo ($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["menu-r"]["tips"]) ? '<div class="ws-menu-page-tips"><a href="' . ws_plugin__s2member_parse_readme_value ("Customization URI") . '"><img src="' . $GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["dir_url"] . '/images/brand-tips.png" alt="." /></a></div>' . "\n" : '';
includes/s2member-min.js CHANGED
@@ -1 +1 @@
1
- "%%globals%%";jQuery(document).ready(function(a){s2member_unique_files_downloaded=[];if(S2MEMBER_CURRENT_USER_IS_LOGGED_IN&&S2MEMBER_CURRENT_USER_DOWNLOADS_CURRENTLY<S2MEMBER_CURRENT_USER_DOWNLOADS_ALLOWED){a("a[href*=s2member_file_download]").click(function(){if(!this.href.match(/s2member_free_file_download_key\=(.+)/)){var b="** Please Confirm This File Download **\n\n";b+="You've downloaded "+S2MEMBER_CURRENT_USER_DOWNLOADS_CURRENTLY+" file"+((S2MEMBER_CURRENT_USER_DOWNLOADS_CURRENTLY<1||S2MEMBER_CURRENT_USER_DOWNLOADS_CURRENTLY>1)?"s":"")+" in the last "+S2MEMBER_CURRENT_USER_DOWNLOADS_ALLOWED_DAYS+" days.\n\n";b+="You're entitled to "+((S2MEMBER_CURRENT_USER_DOWNLOADS_ALLOWED_IS_UNLIMITED)?"unlimited":S2MEMBER_CURRENT_USER_DOWNLOADS_ALLOWED+" unique")+" downloads every "+S2MEMBER_CURRENT_USER_DOWNLOADS_ALLOWED_DAYS+" day period.\n\n";if(confirm(b)){if(a.inArray(this.href,s2member_unique_files_downloaded)===-1){s2member_unique_files_downloaded.push(this.href),S2MEMBER_CURRENT_USER_DOWNLOADS_CURRENTLY++}return true}else{return false}}else{var b="This is a FREE download for members.\n";b+="It does not count against your membership entitlement.\n\n";b+="~Enjoy~";if(confirm(b)){return true}else{return false}}})}if(location.href.match(/\/wp-login\.php/)){a("div#login > form#registerform").submit(function(){var b="",c="";a("input[aria-required=true]",this).each(function(){if(!a.trim(this.value)&&(c=a.trim(a(this).parent("label").text().replace(/\*/,"")))){b+="• ( "+c+" ) is a required field.\n"}});if(b=a.trim(b)){alert("Oops, you missed something:\n\n"+b);return false}return true})}if(location.href.match(/\/\?s2member_profile\=1/)){a("form#ws-plugin--s2member-profile").submit(function(){var b="",c="";a("input[aria-required=true]",this).each(function(){if(!a.trim(this.value)&&(c=a.trim(a("strong",a(this).parent("label")).text().replace(/\*/,"")))){b+="• ( "+c+" ) is a required field.\n"}});if(b=a.trim(b)){alert("Oops, you missed something:\n\n"+b);return false}return true})}});
1
+ "%%globals%%";jQuery(document).ready(function(a){s2member_unique_files_downloaded=[];if(S2MEMBER_CURRENT_USER_IS_LOGGED_IN_AS_MEMBER&&S2MEMBER_CURRENT_USER_DOWNLOADS_CURRENTLY<S2MEMBER_CURRENT_USER_DOWNLOADS_ALLOWED){a("a[href*=s2member_file_download]").click(function(){if(!this.href.match(/s2member_free_file_download_key\=(.+)/)){var b="** Please Confirm This File Download **\n\n";b+="You've downloaded "+S2MEMBER_CURRENT_USER_DOWNLOADS_CURRENTLY+" file"+((S2MEMBER_CURRENT_USER_DOWNLOADS_CURRENTLY<1||S2MEMBER_CURRENT_USER_DOWNLOADS_CURRENTLY>1)?"s":"")+" in the last "+S2MEMBER_CURRENT_USER_DOWNLOADS_ALLOWED_DAYS+" days.\n\n";b+="You're entitled to "+((S2MEMBER_CURRENT_USER_DOWNLOADS_ALLOWED_IS_UNLIMITED)?"unlimited":S2MEMBER_CURRENT_USER_DOWNLOADS_ALLOWED+" unique")+" downloads every "+S2MEMBER_CURRENT_USER_DOWNLOADS_ALLOWED_DAYS+" day period.\n\n";if(confirm(b)){if(a.inArray(this.href,s2member_unique_files_downloaded)===-1){s2member_unique_files_downloaded.push(this.href),S2MEMBER_CURRENT_USER_DOWNLOADS_CURRENTLY++}return true}else{return false}}else{var b="This is a FREE download for members.\n";b+="It does not count against your membership entitlement.\n\n";b+="~Enjoy~";if(confirm(b)){return true}else{return false}}})}if(location.href.match(/\/wp-login\.php/)){a("div#login > form#registerform").submit(function(){var b="",c="";a("input[aria-required=true]",this).each(function(){if(!a.trim(this.value)&&(c=a.trim(a(this).parent("label").text().replace(/\*/,"")))){b+="• ( "+c+" ) is a required field.\n"}});if(b=a.trim(b)){alert("Oops, you missed something:\n\n"+b);return false}return true})}if(location.href.match(/\/\?s2member_profile\=1/)){a("form#ws-plugin--s2member-profile").submit(function(){var b="",c="";a("input[aria-required=true]",this).each(function(){if(!a.trim(this.value)&&(c=a.trim(a("strong",a(this).parent("label")).text().replace(/\*/,"")))){b+="• ( "+c+" ) is a required field.\n"}});if(b=a.trim(b)){alert("Oops, you missed something:\n\n"+b);return false}return true})}});
includes/s2member.js CHANGED
@@ -24,7 +24,7 @@ jQuery(document).ready (function($)
24
  s2member_unique_files_downloaded = []; /* Maintains real-time counts. */
25
  /* This is used in case a user downloads multiple files from a single page. */
26
  /**/
27
- if (S2MEMBER_CURRENT_USER_IS_LOGGED_IN && S2MEMBER_CURRENT_USER_DOWNLOADS_CURRENTLY < S2MEMBER_CURRENT_USER_DOWNLOADS_ALLOWED)
28
  {
29
  $('a[href*=s2member_file_download]').click (function()
30
  {
24
  s2member_unique_files_downloaded = []; /* Maintains real-time counts. */
25
  /* This is used in case a user downloads multiple files from a single page. */
26
  /**/
27
+ if (S2MEMBER_CURRENT_USER_IS_LOGGED_IN_AS_MEMBER && S2MEMBER_CURRENT_USER_DOWNLOADS_CURRENTLY < S2MEMBER_CURRENT_USER_DOWNLOADS_ALLOWED)
28
  {
29
  $('a[href*=s2member_file_download]').click (function()
30
  {
includes/syscon.inc.php CHANGED
@@ -39,7 +39,7 @@ $GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["cache"] = get_option ("ws_plugin__s2me
39
  /*
40
  Configure the right menu options panel for this software.
41
  */
42
- $GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["menu-r"] = array ("tools" => true, "tips" => true, "donations" => true);
43
  /*
44
  Configure the file modification time for the syscon.inc.php file.
45
  */
@@ -70,7 +70,8 @@ function ws_plugin__s2member_configure_options_and_their_defaults ($options = FA
70
  "custom_reg_fields" => "", /* A comma delimited list of custom fields to collect/use. */
71
  "custom_reg_password" => "0", /* Allow users to register their own custom password? */
72
  /**/
73
- "allow_subscribers_in" => "0", /* Allow subscribers to access the login_welcome_page ? */
 
74
  /**/
75
  "login_welcome_page" => "", /* Preceded by bloginfo("url"). Defaults to the home page. */
76
  "login_redirection_override" => "", /* Alternate redirection location; instead of the welcome page. */
@@ -84,7 +85,7 @@ function ws_plugin__s2member_configure_options_and_their_defaults ($options = FA
84
  "login_reg_background_box_shadow_color" => "CCCCCC", /* Defaults to gray, which is slightly visible. */
85
  /**/
86
  "login_reg_logo_src" => $GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["dir_url"] . "/images/logo.png",/**/
87
- "login_reg_logo_src_width" => "350", /* Defaults to the logo_src image width. */
88
  "login_reg_logo_src_height" => "100", /* Defaults to the logo_src image height. */
89
  "login_reg_logo_url" => get_bloginfo ("url"), /* Defaults to the site url. */
90
  "login_reg_logo_title" => get_bloginfo ("name"), /* Defaults to the site name. */
@@ -97,15 +98,33 @@ function ws_plugin__s2member_configure_options_and_their_defaults ($options = FA
97
  "paypal_business" => "", /* Paypal business email address for their account. */
98
  "paypal_identity_token" => "", /* Paypal payment data transfer identity token. */
99
  /**/
100
- "signup_pixel_tracking_codes" => "", /* s2Member pixel tracking codes. */
101
  /**/
102
- "signup_email_subject" => "Congratulations! Your membership has been approved.",/**/
103
  "signup_email_message" => "Thanks %%first_name%%! Your membership has been approved.\n\nIf you haven't already done so, the next step is to Register a Username.\n\nComplete your registration here:\n%%registration_url%%\n\nIf you have any trouble, please feel free to contact us.\n\nBest Regards,\n" . get_bloginfo ("name"),/**/
104
  /**/
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
105
  "signup_notification_urls" => "", /* s2Member signup notification urls. */
 
106
  "payment_notification_urls" => "", /* s2Member payment notification urls. */
107
  "eot_del_notification_urls" => "", /* s2Member eot/del notification urls. */
108
  "ref_rev_notification_urls" => "", /* s2Member ref/rev notification urls. */
 
109
  /**/
110
  "level1_label" => "Bronze", /* This is just an initial generic level label. */
111
  "level2_label" => "Silver", /* This is just an initial generic level label. */
@@ -145,12 +164,26 @@ function ws_plugin__s2member_configure_options_and_their_defaults ($options = FA
145
  "level1_pages" => "", /* It is ok for these to just be empty strings. */
146
  "level2_pages" => "", /* It is ok for these to just be empty strings. */
147
  "level3_pages" => "", /* It is ok for these to just be empty strings. */
148
- "level4_pages" => ""); /* It is ok for these to just be empty strings. */
 
 
 
 
149
  /*
150
  Here they are merged. user options will overwrite some or all default values.
151
  */
152
  $GLOBALS["WS_PLUGIN__"]["s2member"]["o"] = array_merge ($default_options, (($options !== false) ? (array)$options : (array)get_option ("ws_plugin__s2member_options")));
153
  /*
 
 
 
 
 
 
 
 
 
 
154
  Validate each option, possibly reverting back to the default value if invalid.
155
  Also check if options were passed in on some of these, in case empty values are to be allowed.
156
  */
@@ -180,6 +213,9 @@ function ws_plugin__s2member_configure_options_and_their_defaults ($options = FA
180
  else if ($key === "allow_subscribers_in" && (!is_string ($value) || !is_numeric ($value)))
181
  $value = $default_options[$key];
182
  /**/
 
 
 
183
  else if ($key === "login_welcome_page" && (!is_string ($value) || !is_numeric ($value)))
184
  $value = $default_options[$key];
185
  /**/
@@ -195,7 +231,7 @@ function ws_plugin__s2member_configure_options_and_their_defaults ($options = FA
195
  else if ($key === "login_reg_background_color" && (!is_string ($value) || !strlen ($value)))
196
  $value = $default_options[$key];
197
  /**/
198
- else if ($key === "login_reg_background_image" && (!is_string ($value) || !strlen ($value)))
199
  $value = $default_options[$key];
200
  /**/
201
  else if ($key === "login_reg_logo_src" && (!is_string ($value) || !strlen ($value)))
@@ -231,7 +267,7 @@ function ws_plugin__s2member_configure_options_and_their_defaults ($options = FA
231
  else if ($key === "paypal_identity_token" && (!is_string ($value) || !strlen ($value)))
232
  $value = $default_options[$key];
233
  /**/
234
- else if ($key === "signup_pixel_tracking_codes" && (!is_string ($value) || !strlen ($value)))
235
  $value = $default_options[$key];
236
  /**/
237
  else if ($key === "signup_email_subject" && (!is_string ($value) || !strlen ($value)))
@@ -240,9 +276,27 @@ function ws_plugin__s2member_configure_options_and_their_defaults ($options = FA
240
  else if ($key === "signup_email_message" && (!is_string ($value) || !strlen ($value)))
241
  $value = $default_options[$key];
242
  /**/
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
243
  else if ($key === "signup_notification_urls" && (!is_string ($value) || !strlen ($value)))
244
  $value = $default_options[$key];
245
  /**/
 
 
 
246
  else if ($key === "payment_notification_urls" && (!is_string ($value) || !strlen ($value)))
247
  $value = $default_options[$key];
248
  /**/
@@ -252,6 +306,9 @@ function ws_plugin__s2member_configure_options_and_their_defaults ($options = FA
252
  else if ($key === "ref_rev_notification_urls" && (!is_string ($value) || !strlen ($value)))
253
  $value = $default_options[$key];
254
  /**/
 
 
 
255
  else if ($key === "level1_label" && (!is_string ($value) || !strlen ($value)))
256
  $value = $default_options[$key];
257
  /**/
@@ -284,6 +341,12 @@ function ws_plugin__s2member_configure_options_and_their_defaults ($options = FA
284
  /**/
285
  else if (preg_match ("/level[1-4]_pages$/", $key) && (!is_string ($value) || !($value = (($value === "all") ? $value : preg_replace ("/[^0-9,]/", "", $value)))))
286
  $value = $default_options[$key];
 
 
 
 
 
 
287
  }
288
  /**/
289
  return $GLOBALS["WS_PLUGIN__"]["s2member"]["o"];
39
  /*
40
  Configure the right menu options panel for this software.
41
  */
42
+ $GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["menu-r"] = array ("tools" => true, "tips" => true, "donations" => true, "installation" => true);
43
  /*
44
  Configure the file modification time for the syscon.inc.php file.
45
  */
70
  "custom_reg_fields" => "", /* A comma delimited list of custom fields to collect/use. */
71
  "custom_reg_password" => "0", /* Allow users to register their own custom password? */
72
  /**/
73
+ "allow_subscribers_in" => "0", /* Allow subscribers to access the login_welcome_page? */
74
+ "force_admin_lockouts" => "0", /* Redirects admin pages/profile to the login_welcome_page. */
75
  /**/
76
  "login_welcome_page" => "", /* Preceded by bloginfo("url"). Defaults to the home page. */
77
  "login_redirection_override" => "", /* Alternate redirection location; instead of the welcome page. */
85
  "login_reg_background_box_shadow_color" => "CCCCCC", /* Defaults to gray, which is slightly visible. */
86
  /**/
87
  "login_reg_logo_src" => $GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["dir_url"] . "/images/logo.png",/**/
88
+ "login_reg_logo_src_width" => "500", /* Defaults to the logo_src image width. */
89
  "login_reg_logo_src_height" => "100", /* Defaults to the logo_src image height. */
90
  "login_reg_logo_url" => get_bloginfo ("url"), /* Defaults to the site url. */
91
  "login_reg_logo_title" => get_bloginfo ("name"), /* Defaults to the site name. */
98
  "paypal_business" => "", /* Paypal business email address for their account. */
99
  "paypal_identity_token" => "", /* Paypal payment data transfer identity token. */
100
  /**/
101
+ "signup_tracking_codes" => "", /* s2Member tracking codes injected on signup. */
102
  /**/
103
+ "signup_email_subject" => "Congratulations! ( your membership has been approved )",/**/
104
  "signup_email_message" => "Thanks %%first_name%%! Your membership has been approved.\n\nIf you haven't already done so, the next step is to Register a Username.\n\nComplete your registration here:\n%%registration_url%%\n\nIf you have any trouble, please feel free to contact us.\n\nBest Regards,\n" . get_bloginfo ("name"),/**/
105
  /**/
106
+ "single_page_email_subject" => "Thank You! ( instructions for access )",/**/
107
+ "single_page_email_message" => "Thanks %%first_name%%!\n\n%%item_name%%\n\nYour order can be retrieved here:\n%%access_url%%\n( link expires after 72 hours )\n\nIf you have any trouble, please feel free to contact us.\n\nBest Regards,\n" . get_bloginfo ("name"),/**/
108
+ /**/
109
+ "mailchimp_api_key" => "", /* MailChimp® API Key for MailChimp® integration. */
110
+ "level0_mailchimp_list_ids" => "", /* Comma delimited list of MailChimp® List IDs. */
111
+ "level1_mailchimp_list_ids" => "", /* Comma delimited list of MailChimp® List IDs. */
112
+ "level2_mailchimp_list_ids" => "", /* Comma delimited list of MailChimp® List IDs. */
113
+ "level3_mailchimp_list_ids" => "", /* Comma delimited list of MailChimp® List IDs. */
114
+ "level4_mailchimp_list_ids" => "", /* Comma delimited list of MailChimp® List IDs. */
115
+ /**/
116
+ "level0_aweber_list_ids" => "", /* Comma delimited list of AWeber® List IDs. */
117
+ "level1_aweber_list_ids" => "", /* Comma delimited list of AWeber® List IDs. */
118
+ "level2_aweber_list_ids" => "", /* Comma delimited list of AWeber® List IDs. */
119
+ "level3_aweber_list_ids" => "", /* Comma delimited list of AWeber® List IDs. */
120
+ "level4_aweber_list_ids" => "", /* Comma delimited list of AWeber® List IDs. */
121
+ /**/
122
  "signup_notification_urls" => "", /* s2Member signup notification urls. */
123
+ "registration_notification_urls" => "", /* s2Member reg notification urls. */
124
  "payment_notification_urls" => "", /* s2Member payment notification urls. */
125
  "eot_del_notification_urls" => "", /* s2Member eot/del notification urls. */
126
  "ref_rev_notification_urls" => "", /* s2Member ref/rev notification urls. */
127
+ "sp_notification_urls" => "", /* s2Member single-page notification urls. */
128
  /**/
129
  "level1_label" => "Bronze", /* This is just an initial generic level label. */
130
  "level2_label" => "Silver", /* This is just an initial generic level label. */
164
  "level1_pages" => "", /* It is ok for these to just be empty strings. */
165
  "level2_pages" => "", /* It is ok for these to just be empty strings. */
166
  "level3_pages" => "", /* It is ok for these to just be empty strings. */
167
+ "level4_pages" => "", /* It is ok for these to just be empty strings. */
168
+ /**/
169
+ "single_pages" => "", /* It is ok for these to just be empty strings. */
170
+ /**/
171
+ "membership_eot_behavior" => "demote"); /* Demote or delete Members? */
172
  /*
173
  Here they are merged. user options will overwrite some or all default values.
174
  */
175
  $GLOBALS["WS_PLUGIN__"]["s2member"]["o"] = array_merge ($default_options, (($options !== false) ? (array)$options : (array)get_option ("ws_plugin__s2member_options")));
176
  /*
177
+ Backward compatibility for `signup_pixel_tracking_codes`, which was renamed to `signup_tracking_codes` in v2.8.6.
178
+ */
179
+ if ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["signup_pixel_tracking_codes"])
180
+ $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["signup_tracking_codes"] = $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["signup_pixel_tracking_codes"];
181
+ /*
182
+ Backward compatibility for `login_reg_logo_src`, which was resized to 500px wide in v2.8.6.
183
+ */
184
+ if ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["login_reg_logo_src"] === $default_options["login_reg_logo_src"])
185
+ $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["login_reg_logo_src_width"] = $default_options["login_reg_logo_src_width"];
186
+ /*
187
  Validate each option, possibly reverting back to the default value if invalid.
188
  Also check if options were passed in on some of these, in case empty values are to be allowed.
189
  */
213
  else if ($key === "allow_subscribers_in" && (!is_string ($value) || !is_numeric ($value)))
214
  $value = $default_options[$key];
215
  /**/
216
+ else if ($key === "force_admin_lockouts" && (!is_string ($value) || !is_numeric ($value)))
217
+ $value = $default_options[$key];
218
+ /**/
219
  else if ($key === "login_welcome_page" && (!is_string ($value) || !is_numeric ($value)))
220
  $value = $default_options[$key];
221
  /**/
231
  else if ($key === "login_reg_background_color" && (!is_string ($value) || !strlen ($value)))
232
  $value = $default_options[$key];
233
  /**/
234
+ else if ($key === "login_reg_background_image" && !is_string ($value)) /* This is optional. */
235
  $value = $default_options[$key];
236
  /**/
237
  else if ($key === "login_reg_logo_src" && (!is_string ($value) || !strlen ($value)))
267
  else if ($key === "paypal_identity_token" && (!is_string ($value) || !strlen ($value)))
268
  $value = $default_options[$key];
269
  /**/
270
+ else if ($key === "signup_tracking_codes" && (!is_string ($value) || !strlen ($value)))
271
  $value = $default_options[$key];
272
  /**/
273
  else if ($key === "signup_email_subject" && (!is_string ($value) || !strlen ($value)))
276
  else if ($key === "signup_email_message" && (!is_string ($value) || !strlen ($value)))
277
  $value = $default_options[$key];
278
  /**/
279
+ else if ($key === "single_page_email_subject" && (!is_string ($value) || !strlen ($value)))
280
+ $value = $default_options[$key];
281
+ /**/
282
+ else if ($key === "single_page_email_message" && (!is_string ($value) || !strlen ($value)))
283
+ $value = $default_options[$key];
284
+ /**/
285
+ else if ($key === "mailchimp_api_key" && (!is_string ($value) || !strlen ($value)))
286
+ $value = $default_options[$key];
287
+ /**/
288
+ else if (preg_match ("/level[0-4]_mailchimp_list_ids$/", $key) && (!is_string ($value) || !strlen ($value = preg_replace ("/\s+/", "", $value))))
289
+ $value = $default_options[$key];
290
+ /**/
291
+ else if (preg_match ("/level[0-4]_aweber_list_ids$/", $key) && (!is_string ($value) || !strlen ($value = preg_replace ("/\s+/", "", $value))))
292
+ $value = $default_options[$key];
293
+ /**/
294
  else if ($key === "signup_notification_urls" && (!is_string ($value) || !strlen ($value)))
295
  $value = $default_options[$key];
296
  /**/
297
+ else if ($key === "registration_notification_urls" && (!is_string ($value) || !strlen ($value)))
298
+ $value = $default_options[$key];
299
+ /**/
300
  else if ($key === "payment_notification_urls" && (!is_string ($value) || !strlen ($value)))
301
  $value = $default_options[$key];
302
  /**/
306
  else if ($key === "ref_rev_notification_urls" && (!is_string ($value) || !strlen ($value)))
307
  $value = $default_options[$key];
308
  /**/
309
+ else if ($key === "sp_notification_urls" && (!is_string ($value) || !strlen ($value)))
310
+ $value = $default_options[$key];
311
+ /**/
312
  else if ($key === "level1_label" && (!is_string ($value) || !strlen ($value)))
313
  $value = $default_options[$key];
314
  /**/
341
  /**/
342
  else if (preg_match ("/level[1-4]_pages$/", $key) && (!is_string ($value) || !($value = (($value === "all") ? $value : preg_replace ("/[^0-9,]/", "", $value)))))
343
  $value = $default_options[$key];
344
+ /**/
345
+ else if ($key === "single_pages" && (!is_string ($value) || !($value = preg_replace ("/[^0-9,]/", "", $value))))
346
+ $value = $default_options[$key];
347
+ /**/
348
+ else if ($key === "membership_eot_behavior" && (!is_string ($value) || !preg_match ("/^(demote|delete)$/", $value)))
349
+ $value = $default_options[$key];
350
  }
351
  /**/
352
  return $GLOBALS["WS_PLUGIN__"]["s2member"]["o"];
licensing/license.txt CHANGED
@@ -18,16 +18,30 @@ Credits / Additional Acknowledgments:
18
  - BSD / GPL Compatible License <http://michelf.com/projects/php-markdown/license/>
19
  - PHP Markdown <http://michelf.com/projects/php-markdown/>
20
 
 
 
 
 
21
  * Administration panel (tools icon) was provided by Everaldo.com.
22
  - LGPL License <http://www.everaldo.com/crystal/?action=license>
23
  - Everaldo <http://www.everaldo.com/crystal/?action=downloads>
24
-
25
  * PayPal® and its associated buttons & services have been integrated into this software via external hyperlinks.
26
  The files/services provided by PayPal® are not distributed with this software. They have their own terms & conditions.
27
  - PayPal®, a 3rd party service, is powered by eBay, Inc. <http://www.paypal.com/>
28
  - PayPal® is a trademark of eBay, Inc. <http://www.ebay.com/>
29
-
30
  * The W3C® and its associated validator & services have been integrated into this software via external hyperlinks.
31
  The files/services provided by the W3C® are not distributed with this software. They have their own terms & conditions.
32
  - The W3C®, a 3rd party service, is powered by the World Wide Web Consortium <http://validator.w3.org/>
33
- - W3C® is a trademark of the World Wide Web Consortium. <http://www.w3.org/>
 
 
 
 
 
 
 
 
 
 
18
  - BSD / GPL Compatible License <http://michelf.com/projects/php-markdown/license/>
19
  - PHP Markdown <http://michelf.com/projects/php-markdown/>
20
 
21
+ * MailChimp® integration, powered (in part) by the original PHP MCAPI class.
22
+ - MIT / GPL Compatible License <http://www.mailchimp.com/api/downloads/>
23
+ - The MCAPI class <http://www.mailchimp.com/api/>
24
+
25
  * Administration panel (tools icon) was provided by Everaldo.com.
26
  - LGPL License <http://www.everaldo.com/crystal/?action=license>
27
  - Everaldo <http://www.everaldo.com/crystal/?action=downloads>
28
+
29
  * PayPal® and its associated buttons & services have been integrated into this software via external hyperlinks.
30
  The files/services provided by PayPal® are not distributed with this software. They have their own terms & conditions.
31
  - PayPal®, a 3rd party service, is powered by eBay, Inc. <http://www.paypal.com/>
32
  - PayPal® is a trademark of eBay, Inc. <http://www.ebay.com/>
33
+
34
  * The W3C® and its associated validator & services have been integrated into this software via external hyperlinks.
35
  The files/services provided by the W3C® are not distributed with this software. They have their own terms & conditions.
36
  - The W3C®, a 3rd party service, is powered by the World Wide Web Consortium <http://validator.w3.org/>
37
+ - W3C® is a trademark of the World Wide Web Consortium. <http://www.w3.org/>
38
+
39
+ * The MailChimp® services have been integrated into this software through a GPL compatible API & hyperlinks.
40
+ The services provided by MailChimp® are not distributed with this software. They have their own terms & conditions.
41
+ - MailChimp®, a 3rd party service, is powered by The Rocket Science Group, LLC <http://www.mailchimp.com/>
42
+ - MailChimp® is a trademark of The Rocket Science Group, LLC. <http://www.mailchimp.com/terms-policies/terms-of-use/>
43
+
44
+ * The AWeber® services have been integrated into this software through hyperlinks & email commands.
45
+ The services provided by AWeber® are not distributed with this software. They have their own terms & conditions.
46
+ - AWeber®, a 3rd party service, is powered by AWeber Communications <http://www.aweber.com/about.htm>
47
+ - AWeber® is a trademark of AWeber Communications. <http://www.aweber.com/service-agreement.htm>
readme.txt CHANGED
@@ -1,12 +1,12 @@
1
- === s2Member ( Membership w/ PayPal Integration ) also works w/ BuddyPress ===
2
 
3
- Version: 2.8.5
4
- Stable tag: 2.8.5
5
  Framework: WS-P-2.1
6
 
7
  WordPress Compatible: yes
8
  BuddyPress Compatible: yes
9
- WordPress MU Compatible: yes
10
  MU Blog Farm Compatible: soon
11
 
12
  Tested up to: 2.9
@@ -21,6 +21,7 @@ Author: PriMoThemes.com / WebSharks, Inc.
21
  Donate link: http://www.primothemes.com/donate/
22
 
23
  Plugin Name: s2Member
 
24
  Plugin URI: http://www.primothemes.com/post/s2member-membership-plugin-with-paypal/
25
  Customization URI: http://www.primothemes.com/post/s2member-membership-plugin-with-paypal/#comments
26
  Description: Empowers WordPress® with membership capabilities. Integrates seamlessly with PayPal®. Also compatible with the BuddyPress plugin for WP.
@@ -40,9 +41,15 @@ s2Member is a full-featured membership management system for WordPress®. It emp
40
 
41
  == Description ==
42
 
43
- s2Member is a full-featured membership management system for WordPress®. It provides a very tight integration with PayPal® Subscriptions, and fully supports recurring billing with the ability to track affiliate commissions on a recurring basis. s2Member supports up to 4 different levels of membership with custom labels. It supports custom Pages for signup, account access, and many others. It also supports the ability to protect certain Pages, certain Posts, certain Categories/Tags, certain parts of content, and even includes advanced documentation on how to utilize the PHP runtime constants provided by the s2Member API. s2Member also supports protected file downloads with limitations on the how many files each user ( or each level ) can download in a given period of time.
44
 
45
- - s2Member is also compatible with the BuddyPress plugin for WordPress®.
 
 
 
 
 
 
46
 
47
  == Screenshots ==
48
 
@@ -60,43 +67,64 @@ s2Member is a full-featured membership management system for WordPress®. It pro
60
  == Frequently Asked Questions ==
61
 
62
  = Does the PayPal integration work right-out-of-the-box? =
63
- Yes, it can even generate your PayPal® Subscription Buttons for you. Everything is fully integrated. You even get to create your own Pages within WordPress® to handle Membership Options, the Login Welcome Page, etc. For advanced webmasters, there are scripting techniques that are documented as well. These will help you further develop your site and tailor it to meet your specific needs. Advanced scripting is not required however.
64
 
65
- = How many membership levels are supported? =
66
- s2Member supports up to 4 membership levels, and you can label those levels anything you like. The defaults are Bronze, Silver, Gold, Platinum.
67
 
68
- = Does s2Member utilize the PayPal IPN system? =
69
- Yes, s2Member supports automation of account activation, welcome emails, renewals, de-activation, refunds, etc.
70
 
71
  = Does s2Member support PayPal Auto-Return w/Payment Data Transfer? =
72
  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 enter your Identity Token. If one is enabled, the other must also be enabled. There is a place to enter your PayPal® Identity Token for PDT under `s2Member -> PayPal® Options`. You'll also find some additional instructions there.
73
 
74
  = Does s2Member install any new database tables? =
75
- No, s2Member has been fully integrated with the Roles & Capabilities that are already built into WordPress®. It is designed to be completely seamless without code bloat.
76
 
77
  = How does s2Member protect content from public access? =
78
- s2Member allows you to protect Pages, Posts, and/or portions of content within Pages & Posts. It also allows you to protect downloadable files with special periodic restrictions on how many downloads can occur within a certain amount of time; on a per-user basis. All of this is configurable through the s2Member options panel. Each membership level can have different restrictions, and you could even integrate conditionals within your content based on the membership of the user. Examples are provided.
79
 
80
  = Does s2Member provide an API that I can connect to? =
81
- Yes, s2Member provides many *Advanced Scripting* techniques that are fully documented within its configuration and info pages. Example code is provided for everything. There are several functions that you can use, along with PHP Constants. This allows you to access many parts of its functionality, as well as specific user information. Theme designers are welcome to integrate their themes with s2Member using the code samples we provide.
82
 
83
  = Is s2Member compatible with Quick Cache or WP Super Cache? =
84
- Yes, there were some bugs in the beginning, but they have been fixed now. Both Quick Cache and WP Super Cache will remain compatible with s2Member. We have integrated two internal constants that prevent these plugins from caching important members only areas of your site, no matter what your cache configuration might be. The two Constants are: `DONOTCACHEPAGE` and `QUICK_CACHE_ALLOWED = false`. We recommend Quick Cache over WP Super Cache simply because we actually developed Quick Cache and we have done more extensive testing with the s2Member/Quick-Cache combination.
85
 
86
  = Is s2Member compatible with the BuddyPress plugin for WordPress? =
87
  Yes it is. In fact, we must say... the s2Member/BuddyPress combination is just awesome. These two plugins running together make all sorts of things possible.
88
 
89
  = Do you take feature requests for future versions of s2Member? =
90
- We welcome any and all [contributions](http://www.primothemes.com/donate/) so that s2Member may remain publicly available. If you contribute more than $200, your feature requests will be given high priority, and you will also receive 5 WordPress® themes ( of your choosing ) from PriMoThemes.com, along with a PriMoThemes.com T-shirt, and special credits in the next release of s2Member.
91
 
92
  = Do you offer professional installation for s2Member? =
93
- Yes, please contact [PriMoThemes.com](http://www.primothemes.com/contact/) for professional assistance.
94
 
95
  = Is there a discussion forum for s2Member? =
96
  Yes. In the form of comments on [this page](http://www.primothemes.com/post/s2member-membership-plugin-with-paypal/).
97
 
98
  == Changelog ==
99
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
100
  = 2.8.5 =
101
  * Bug fix. A bug was causing the First &amp; Last Name of a new User to be excluded whenever a new User was created manually through the WordPress® Dashboard by an Administrator. This bug was first introduced in v2.8.2 and has now been resolved in v2.8.5.
102
  * Internal references to `?s2AC` and `?s2ABC` have been removed. These have been deprecated since v1.6 anyway. They have now been removed completely in favor of `qcAC` and `qcABC`. These two variables are ONLY used internally, in order to provide compatibility with the Quick Cache plugin for WordPress®. This will have no impact on existing installations of s2Member; UNLESS you're using the Quick Cache plugin. If you ARE using the Quick Cache plugin, you should make sure that you're using Quick Cache 2.1.4+ for the highest level of compatibility with s2Member.
1
+ === s2Member ( Membership w/ PayPal® Integration ) also works w/ BuddyPress ===
2
 
3
+ Version: 2.8.6
4
+ Stable tag: 2.8.6
5
  Framework: WS-P-2.1
6
 
7
  WordPress Compatible: yes
8
  BuddyPress Compatible: yes
9
+ WordPress MU Compatible: soon
10
  MU Blog Farm Compatible: soon
11
 
12
  Tested up to: 2.9
21
  Donate link: http://www.primothemes.com/donate/
22
 
23
  Plugin Name: s2Member
24
+ Professional Installation URI: http://www.primothemes.com/support/
25
  Plugin URI: http://www.primothemes.com/post/s2member-membership-plugin-with-paypal/
26
  Customization URI: http://www.primothemes.com/post/s2member-membership-plugin-with-paypal/#comments
27
  Description: Empowers WordPress® with membership capabilities. Integrates seamlessly with PayPal®. Also compatible with the BuddyPress plugin for WP.
41
 
42
  == Description ==
43
 
44
+ s2Member is a robust/powerful ( and free ) membership management system for WordPress®. s2Member integrates seamlessly with PayPal® ( very easy ), and fully supports recurring billing, with the ability to track affiliate commissions on a recurring basis. s2Member supports custom Pages for registration ( including Custom Registration Fields ), account access, and a whole lot more.
45
 
46
+ 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.
47
+
48
+ s2Member allows you to protect Pages, Posts, Tags, Categories, URIs, URI word fragments, Single-Page 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.
49
+
50
+ 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!
51
+
52
+ New! - Now you can sell Single-Page Access too, using "Buy Now" buttons. Further details are provided under `s2Member -> PayPal® Buttons`.
53
 
54
  == Screenshots ==
55
 
67
  == Frequently Asked Questions ==
68
 
69
  = Does the PayPal integration work right-out-of-the-box? =
70
+ Yes, it can even generate your PayPal® Subscription Buttons for you. Everything is fully integrated. You even get to create your own Pages within WordPress® to handle Membership Options, the Login Welcome Page, etc. For advanced webmasters, there are scripting techniques that are documented as well. These will help you further develop your site and tailor it to meet your specific needs. s2Member API Scripting is NOT required however.
71
 
72
+ = How many Membership Levels are supported? =
73
+ s2Member supports up to 4 Primary Membership Levels, and unlimited Custom Capabilities. This allows you to create an unlimited number of Membership Packages, all with different Capabilities and prices. You can label your Membership Levels anything you like. The defaults are Bronze, Silver, Gold, Platinum. s2Member also makes it possible to sell an unlimited number of Single-Page Access Links using "Buy Now" buttons. Further details are provided under `s2Member -> PayPal® Buttons`.
74
 
75
+ = Does s2Member utilize the PayPal® IPN system? =
76
+ Yes, s2Member supports automation of account activation, welcome emails, confirmations, renewals, de-activation, refunds, etc. The integration with PayPal® is seamless. 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.
77
 
78
  = Does s2Member support PayPal Auto-Return w/Payment Data Transfer? =
79
  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 enter your Identity Token. If one is enabled, the other must also be enabled. There is a place to enter your PayPal® Identity Token for PDT under `s2Member -> PayPal® Options`. You'll also find some additional instructions there.
80
 
81
  = Does s2Member install any new database tables? =
82
+ No, s2Member has been fully integrated with the Roles &amp; Capabilities that are already built into WordPress®. 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!
83
 
84
  = How does s2Member protect content from public access? =
85
+ s2Member allows you to protect Pages, Posts, Tags, Categories, URIs, URI word fragments, Single-Page Access ( Buy Now! ), and even portions of content within Pages/Posts. 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. 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`.
86
 
87
  = Does s2Member provide an API that I can connect to? =
88
+ 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.
89
 
90
  = Is s2Member compatible with Quick Cache or WP Super Cache? =
91
+ Yes, there were some bugs in the beginning, but they have been fixed now. Both Quick Cache and WP Super Cache will remain compatible with s2Member. We have integrated two internal constants that prevent these plugins from caching important Members Only areas of your site, no matter what your cache configuration might be. The two Constants are: `DONOTCACHEPAGE` and `QUICK_CACHE_ALLOWED = false`. We recommend Quick Cache over WP Super Cache simply because we actually developed Quick Cache and we have done more extensive testing with the s2Member/Quick-Cache combination.
92
 
93
  = Is s2Member compatible with the BuddyPress plugin for WordPress? =
94
  Yes it is. In fact, we must say... the s2Member/BuddyPress combination is just awesome. These two plugins running together make all sorts of things possible.
95
 
96
  = Do you take feature requests for future versions of s2Member? =
97
+ We welcome any and all [contributions](http://www.primothemes.com/donate/) so that s2Member may remain publicly available. If you contribute more than $200, your feature requests will be given high priority, and you will also receive 5 WordPress® themes ( of your choosing ) from PriMoThemes.com.
98
 
99
  = Do you offer professional installation for s2Member? =
100
+ Yes, please contact [PriMoThemes.com](http://www.primothemes.com/contact/) for assistance.
101
 
102
  = Is there a discussion forum for s2Member? =
103
  Yes. In the form of comments on [this page](http://www.primothemes.com/post/s2member-membership-plugin-with-paypal/).
104
 
105
  == Changelog ==
106
 
107
+ = 2.8.6 =
108
+ * Powerful new feature! - s2Member now supports unlimited Custom Capabilities. This allows you to create an unlimited number of Membership Packages, all with different Capabilities ( customized specifically for what your site offers ). Custom Capabilities can also be configured on a per-User basis through your WordPress® Dashboard, under `Users`. For further details, see: `s2Member -> API Scripting -> Custom Capability Packages`.
109
+ * Powerful new feature! - Now you can sell Single-Page Access too, using "Buy Now" buttons. Single-Page Access works independently from Member Level Access. That is, you can sell an unlimited number of Pages using "Buy Now" Buttons, and your Customers will NOT be required to have a Membership Account with your site in order to receive access. If they are already a Member, that's fine, but they won't need to be. Further details are provided under `s2Member -> PayPal® Buttons`.
110
+ * MailChimp® integration. s2Member can now be integrated with MailChimp®. MailChimp® is an email marketing service. MailChimp® makes it easy to send email newsletters to your Customers, manage your MailChimp® subscriber lists, and track campaign performance. Although s2Member can be integrated with almost ANY list server, we highly recommend MailChimp®; because of their powerful API for MailChimp® services. In future versions of s2Member, we plan to build additional features into s2Member that work with, and extend, MailChimp® services.
111
+ * AWeber® integration. As a secondary option, s2Member can also be integrated with AWeber®. AWeber® is an email marketing service. Whether you're looking to get your first email campaign off the ground, or you're a seasoned veteran who wants to dig into advanced tools like detailed email web analytics, activity based segmentation, geo-targeting and broadcast split-testing, AWeber's got just what you need to make email marketing work for you.
112
+ * Bug fix. Some of the %%replacement_codes%% for email messages were returning URL-encoded values. Replacement codes DO return URL-encoded values for API Notifications, because those are designed for use within URLs. However, they should NOT be encoded for email messages. This has been corrected in s2Member v2.8.6.
113
+ * Bug fix. `S2MEMBER_LOGIN_WELCOME_PAGE_URL` was missing in the s2Member JavaScript API. This has been corrected in s2Member v2.8.6.
114
+ * Important change. The API Constant: `S2MEMBER_CURRENT_USER_FIELDS` is now a JSON-encoded array, rather than a serialized array. Check `s2Member -> API Scripting` for code samples. This makes `S2MEMBER_CURRENT_USER_FIELDS` compatible with the PHP API, and also with the s2Member JavaScript API. In PHP, use `json_decode()` instead of `unserialize()`.
115
+ * Important change. The API Constant: `S2MEMBER_CURRENT_USER_IS_LOGGED_IN` works a little bit differently than it has in previous versions. Starting with s2Member v2.8.6, you should change any existing references to: `S2MEMBER_CURRENT_USER_IS_LOGGED_IN`, into this new API Constant: `S2MEMBER_CURRENT_USER_IS_LOGGED_IN_AS_MEMBER`. These two API Constants are documented under `s2Member -> API Scripting`. We're not getting rid of `S2MEMBER_CURRENT_USER_IS_LOGGED_IN` ( it's still useful ), but it does work a bit differently than it has in previous versions. Check the documentation if you're unsure, and we're sorry for the change-up.
116
+ * Under `s2Member -> General Options`, there is a new configuration option for Profile Modifications.
117
+ * Under `s2Member -> PayPal® Options`, there is a new configuration option for EOT behavior.
118
+ * The `s2Member -> API Tracking` field for Signup Confirmation, now supports PHP code too!
119
+ * The PayPal® Button Generator for s2Member, now supports Subscription Modification Buttons.
120
+ * The PayPal® Button Generator for s2Member, now supports Subscription Cancellation Buttons.
121
+ * A new s2Member API Notification event has been added for Single-Page Access.
122
+ * The PayPal® Button Generator for s2Member, now supports "Buy Now" Buttons.
123
+ * A new s2Member API Notification event has been added for Registrations.
124
+ * We've added a new Quick Start Guide for site owners.
125
+ * Documentation and code samples updated throughout.
126
+ * Support for WordPress® MU has been dropped, for now. Once WP 3.0 is released, we will come back to this. If anyone can help contribute to this effort, I would be very appreciative.
127
+
128
  = 2.8.5 =
129
  * Bug fix. A bug was causing the First &amp; Last Name of a new User to be excluded whenever a new User was created manually through the WordPress® Dashboard by an Administrator. This bug was first introduced in v2.8.2 and has now been resolved in v2.8.5.
130
  * Internal references to `?s2AC` and `?s2ABC` have been removed. These have been deprecated since v1.6 anyway. They have now been removed completely in favor of `qcAC` and `qcABC`. These two variables are ONLY used internally, in order to provide compatibility with the Quick Cache plugin for WordPress®. This will have no impact on existing installations of s2Member; UNLESS you're using the Quick Cache plugin. If you ARE using the Quick Cache plugin, you should make sure that you're using Quick Cache 2.1.4+ for the highest level of compatibility with s2Member.
s2member.php CHANGED
@@ -9,13 +9,13 @@ along with this software. In the main directory, see: /licensing/
9
  If not, see: <http://www.gnu.org/licenses/>.
10
  */
11
  /*
12
- Version: 2.8.5
13
- Stable tag: 2.8.5
14
  Framework: WS-P-2.1
15
 
16
  WordPress Compatible: yes
17
  BuddyPress Compatible: yes
18
- WordPress MU Compatible: yes
19
  MU Blog Farm Compatible: soon
20
 
21
  Tested up to: 2.9
@@ -30,6 +30,7 @@ Author: PriMoThemes.com / WebSharks, Inc.
30
  Donate link: http://www.primothemes.com/donate/
31
 
32
  Plugin Name: s2Member
 
33
  Plugin URI: http://www.primothemes.com/post/s2member-membership-plugin-with-paypal/
34
  Customization URI: http://www.primothemes.com/post/s2member-membership-plugin-with-paypal/#comments
35
  Description: Empowers WordPress® with membership capabilities. Integrates seamlessly with PayPal®. Also compatible with the BuddyPress plugin for WP.
9
  If not, see: <http://www.gnu.org/licenses/>.
10
  */
11
  /*
12
+ Version: 2.8.6
13
+ Stable tag: 2.8.6
14
  Framework: WS-P-2.1
15
 
16
  WordPress Compatible: yes
17
  BuddyPress Compatible: yes
18
+ WordPress MU Compatible: soon
19
  MU Blog Farm Compatible: soon
20
 
21
  Tested up to: 2.9
30
  Donate link: http://www.primothemes.com/donate/
31
 
32
  Plugin Name: s2Member
33
+ Professional Installation URI: http://www.primothemes.com/support/
34
  Plugin URI: http://www.primothemes.com/post/s2member-membership-plugin-with-paypal/
35
  Customization URI: http://www.primothemes.com/post/s2member-membership-plugin-with-paypal/#comments
36
  Description: Empowers WordPress® with membership capabilities. Integrates seamlessly with PayPal®. Also compatible with the BuddyPress plugin for WP.