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

Version Description

= v150102 =

(Maintenance Release) Upgrade immediately.

Download this release

Release Info

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

Code changes from version 141007 to 150102

Files changed (31) hide show
  1. changelog.md +527 -0
  2. checksum.txt +1 -1
  3. includes/classes/access-cap-times.inc.php +9 -3
  4. includes/classes/auto-eots.inc.php +1 -1
  5. includes/classes/custom-reg-fields.inc.php +47 -0
  6. includes/classes/files-in.inc.php +2 -2
  7. includes/classes/login-customizations.inc.php +1 -1
  8. includes/classes/mailchimp.inc.php +3 -3
  9. includes/classes/meta-boxes.inc.php +1 -1
  10. includes/classes/mms-patches.inc.php +5 -5
  11. includes/classes/paypal-notify-in-merch-pmt.inc.php +0 -77
  12. includes/classes/paypal-notify-in-sp-refund-reversal.inc.php +151 -142
  13. includes/classes/paypal-notify-in-subscr-modify-w-level.inc.php +368 -355
  14. includes/classes/paypal-notify-in-subscr-or-rp-eots-w-level.inc.php +424 -413
  15. includes/classes/paypal-notify-in-subscr-or-rp-payment-w-level.inc.php +223 -214
  16. includes/classes/paypal-notify-in-subscr-or-wa-w-level.inc.php +334 -311
  17. includes/classes/paypal-notify-in-wa-ccaps-wo-level.inc.php +363 -349
  18. includes/classes/paypal-notify-in-web-accept-sp.inc.php +235 -221
  19. includes/classes/paypal-notify-in.inc.php +0 -3
  20. includes/classes/paypal-return-in-subscr-modify-w-level.inc.php +228 -222
  21. includes/classes/paypal-return-in-subscr-or-wa-w-level.inc.php +57 -51
  22. includes/classes/paypal-return-in-wa-ccaps-wo-level.inc.php +194 -188
  23. includes/classes/paypal-return-in-web-accept-sp.inc.php +140 -134
  24. includes/classes/querys.inc.php +11 -3
  25. includes/classes/users-list-in.inc.php +6 -3
  26. includes/functions/api-functions.inc.php +3 -1
  27. includes/hooks.inc.php +6 -0
  28. includes/menu-pages/api-ops.inc.php +1025 -1014
  29. includes/menu-pages/down-ops.inc.php +92 -1
  30. includes/menu-pages/els-ops.inc.php +1 -1
  31. includes/menu-pages/paypal-ops.inc.php +367 -579
changelog.md ADDED
@@ -0,0 +1,527 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ = v150102 =
2
+
3
+ - (s2Member/s2Member Pro) **Custom Field Mapping:** This release of s2Member adds an internal mapping from s2Member's Custom Field values for each user, to the `get_user_option()` function in the WordPress core. This makes it possible to retrieve user custom field values like always via `get_user_field()` or now through the native `get_user_option()` function also. The benefit of this is that s2Member's custom fields are now more compatible with other themes/plugins for WordPress.
4
+ - (s2Member Pro) **[s2Member-List /] Shortcode:** It is now possible to search through custom fields created with s2Member using the `search_columns=""` attribute; e.g. `search_columns="user_login,user_email,s2member_custom_field_MYFIELDID"`; where `MYFIELDID` can be replaced with a field ID that you generate with s2Member via `Dashboard ⥱ s2Member ⥱ General Options ⥱ Registration/Profile Fields`. See also: [this KB article](http://www.s2member.com/kb/s2member-list-shortcode/) for further details. See also: [this GitHub issue](https://github.com/websharks/s2member/issues/155) for details regarding this improvement.
5
+ - (s2Member/s2Member Pro) **MailChimp Bug Fix** This release fixes a bug first introduced in the previous release, which was causing Interest Groups configured w/ s2Member to not be added properly. Resolved in this release. Props to @ethanpil Thanks!
6
+ - (s2Member Pro) **ccBill Buttons** This release updates all ccBill button graphics. The MasterCard logo has been removed, and a new set of buttons was created to improve upon the set provided in previous versions of s2Member Pro. See: [this GitHub issue](https://github.com/websharks/s2member/issues/392) if you'd like further details.
7
+ - (s2Member Pro) **Authorize.Net** The `AUD` currency code is now supported by Authorize.Net, and thus, s2Member Pro has been updated to support the `AUD` currency code for Pro Forms integrated with Authorize.Net. See [this GitHub issue](https://github.com/websharks/s2member/issues/383) if you'd like further details.
8
+ - (s2Member Pro) **Subscr. CID for Stripe** This release corrects a bug which made it impossible to update the Subscr. CID value (for Stripe) using the user edit form in the Dashboard. For further details, please see [this GitHub issue](https://github.com/websharks/s2member/issues/380).
9
+ - (s2Member/s2Member Pro) **Bug fix** s2Member's membership access times log was failing to collect all required access times under certain scenarios where multiple CCAPS were being added or removed in succession within the same process, but across multiple function calls. This resulted in unexpected behaviors (in rare cases) when attempting to use the `[s2Drip /]` shortcode. Fixed in this release. See [this GitHub issue](https://github.com/websharks/s2member/issues/406) for technical details.
10
+ - (s2Member/s2Member Pro) **Compatibility** This release includes a fix for s2Member's Multisite Network patches applied to the `wp-admin/user-new.php` file whenever you configure s2Member on a Multisite Network. This change makes s2Member compatible with the coming release of WordPress v4.1 and v4.2-beta as it exists now. See: [this GitHub issue](https://github.com/websharks/s2member/issues/410) if you'd like additional details.
11
+ - (s2Member Pro) **Bug Fix:** A feature that was previously introduced in v140816, which made it possible for site owners to set a failed payment threshold (in s2Member's Authorize.Net integration), was suffering from an off-by-one issue during total failed payment calculations. Fixed in this release. See also [this GitHub issue](https://github.com/websharks/s2member/issues/416) if you'd like further details.
12
+ - (s2Member Pro) **Feature Enhancement:** Whenever a failed payment threshold is reached (in s2Member's Authorize.Net integration), not only will s2Member terminate on-site access, but now the underlying ARB (Automated Recurring Profile) is cancelled at the same exact time. This way future billing attempts on the Authorize.Net side will not be possible; i.e. it ensures that a failed payment threshold will always terminate both on-site access and the ARB itself together at the same time, as opposed to allowing the ARB termination to occur automatically via Authorize.Net, _whenever_. See also [this GitHub issue](https://github.com/websharks/s2member/issues/416) if you'd like further details.
13
+ - (s2Member Pro) **ClickBank Disclaimer:** This release of s2Member adds a default Auto-Return Header Template (customizable from `s2Member ⥱ ClickBank Options` in the Dashboard) which includes a disclaimer that ClickBank requires of most merchants before final approval.
14
+
15
+ _This default template should help to reduce the time it takes new merchants to receive final approval from ClickBank when first starting out in the ClickBank network. See also: [this GitHub issue](https://github.com/websharks/s2member/issues/412) if you'd like further details._
16
+ - (s2Member Pro) **Bug Fix:** PayPal Pro Forms for Specific Post/Page Access, and configured with `accept="paypal"` (i.e. to accept PayPal only) were not hiding the entire Billing Method section as intended. Fixed in this release. See also: [this GitHub issue](https://github.com/websharks/s2member/issues/399) if you'd like further details.
17
+ - (s2Member Pro) **Bug Fix:** PayPal Pro Forms using Express Checkout for Billing Agreements under a non-native currency (i.e. under a different currency than their own PayPal account) were failing under some scenarios (notably with the `BRL` currency code). Fixed in this release. See also: [this GitHub issue](https://github.com/websharks/s2member/issues/414) if you'd like technical details.
18
+ - (s2Member Pro) **Stripe API:** s2Member's Stripe integration has been updated to use the new `statement_descriptor` field in favor of the now deprecated `statement_description`. See [this GitHub issue](https://github.com/websharks/s2member/issues/422) for technical details.
19
+ - (s2Member Pro) **Stripe Bug Fix:** In the case of a global tax rate having been applied to the total cost, there were certain scenarios where s2Member Pro would kick back an error message, "Invalid Parameters to Stripe". Fixed in this release. See also: [this GitHub issue](https://github.com/websharks/s2member/issues/425) if you'd like technical details.
20
+ - (s2Member/s2Member Pro) **WP Core Compat.:** This version of s2Member forces the `wptexturize` filter off in WordPress, due to a bug that was introduced in recent versions of the WordPress core; which results in broken shortcodes in some scenarios. Until the underlying bug is fixed in the WP core, the `wptexturize` filter must be disabled to prevent corruption of any WordPress shortcode that may contain `<` or `>` symbols.
21
+
22
+ See [this GitHub issue](https://github.com/websharks/s2member/issues/349) for further technical details. Also referencing: [this WordPress core bug report](https://core.trac.wordpress.org/ticket/29608).
23
+ - (s2Member/s2Member Pro) **Alt. Views:** This release fixes a bug that caused `wp_list_pages()` not to be filtered properly under certain scenarios. A symptom of this bug was to apply s2Member's Alt. View protection for "Pages", but for this not work properly in all cases. Fixed in this release. See also: [this GitHub issue](https://github.com/websharks/s2member/issues/372) if you'd like technical details.
24
+ - (s2Member/s2Member Pro) **Currency Code/Symbol:** All email templates, API Notifications (except cancellation/EOT notifications), and all Custom Return URLs on Success; across all payment gateways; now support two additional Replacement Codes: `%%currency%%` and `%%currency_symbol%%`. See also: [this GitHub issue](https://github.com/websharks/s2member/issues/314) if you'd like additional details.
25
+ - (s2Member Pro) **Coupon Codes:** All transaction-related email templates now support three additional Replacement Codes: `%%full_coupon_code%%`, `%%coupon_code%%`, and `%%coupon_affiliate_id%%`. These have been documented in your Dashboard in places where transaction-related email templates are configured. See also: [this GitHub issue](https://github.com/websharks/s2member/issues/384) if you'd like additional details.
26
+ - (s2Member Pro) **Stripe Tax Info:** s2Member now attaches metadata to Stripe Charges and to Stripe Subscriptions which includes a JSON-encoded object containing two or more properties when tax applies.
27
+
28
+ These metadata properties can be found in your Stripe Dashboard with the metadata key: `tax_info`; which contains the following JSON-encoded properties: `tax` (total tax that was or will be charged on the regular amount), `tax_per` (tax percentage rate that was applied based on your configuration of s2Member Pro); along with `trial_tax` and `trial_tax_per` in the case of a Stripe Subscription that includes an initial/trial period that requires payment; i.e. the tax applied (if any) to an initial/trial payment on a Subscription.
29
+
30
+ We hope this additional information being recorded by s2Member and stored securely within your Stripe account will make it easier for you to maintain accurate bookkeeping records moving forward. This additional metadata is generated for new customers only. It will not be backfilled for any past transactions.
31
+
32
+ - (s2Member Pro) **Stripe Tax Info:** s2Member now passes the tax location; i.e. `address_state`, `address_zip`, and `address_country` to each Stripe Card object associated with a Stripe Customer.
33
+
34
+ We hope this additional information being recorded by s2Member and stored securely within your Stripe account will make it easier for you to maintain accurate bookkeeping records moving forward. This additional cardholder data is collected and stored for new customers only; it will not be backfilled for any past transactions.
35
+
36
+ - (s2Member Pro) **Stripe IP Address:** s2Member now attaches the customer's IP address (as detected via `$_SERVER['REMOTE_ADDR']` on your server) into each Stripe Customer object, along with the customer's full name. These metadata properties can be found in your Stripe Dashboard with the metadata keys: `name` and `ip`.
37
+
38
+ - (s2Member Pro) **Stripe Coupon Code:** s2Member now attaches metadata w/ a coupon code used by your customer (if applicable) to each Stripe Charge and/or Stripe Subscription object.
39
+
40
+ This metadata property can be found in your Stripe Dashboard with the metadata key: `coupon`; which contains the following JSON-encoded property: `code` i.e. the full coupon code used by your customer. This additional metadata is generated for new customers only. It will not be backfilled for any past transactions. Filled only for transactions that use a coupon code.
41
+ - (s2Member Pro) **Stripe Invoice:** This release corrects a bug in s2Member's Stripe integration whereby `subscr-signup-as-subscr-payment` was not always being forced into the core gateway processor; resulting in a miscalculation of the `last_payment_time` under certain scenarios. Fixed in this release. See also: [this GitHub issue](https://github.com/websharks/s2member/issues/396) if you'd like additional details.
42
+
43
+ = v141007 =
44
+
45
+ - (s2Member Pro) **ClickBank IPN v6:** This release enables a new integration option for site owners integrated with ClickBank. You may now choose to integrate with v6 of ClickBank's IPN service, since all previous versions are slowly being phased out by ClickBank. Please see: `Dashboard ⥱ s2Member ⥱ ClickBank Options ⥱ IPN Integration` for v6 config. options. See also [this GitHub issue](https://github.com/websharks/s2member/issues/256) if you'd like further details regarding this topic. See also: [this article @ ClickBank](https://support.clickbank.com/entries/22803622-instant-notification-service).
46
+ - (s2Member/s2Member Pro) **AWeber API Integration:** This release of s2Member adds a new option for site owners using AWeber. It is now possible to integrate with the new [s2Member App](http://www.s2member.com/r/aweber-api-key) for AWeber; i.e. via the AWeber API instead of via email-based communication. For further details, please see: `Dashboard ⥱ s2Member ⥱ API / List Servers ⥱ AWeber Integration`. See also: [this GitHub issue](https://github.com/websharks/s2member/issues/303) if you'd like additional details.
47
+ - (s2Member/s2Member Pro) **Bug Fix:** The EOT Behavior option for `refunds,partial_refunds,reversals` was not being accepted by s2Member. Fixed in this release. Please see [this GitHub issue](https://github.com/websharks/s2member/issues/345) if you'd like further details.
48
+ - (s2Member/s2Member Pro) **MailChimp API Wrapper:** This release of s2Member comes with an updated API wrapper class for MailChimp integration. No change in functionality, just a smoother, slightly faster, and more bug-free interaction with the MailChimp API. Please see [this GitHub issue](https://github.com/websharks/s2member/issues/303) if you'd like further details regarding this improvement. See also: [the official MailChimp API class](https://bitbucket.org/mailchimp/mailchimp-api-php); i.e. what s2Member has been updated to in this release.
49
+ - (s2Member/s2Member Pro) **URI Restrictions caSe-insensitive (Security Fix)** This release of s2Member changes the way URI Restrictions work. All URI Restrictions are now caSe-insensitive (i.e. `/some-path/` is now the same as `/some-Path/`), allowing s2Member to automatically pick up different variations used in attempts to exploit the behavior of certain slugs within the WordPress core. You can also change this new default behavior, if you prefer. Please see: `Dashboard ⥱ s2Member ⥱ Restriction Options ⥱ URI Restrictions`. See also: [this GitHub issue](https://github.com/websharks/s2member/issues/354) for the details about why this was changed in the most recent copy of s2Member.
50
+ - (s2Member/s2Member) **AWeber Role-Based Emails:** In this release we're adding a note in the s2Member UI regarding role-based email addresses being rejected by AWeber. AWeber does not allow role-based emails like: `admin@` or `webmaster@` to be subscribed. It is suggested that you enable s2Member's config. option: "Force Personal Emails" if you intend to integrate with AWeber. Please see: `Dashboard ⥱ s2Member ⥱ General Options ⥱ Registration/Profile Fields`; where you can tell s2Member for force personal email addresses when someone registers on-site. This will prevent a potential subscriber from entering something like `admin@example.com` as their email address.
51
+
52
+ = v140921 =
53
+
54
+ - (s2Member/s2Member Pro) **WP v4 over SSL Compat.** A compatibility issue with the `home_url()` function in the latest release of WordPress has been resolved with this release. Some site owners reported that their s2Member menu pages were appearing without any CSS/JavaScript being loaded; i.e. the graphical UI was not appearing as one would expect under certain scenarios.
55
+ - (s2Member/s2Member Pro) **WP v4 Compat.** This release brings s2Member up-to-date with the latest changes to the `like_escape()` function in WP v4.0. The `like_escape()` function is now deprecated in favor of `wpdb::esc_like()`. s2Member has been updated in this release, but also remains compatible with previous versions of WordPress. See [this GitHub issue](https://github.com/websharks/s2member/issues/329) if you'd like further details.
56
+ - (s2Member Pro) **[s2MOP /] Shortcode Enhancment** The `[s2MOP /]` shortcode allows for a new `required_value=""` attribute. Please see [this KB article](http://www.s2member.com/kb/s2mop-shortcode/) for details about the `[s2MOP /]` shortcode. See also: [this GitHub issue](https://github.com/websharks/s2member-pro/issues/51) if you'd like further details.
57
+
58
+ = v140909 =
59
+
60
+ - (s2Member/s2Member Pro) **Compatibility:** Several instances of `site_url()` (a WordPress core function) have been converted to `home_url()` instead. This provides better compatibility with WordPress installations running from a sub-directory. Please see [this GitHub issue](https://github.com/websharks/s2member/issues/293) if you'd like further details.
61
+ - (s2Member Pro) **Bug Fix:** Ampersands; i.e. `&` symbols in a ClickBank button `desc=""` attribute are now converted to the word `and` automatically. The symbol itself causes issues in ClickBank's IPN processing. Fixed in this release. Please see [this GitHub issue](https://github.com/websharks/s2member/issues/253) if you'd like further details.
62
+ - (s2Member) **Bug Fix:** Improving compatibility with Mozilla/Firefox for the default `wp-login.php?action=register` handler. This release corrects an issue where `<select>` fields contained text with too large a font-size for Mozilla browsers to deal with. Please see [this GitHub issue](https://github.com/websharks/s2member/issues/244) if you'd like further details.
63
+ - (s2Member) **WP v4.0 / bbPress Compat.** A conflict between WordPress v4.0, bbPress v2.5.4 and the previous release of s2Member has been resolved. A symptom of this issue was to see the leading topic post missing from your bbPress forum threads.
64
+
65
+ This was a complex issue related to changes in the most recent copy of WordPress where `WP_Query::$is_search` is flagged as `TRUE` when the `s` key `isset()` instead of `!empty()`. s2Member has implemented a workaround so that the conflict will no longer cause this problem for site owners running s2Member/bbPress.
66
+
67
+ However, please note that some other 3rd-party plugins may still conflict in this way; when running the latest version of bbPress under WordPress v4.0. We are working to notify bbPress and other plugin authors about this issue; just to help others avoid the problem. While unconfirmed, some site owners reported that the Relevanssi search plugin may have some trouble with this also.
68
+ For further details, please see <http://bbpress.org/?p=151839>. See also: [this GitHub issue](https://github.com/websharks/s2member/issues/321) if you'd like all of the details regarding this workaround in the s2Member software.
69
+ - (s2Member) **WP v4.0 Compat.** Updating s2Member's use of the now-deprecated `get_all_category_ids()`. Using `get_terms()` instead. Please see [this GitHub issue](https://github.com/websharks/s2member/issues/322) if you'd like further details.
70
+ - (s2Member Pro) **Stripe Bug Fix:** This release corrects an issue with Stripe Pro Forms and a `$0` trial period. A symptom of this bug was to find a customer's Stripe token value missing from their Customer object in the Stripe Dashboard. This issue impacted Pro Forms whenever a 100% free trial was offered (i.e. with a `$0` sale amount). Resolved by this release. Please see [this GitHub issue](https://github.com/websharks/s2member/issues/326) if you'd like the details.
71
+
72
+ = v140816 =
73
+
74
+ * (s2Member/s2Member Pro) **bbPress Forum Compatibility** Woohoo! This release of s2Member improves s2Member's compatibility with bbPress Forums/Topics/Replies. It is now possible to protect a Forum with s2Member, and have all Topics within that Forum protected automatically. No changes necessary to enable this feature. If you protect a bbPress Forum, this is how s2Member will behave automatically. It's a parent/child relationship that s2Member is now compatible with.
75
+
76
+ *WARNING: If you have been running s2Member together with bbPress in the past, this change may impact you. Any bbPress Forums that are protected by s2Member will now also protect all Topics within that Forum. This improvement also impacts s2Member's Alt. View Restrictions. If you are using s2Member's Alt. View Restrictions, any bbPress Topics that live within a protected Forum will automatically be hidden from Alternative Views configured with s2Member.*
77
+
78
+ Please see [this GitHub issue](https://github.com/websharks/s2member/issues/116) if you'd like more info.
79
+ * (s2Member Pro) **[s2Stream /] Resolutions** Awesome! This release introduces a new Shortcode Attribute (`player_resolutions=""`). See [this screenshot](http://bit.ly/1uASNau) of the details and [this screenshot](http://bit.ly/1uASY5M) of the functionality.
80
+
81
+ This is an s2Member Pro feature that allows a site owner to offer multiple resolutions of a video through the `[s2Stream /]` Shortcode implemented with s2Member's Download Restrictions. Please see [this KB article](http://www.s2member.com/kb/jwplayer-s2stream-shortcodes/#using-s2stream-shortcodes) and choose the **"Shortcode Attributes (Explained)" tab** for all the details, along with an example of `player_resolutions=""` in the `[s2Stream /]` Shortcode.
82
+
83
+ See also: [this GitHub issue](https://github.com/websharks/s2member/issues/179) if you'd like more info.
84
+ * (s2Member Pro) **Authorize.Net** This release introduces a new configurable EOT Behavior option for site owners integrated with Authorize.Net. It is now possible to configure a Max Failed Payments threshold; after which s2Member will automatically trigger an EOT (End Of Term). See: `Dashboard ⥱ s2Member ⥱ Authorize.Net Options ⥱ EOT Behavior`. See also: [this GitHub issue](https://github.com/websharks/s2member/issues/141) if you'd like more info.
85
+ * (s2Member/s2Member Pro) **Enhancement** A new Replacement Code (`%%current_user_nicename%%`) has been introduced by s2Member to improve compatibility with plugins like BuddyPress and bbPress. If you are currently using a Special Login Redirection URL as your s2Member Login Welcome Page, and you've used `%%current_user_login%%` (i.e. the old way), we suggest that you update your Special Redirection URL to use `%%current_user_nicename%%`. Please see [Jason's comments here](https://github.com/websharks/s2member/issues/276#issuecomment-51706582) for further details. See also: `Dashboard ⥱ s2Member ⥱ General Options ⥱ Login Welcome Page`. It is this area of your Dashboard where a Special Redirection URL can be configured.
86
+ * (s2Member Pro) **Pro Login Widget** There are some new Replacement Codes available for the "My Account" page URL, and the "My Profile" page URL whenever you configure the s2Member Pro Login Widget in WordPress. s2Member Pro now supports things like `%%current_user_nicename%%` and `%%current_user_level%%` in these customizable URLs. See: `Dashboard ⥱ Appearance ⥱ Widgets ⥱ s2Member Pro Login Widget` for further details. See also: [this GitHub issue](https://github.com/websharks/s2member/issues/276#issuecomment-51706582) if you'd like more info.
87
+ * (s2Member Pro) **Stripe Bug Fix** Wrapping multiple Stripe Pro Form Shortcodes together as "Checkout Options" was not working properly in the previous release. The dropdown for Checkout Options was not maintaining the underlying variable needed to keep a Checkout Option selected. Fixed in this release. If you'd like more info, please see [this GitHub issue](https://github.com/websharks/s2member/issues/296).
88
+ * (s2Member Pro) **Stripe Bug Fix** A few site owners reported issues between s2Member's integration with Stripe and other plugins that also depend on the Stripe SDK for PHP. Fixed in this release. If you'd like more info, please see [this GitHub issue](https://github.com/websharks/s2member/issues/295).
89
+ * (s2Member Pro) **Pro Cancellation Forms** This release introduces a new Shortcode Attribute that can be used with Pro Cancellation Forms. The new Shortcode Attribute is `unsub=""`. Setting this to a value of `unsub="1"` will enable an automatic unsubscribe upon cancellation. To clarify, this is related to any List Servers (e.g. MailChimp, AWeber, GetResponse) that you integrate with s2Member. If `unsub="1"` when a customer cancels future billing they will also be removed from the mailing list they are currently subscribed to, according to your List Server configuration in s2Member. Please see [this GitHub issue](https://github.com/websharks/s2member/issues/238) if you'd like more info.
90
+ * (s2Member/s2Member Pro) **Child Theme Compabitility** Portions of s2Member (e.g. Return-Page templates, s2Stream templates, Pro Form templates, IP Restriction templates, and more) allow advanced site owners to use custom templates of their own. In the past these templates *had* to be created inside the parent theme directory or inside of your `/wp-content/` directory. Starting with this release, s2Member will also look for custom templates inside of your current Child Theme directory too (i.e. `get_stylesheet_dir()`). Please see [this GitHub issue](https://github.com/websharks/s2member/issues/271) if you'd like more info.
91
+ * (s2Member/s2Member Pro) **S3/CloudFront Compatibility** The latest release of s2Member has been made compatible with the latest changes at Amazon S3/CloudFront [regarding IAM users](http://aws.amazon.com/blogs/aws/updated-iam-console/). If you've been running s2Member together with Amazon S3/CloudFront there are no changes necessary in s2Member configuration. If you are just integrating s2Member with Amazon S3/CloudFront you are advised to setup an IAM user instead of using your AWS Root Keys. s2Member will continue to work with either Root Keys or with IAM user keys. Either are fine. If you'd like more info, please see [this GitHub issue](https://github.com/websharks/s2member/issues/297).
92
+ * (s2Member/s2Member Pro) **MySQLi Compatiblity** This release brings s2Member into full compatibility with the MySQLi extension. In the previous release it was reported that one specific routine in s2Member that checks the total number of users in your WordPress database was incompatible with MySQLi. Resolved in this release. See [this GitHub issue](https://github.com/websharks/s2member/issues/274) if you'd like more info.
93
+ * (s2Member/s2Member Pro) **Amazon CloudFront** s2Member now makes a new button [Reset CloudFront Configuration] available inside of your WP Dashboard under: `s2Member ⥱ Download Options ⥱ Amazon CloudFront`. This button allows a site owner (if necessary) to do a quick reset of s2Member's current integration with Amazon CloudFront Distributions. Please see [this GitHub issue](https://github.com/websharks/s2member/issues/270) if you'd like more info.
94
+ * (s2Member/s2Member Pro) **Bug Fix** This release corrects a bug in s2Member's log of a user's WordPress Capability access times. This bug had no serious impact on previous releases of s2Member. However, it was a bug that needed fixing nonetheless. Resolved in this release. Please see [this GitHub issue](https://github.com/websharks/s2member/issues/237) if you'd like more info.
95
+ * (s2Member/s2Member Pro) **Responsive Compatibility** This release of s2Member makes the `/wp-login.php` file (the WordPress Login/Registration system) Responsive; i.e. more compatible with mobile devices and tablets. This only impacts site owners that use s2Member's Login/Registration Design options to improve and customize the appearance of this core WordPress component. No changes necessary to existing installations for this to kick-in. It's automatic (assuming you are using this s2Member feature). Please see [this GitHub issue](https://github.com/websharks/s2member/issues/211) if you'd like more info.
96
+ * (s2Member Pro) **Remote Operations API** This release of s2Member makes it possible to change the API Key assigned to your WordPress installation. The Pro Remote Operations API is one way for developers to integrate with some of s2Member's functionality. See: `Dashboard ⥱ s2Member ⥱ API / Scripting ⥱ Remote Operations API`. This is where it's possible to change your API Key if you'd like to. Please see [this GitHub issue](https://github.com/websharks/s2member/issues/206) if you'd like more info.
97
+ * (s2Member/s2Member Pro) **Enhancement** s2Member's Auto-Return system (i.e. default Thank-You page handler) which integrates with: PayPal Standard Buttons, ClickBank, and Google Wallet; has been updated in this release. If a customer happens to find their way back to a self-expiring Auto-Return URL (a rare occurrence); instead of an unfriendly error message about duplicate return data, s2Member now provides a more friendly note that asks the customer to check their email for the details needed to access what they paid for. Please see [this GitHub issue](https://github.com/websharks/s2member/issues/205) if you'd like more info.
98
+ * (s2Member/s2Member Pro) **Enhancement** s2Member's Security Encryption Key configuration panel in the Dashboard was updated to include additional details related to the use of your Security Encryption Key. This additional information explains s2Member's use of this key in greater detail. See: `Dashboard ⥱ s2Member ⥱ General Options ⥱ Security Encryption Key`. See also: [this GitHub issue](https://github.com/websharks/s2member/issues/182) if you'e like more info.
99
+ * (s2Member Pro) **One-Time-Offers Upon Login** This release resolves a conflict between s2Member's Pro Login Widget and One-Time-Offers (Upon Login) — a feature that can be configured with s2Member Pro. One-Time-Offers (Upon Login) now take precedence over certain automatic login redirections that can occur through the Pro Login Widget, removing the chance of a conflict. If a visitor logs into their account with a default login redirection URL (i.e. a redirection URL formulated dynamically by the Pro Login Widget that is not related to a visitor's request to access a specific page of the site), and a One-Time-Offer is triggered at the same time, the One-Time-Offer will take precendence. The visitor will see the One-Time-Offer instead of being redirected to the default location specified by the Pro Login Widget. Please see [this GitHub issue](https://github.com/websharks/s2member/issues/119) if you'd like more info.
100
+
101
+ = v140725 =
102
+
103
+ * (s2Member Pro) **NEW: Stripe Pro Forms (Beta)** Holy hula hoop! s2Member now has a deep integration with Stripe for on-site credit card processing that uses a Stripe overlay. Stripe is an almost-free service that is super easy to setup and work with. We think you'll find that Stripe is quickly becoming the MOST popular of all payment gateways in the industry. A few bugs have [already been zapped](https://github.com/websharks/s2member/issues?milestone=5&page=1&state=closed) prior to this release after some initial beta testing was completed over the last few weeks. Everything is looking great so far, but please do [report any new issues via GitHub](https://github.com/websharks/s2member/issues?page=1&state=open).
104
+
105
+ **If you are an s2Member Pro site owner** you can upgrade to the latest version of s2Member Pro at anytime you like; then enable Stripe as an additional payment gateway option. See: `Dashboard ⥱ s2Member Pro ⥱ Other Gateways`.
106
+
107
+ **Questions About Stripe?** Please watch [this video](http://www.s2member.com/videos/L0aJz4-9mNanxemFZ_3G2-SIn-xAoiwD/) by Lead Develoer Jason Caldwell regarding s2Member's new integration with Stripe payment processing. It's never been easier! Jason answers several questions about Stripe in this video also. You might _also_ find it interesting to hear the [latest news regarding Stripe and Bitcoin](https://stripe.com/blog/bitcoin-the-stripe-perspective). We look forward to supporting Bitcoin in s2Member (via Stripe) very soon.
108
+
109
+ * (s2Member Pro) **NEW: Advanced Import/Export Tools Option** This release introduces a new "Advanced" set of user import/export tools. We think you'll find this to be an extremely helpful and much more powerful way to deal with user import/export in WordPress. Please see `Dashboard ⥱ s2Member ⥱ Import/Export` and click the link to enable the new Advanced Import/Export Tools. See also: [this KB article](http://www.s2member.com/kb/advanced-import-tools/) which documents the new tools. See also: [this GitHub issue](https://github.com/websharks/s2member/issues/149) if you'd like further details about the development behind this new feature.
110
+ * (s2Member Pro) **ClickBank Bug Fix** Nillable fields causing some issues (only under one specific scenario) after a recent change in the ClickBank API. Fixed in this release. See [this GitHub issue](https://github.com/websharks/s2member/issues/250) if you would like further detais.
111
+ * (s2Member Pro) **Compatibility** Resolved a minor single-quote issue in the Visual Editor. Please see [this GitHub issue](https://github.com/websharks/s2member/issues/228) if you'd like further details.
112
+ * (s2Member/s2Member Pro) **Bug Fix** Non-HTML whitespace being trimmed inside the `[s2If /]` shortcode. Resolved in this release. Please see [this GitHub issue](https://github.com/websharks/s2member/issues/224) if you'd like further details.
113
+ * (s2Member Pro) **Pro Forms Bug Fix** Related to List Server processing during an upgrade. This bug impacted all payment gateways integrated with s2Member's Pro Forms; including PayPal, Authorize.Net and now Stripe. Resolved in this release. Please see [this GitHub issue](https://github.com/websharks/s2member/issues/216) if you'd like further details.
114
+ * (s2Member Pro) **Bug Fix** An `array_intersect()` error in the `[s2MOP /]` shortcode under the right conditions. Fixed in this release. Please see [this GitHub issue](https://github.com/websharks/s2member/issues/204) if you'd like further details.
115
+ * (s2Member Pro) **Enhancement** Free Registration Pro Forms can now be included in a list of nested Checkout Option drop-downs. Please see [this GitHub issue](https://github.com/websharks/s2member/issues/197) if you'd like further details. See also: `Dashboard ⥱ s2Member ⥱ [Your Payment Gateway] Pro Forms ⥱ Checkout Options`; where there is more information about how to use Checkout Options with s2Member Pro Forms.
116
+ * (s2Member/s2Member Pro) **Bug Fix / List Servers** This release corrects a bug that may cause members to be unsubscribed from a List Server if they forget to check the box again while editing their profile. In the previous release we introduced a feature that allows the checkbox to be pre-checked if the user already chose to subscribe once before. However, the internal tracking for this was not as reliable as it could be. There is still more work to be done on this front, but the immediate issue has now been resolved. Please see [this GitHub issue](https://github.com/websharks/s2member/issues/196) if you'd like further details.
117
+ * (s2Member/s2Member Pro) **WP_DEBUG Compat.** Some older portions of s2Member's codebase were cleaned up and reformatted in this update. This is an ongoing process to bring s2Member into full compatibility with `WP_DEBUG` mode in WordPress. This is intended to help other developers in the WP community. Much progress has been made on this front now, but still some more work to do. We will continue to update s2Member's codebase little-by-little with each release.
118
+ * (s2Member/s2Member Pro) **Uninstall vs. Deactivation** s2Member has always made a strong effort to cleanup after itself should you decide (for whatever reason) to uninstall it. However, we are also very concerned with preserving any data associated with such a powerful plugin that comes with so many options. Nobody wants accidental data loss, right!?
119
+
120
+
121
+ In the past, s2Member came with a feature called "Deactivation Safeguards". These (if disabled) attached themselves to a plugin "deactivation" hook within WordPress and they would uninstall s2Member when you deactivated the plugin. Starting with this release ,s2Member's Deactivation routines have been changed. We now attach them to the WordPress "uninstall" hook — which is triggered only on plugin deletion.
122
+
123
+ In this way, deactivating s2Member will never result in a loss of any data. Instead of "Deactivation Safeguards", s2Member now calls this feature "Plugin Deletion Safeguards". In short, to tell s2Member to uninstall itself (including any data/options associated with s2Member), you can simply disable s2Member's Plugin Deletion Safeguards under: `s2Member ⥱ General Options`, and then deactivate _and delete_ the s2Member plugin entirely. Whenever you delete the plugin this automatically and silently triggers s2Member's uninstaller which cleans up after itself nicely :-)
124
+
125
+ = v140630 =
126
+
127
+ - (s2Member Pro) **Stripe Payment Gateway** Hooray! s2Member Pro now integrates with [Stripe](http://www.s2member.com/r/stripe). s2Member Pro Forms, Coupon Codes, Tax Settings, Checkout Options, and all of the other great features provided by s2Member Pro are now compatible with Stripe. To enable Stripe in your installation of s2Member, please see: `Dashboard ⥱ s2Member ⥱ Other Gateways ⥱ Stripe`.
128
+
129
+ We expect Stripe to become the most popular payment gateway integration for s2Member Pro over the next few months. Stripe is nearly free; it's easier to setup, easier to maintain; and just more flexible overall in our opinion.
130
+
131
+ _See also: [this GitHub issue](https://github.com/websharks/s2member/issues/177) where efforts to integrate with Stripe took place. A quick tutorial video and KB articles will come soon at s2Member.com; once beta testing is complete._
132
+ - (s2Member Pro) **Bug Fix; [s2MOP /]** This release corrects a bug in the `[s2MOP /]` `restriction_type` attribute. See [this GitHub issue](https://github.com/websharks/s2member/issues/204) if you'd like further details.
133
+
134
+ = v140614 =
135
+
136
+ * (s2Member/s2Member Pro) **Quick Cache Compat.** This release makes it possible for Quick Cache to cache content protected by s2Member. If, and only if, you have [Quick Cache Pro](http://www.websharks-inc.com/product/quick-cache/) configured to enable user-specific caching; i.e. to cache when users are logged into the site. See [this GitHub issue](https://github.com/websharks/s2member/issues/172) if you'd like further details.
137
+ * (s2Member Pro) **ClickBank API Compat.** This release brings s2Member's ClickBank integration into full compatibility with a recent change in the ClickBank API. Under the right conditions, a symptom of this bug was to see an error regarding an unexpected `txnType` upon returning from checkout via ClickBank. Resolved in this release. See [this GitHub issue](https://github.com/websharks/s2member/issues/199) if you'd like further details.
138
+
139
+ = v140603 =
140
+
141
+ * (s2Member/s2Member Pro) **Profile Sync to List Servers** If you have a supported List Server integrated with s2Member (e.g. MailChimp, GetResponse, AWeber), the opt-in checkbox will now also be displayed in user profile editing panels (i.e. by the `[s2Member-Profile /]` shortcode, or if you integrate s2Member with BuddyPress profiles).
142
+
143
+ If a user updates their profile, their profile on the List Server is updated too (i.e. s2Member updates their first name, last name, along with any merge vars or customs you've integrated through s2Member hooks/filters). If a user changes their email address, they will be subscribed with the new email address. Leaving the box unchecked during a profile update will effectively unsubscribe the user from the lists you have configured at their current Membership Level.
144
+
145
+ *s2Member's AWeber integration does not yet support profile updates (i.e. changes in first/last name or other details); it only supports the ability to either subscribe or unsubscribe; and/or changes in email address.*
146
+
147
+ See [this GitHub issue](https://github.com/websharks/s2member/issues/146) if you'd like further details.
148
+ * (s2Member/s2Member Pro) **BuddyPress Compatibility** This release makes s2Member and s2Member Pro compatible with the latest release of BuddyPress. BuddyPress v2.01 broke some of s2Member's previous integration. Fixed in this release. See [this GitHub issue](https://github.com/websharks/s2member/issues/162) if you'd like further details.
149
+ * (s2Member/s2Member Pro) **Multisite Lost Password URL** In a multisite environment (given the WordPress default behavior), a lost password URL generated by WordPress will force all users to recover their password from the Main Site in the Network; which is usually NOT desirable. This release of s2Member fixes this odd behavior in the WordPress core by allowing users to recover their password in the UI for the current Child Blog they are accessing. See [this GitHub issue](https://github.com/websharks/s2member/issues/138) if you'd like further details and ways to enable/disable; or even customize this further.
150
+ * (s2Member/s2Member Pro) **Default EOT Behavior** By popular demand, this release changes s2Member's default EOT (End Of Term) Behavior option with respect to refunds/chargebacks. The new default behavior (assuming you have not yet configured s2Member) is to force an EOT on chargebacks only; not on a refund of any kind. A refund is just a refund (in many cases) and an EOT (if one should occur) is something that a site owner generally should decide on their own; i.e. to review refunds manually and if an EOT should occur, the site owner will mostly like prefer to terminate a user's account access on their own; and on a case-by-case basis.
151
+
152
+ **Further clarification...** EOT (End Of Term) is meant to occur when a subscription ends, and since a refund doesn't necessarily end a subscription, it's not the default anymore to trigger an automatic EOT on a refund event. Site owners that want an EOT on refunds still have that option available to them however. See `Dashboard ⥱ s2Member ⥱ [Payment Gateway] Options ⥱ Auto EOT Behavior ⥱ Chargebacks/Refunds`.
153
+
154
+ See also: [this GitHub issue](https://github.com/websharks/s2member/issues/183) if you'd like further details.
155
+ * (s2Member/s2Member Pro) **Currency Conversion** s2Member's integration with the Google Currency Converter went stale after some changes to the Google API. This release updates s2Member's internal currency conversion routines to correct the issue. See [this GitHub issue](https://github.com/websharks/s2member/issues/169) if you'd like further details.
156
+ * (s2Member/s2Member Pro) **Bug Fix** This release corrects a sortable User column issue in the WordPress Dashboard; with respect to numeric values stored in the WordPress meta table. A symptom of this bug was to see sortable columns for Last Login Time, Total Logins, or EOT Time just a bit out of whack in some scenarios. Fixed in this release. See [this GitHub issue](https://github.com/websharks/s2member/issues/164) if you'd like further details.
157
+ * (s2Member/s2Member Pro) **Bug Fix** Updating the inline documentation for the `[s2Drip /]` shortcode in the Dashboard to match the most recent improvements to this feature; and to bring it up-to-date with [this KB article](http://www.s2member.com/kb/s2drip-shortcode/). See [this GitHub issue](https://github.com/websharks/s2member/issues/163) if you'd like further details.
158
+ * (s2Member Pro) **Enhancement** This release enhances the UI and error reporting for the `[s2Member-List /]` shortcode. See [this GitHub issue](https://github.com/websharks/s2member/issues/161) if you'd like further details. See also [this KB article](http://www.s2member.com/kb/s2member-list-shortcode/).
159
+ * (s2Member Pro) **Bug Fix** This release corrects an issue with the `[s2Member-List /]` shortcode when used on a site that does not use fancy permalinks. See [this GitHub issue](https://github.com/websharks/s2member/issues/160) if you'd like further details.
160
+ * (s2Member/s2Member Pro) **Bug Fix** This release adds width/height attributes to the image tags used in the s2Member Security Badges that display on-site (if you enable them); allowing them to pass a W3C validation. See [this GitHub issue](https://github.com/websharks/s2member/issues/157) if you'd like further details.
161
+ * (s2Member Pro) **Logging Enhancement** This release improves s2Member's log files with respect to Recurring Profiles created through PayPal Pro (Payflow Edition) and/or Authorize.Net. s2Member's automatic polling routines will now log scenarios where a user's account record is missing the original IPN Signup Vars that should be present on a site running s2Member Pro. See [this GitHub issue](https://github.com/websharks/s2member/issues/104) if you'd like further details.
162
+
163
+ = v140520 =
164
+
165
+ * (s2Member Pro) **`[s2Member-List /]` Shortcode** Amazing new feature! It is now possible to list members using a powerful shortcode, and even make it possible for members to view and search for each other. See [this KB article](http://www.s2member.com/?p=62860) for all the details on this feature. Very cool!
166
+ * (s2Member/s2Member Pro) **Server-Side Validation** For Registration/Profile Fields that you configure on your own (using the s2Member software), there is now support within all areas of the s2Member codebase for both JavaScript and *now server-side validation too*. In the past, all validations applied to custom fields was via JavaScript only. With server-side validation too, now it is impossible for required and/or invalid fields that you configure to go missing. This also resolves a few issues related to spam bots attempting to bypass JavaScript validation. See [this GitHub issue](https://github.com/WebSharks/s2Member/issues/99) if you'd like further details.
167
+ * (s2Member Pro) **Button Processing Animation**. Improving the processing animation used in submit buttons across Pro Forms. Instead of a script-based solution (rather jumpy), we are now taking advantage of CSS3 for a much smoother animation. See [this GitHub issue](https://github.com/WebSharks/s2Member/issues/114) if you'd like further details.
168
+ * (s2Member Pro) **`[s2Drip /]` Shortcode Enhancement** This release adds support for a new `access=""` shortcode attribute that can parse `and` / `or` logic. Also, it is now possible for `[s2Drip /]` to be used with Custom Capabilities too! See [this KB article](http://www.s2member.com/kb/s2drip-shortcode/) for all the details.
169
+ * (s2Member/s2Member Pro) **Bug Fix, Custom Fields UI** This release corrects a bug related to the `jquery/.htaccess` file that ships with s2Member. A symptom was to have issues with the Registration/Profile Fields UI and find a JS error in the browser's developer console. Fixed in this release. See also, [this GitHub issue](https://github.com/WebSharks/s2Member/issues/144#issuecomment-43198045) if you'd like further details.
170
+ * (s2Member Pro) **Bug Fix, Clickbank HTTPS** This release corrects a bug in the default Auto-Return Page for ClickBank, when/if it's served over the `https` protocol. See [this GitHub issue](https://github.com/WebSharks/s2Member/issues/145) if you'd like further details.
171
+ * (s2Member/s2Member Pro) **Sortable User Columns** This release adds support for sortable user columns in the Dashboard, where possible. Things like EOT Time, Registration Time, Last Login Time, Total Logins, etc. NOTE: it is currently NOT possible to sort by Custom Registration/Profile Fields (yet). See [this GitHub issue](https://github.com/WebSharks/s2Member/issues/147) if you'd like further details.
172
+ * (s2Member/s2Member Pro) **Hook Priority for Translations** This release corrects a bug related to Gettext translations. There were a couple of areas within s2Member that weren't picking up all of the translation entries; caused by a conflict in hook priority. Fixed in this release. See [this GitHub issue](https://github.com/WebSharks/s2Member/issues/132) if you'd like further details.
173
+ * (s2Member Pro) **`[s2MOP /]` Shortcode Enhancement** A new Replacement Code was added: `%%REQUIRED_LEVEL_LABEL%%`. See [this KB article](http://www.s2member.com/kb/s2mop-shortcode/) and [this GitHub issue](https://github.com/WebSharks/s2Member/issues/129) if you'd like further details.
174
+
175
+ = v140423 =
176
+
177
+ * (s2Member/s2Member Pro) **WP v3.9 Compatibility**. Resolving an incompatibility between s2Member and WP v3.9 where s2Member was attempting to use the jQuery `highlight` effect no longer available by default; starting with WP v3.9. A symptom of this bug was to have problems closing the dialog box when creating new Registration/Profile Fields with s2Member in the WP Dashboard. See also [this GitHub issue](https://github.com/WebSharks/s2Member/issues/108).
178
+ * (s2Member Pro) **User Export Limitation**. Adding an option to the Import/Export panel used to export Users from your installation of WordPress. This new option makes it possible to specify an exact number of maximum rows to export; instead of the previous behavior which forced to a value of `1000` max. See also [this GitHub issue](https://github.com/WebSharks/s2Member/issues/80).
179
+ * (s2Member Pro) **s2Drip Enhancement**. Updating the s2Drip shortcode to allow for a time frame that specifies `from_day="1" to_day="1"`. See also [this GitHub issue](https://github.com/WebSharks/s2Member/issues/103). For instructions on how to use the `[s2Drip]` shortcode see [this KB article](http://www.s2member.com/kb/s2drip-shortcode/).
180
+ * (s2Member Pro) **s2Drip Enhancement**. Adding support for nested shortcodes inside the `[s2Drip]` conditional shortcode tags. See [this commit](https://github.com/WebSharks/s2Member-Pro/commit/3d042250736a074136924afd5b4030065aff881e) for detailed changes. For instructions on how to use the `[s2Drip]` shortcode see [this KB article](http://www.s2member.com/kb/s2drip-shortcode/).
181
+ * (s2Member Pro). **s2MOP Enhancement**. Adding an optional `%%POST_EXCERPT%%` Replacement Code to the `[s2MOP]` shortcode. For further details see [this GitHub issue](https://github.com/WebSharks/s2Member-Pro/pull/11). For instructions on how to use the `[s2MOP]` shortcode see [this KB article](http://www.s2member.com/kb/s2mop-shortcode/).
182
+ * (s2Member Pro). **s2MOP Enhancement**. Improving `[s2MOP]` Replacement Codes overall by converting internal slugs into textual labels for an improved user experience. Also making it possible to filter the default labels. See [this GitHub issue](https://github.com/WebSharks/s2Member-Pro/pull/10). For instructions on how to use the `[s2MOP]` shortcode see [this KB article](http://www.s2member.com/kb/s2mop-shortcode/).
183
+ * (s2Member Pro) **s2MOP Enhancement**. Adding support for nested shortcodes inside the `[s2MOP]` shortcode. For instructions on how to use the `[s2MOP]` shortcode see [this KB article](http://www.s2member.com/kb/s2mop-shortcode/).
184
+ * (s2Member/s2Member Pro) **Time Tracking**. This release begins tracking some additional timestamps to be used by features coming in a future version of s2Member. A new routine was added internally to go ahead and begin tracking some additional timestamps associated with the addition and/or removal of specific Membership Levels and/or Custom Capabilities. A future release of s2Member will take advantage of this data in some of it's shortcodes and API Functions (coming soon). See also [this GitHub issue](https://github.com/WebSharks/s2Member/issues/84).
185
+ * (s2Member/s2Member Pro) **Bug Fix**. A bug related to domain validation against some of the latest TLDs like `.photography` or `.solutions` has been resolved with this release. See also [this GitHub issue](https://github.com/WebSharks/s2Member/issues/98).
186
+ * (s2Member) **Bug Fix**. The declaration `function ksort_deep` should be `public static function ksort_deep`. Fixed in this release.
187
+ * (s2Member/s2Member Pro) **Bug Fix**. s2Member preventing some fields from making it into results provided by `WP_User_Query` on the front-end of a site utilizing this core class. Fixed in this release. See also [this GitHub issue](https://github.com/WebSharks/s2Member/issues/95).
188
+ * (s2Member Pro). **Authorize.Net Trial Limitation**. Updating s2Member Pro to support a 100% free trial period of any length when integrating with Authorize.Net. See also [this GitHub issue](https://github.com/WebSharks/s2Member/issues/106).
189
+ * (s2Member/s2Member Pro) **WP_DEBUG Compatibility**. Resolving several `E_NOTICE` level messages in an ongoing effort to satisfy `WP_DEBUG` mode. For further details, please see [this GitHub issue](https://github.com/WebSharks/s2Member/issues/97). See also [issue #105](https://github.com/WebSharks/s2Member/issues/105). See also [issue #91](https://github.com/WebSharks/s2Member/issues/91).
190
+
191
+ = v140409 =
192
+
193
+ * (s2Member Pro) **s2MOP Shortcode**. A new shortcode is now available for site owners running s2Member Pro: `[s2MOP]`. For further details, please check your Dashboard under: `s2Member ⥱ API / Scripting ⥱ Membership Options Page / Variables`. See also: [this KB article](http://www.s2member.com/kb/s2mop-shortcode/).
194
+ * (s2Member/s2Member Pro) **Compatibility**. Reviewed by Lead Developer Jason Caldwell for full compatibility against WordPress v3.9. s2Member also remains backward compatible with WP v3.3 - 3.8.
195
+ * (s2Member/s2Member Pro) **Security Review**. Reviewed by Lead Developer Jason Caldwell to look closer at any portions of s2Member which might be impacted by the [OpenSSL Heartbleed bug](http://heartbleed.com/). Please note, the Heartbleed bug is NOT an s2Member bug. It is a bug in the OpenSSL library used by many services across the web. Please see this [GitHub issue](https://github.com/WebSharks/s2Member/issues/90) where Jason posted a few tips for site owners running the s2Member software.
196
+ * (s2Member/s2Member Pro) **s2 MOP Vars**. The format of s2Member's MOP Vars has been updated in this release. Backward compatibility remains for the older formats, so this should not cause any problems for site owners using the older formats provided by previous versions of s2Member. For further details, please check your Dashboard under: `s2Member ⥱ API / Scripting ⥱ Membership Options Page / Variables`.
197
+ * (s2Member/s2Member Pro) **s2 MOP Vars**. s2Member MOP Vars are now an optional feature. It is now possible to disable the additional variables that s2Member appends to the end of your Membership Options Page URL when it redirects a visitor without access to something you've restricted. To configure this new option, please check your Dashboard under: `s2Member ⥱ General Options ⥱ Membership Options Page`.
198
+ * (s2Member/s2Member Pro) **Bug Fix**. Updating core IPN handler to correct a PHP warning `array to string conversion`. A symptom was to see warnings in your PHP error log when using a custom Thank-You page. Fixed in this release.
199
+ * (s2Member/s2Member Pro) **Bug Fix**. Updating the new EOT Time column in the list of WP Users so it displays a human readable date and time; as opposed to a UNIX timestamp. Fixed in this release.
200
+
201
+ = v140328 =
202
+
203
+ * (s2Member/s2Member Pro) **Compatibility**. Updated to support WordPress v3.9. Nothing significant, just minor UI tweaks to make s2Member fully compatible with WP v3.9.
204
+ * (s2Member) **Compatibility**. Updating for backward compatibility with WordPress v3.8 - 3.3 by tweaking calls to `get_post()`. See this [commit](https://github.com/WebSharks/s2Member/commit/7b8c8aecc3e8d0d0bada3e80f41615b968a763f8) for further details.
205
+ * (s2Member/s2Member Pro) **Translations**. Updating the `includes/translations/s2member.pot` [file](https://github.com/WebSharks/s2Member/tree/000000-dev/s2member/includes/translations) to include the entire set of translation strings for both s2Member and s2Member Pro. Some translation entries from JS files were missing in the previous release due to a glitch in our WP i18n processor. Fixed in this release.
206
+ * (s2Member) **Server Check Tool**. Updating the [s2Member Server Scanner](https://www.s2member.com/kb/server-scanner/) to exclude checksum validations against README files. This release includes other scanning improvements also, which allow the tool to do a better job of scanning for compatibility issues.
207
+ * (s2Member Pro) **GetResponse Integration**. This release adds support for GetResponse™ as an email service provider. s2Member now comes preintegrated with GetResponse™ (requires s2Member Pro), MailChimp® and AWeber™ too.
208
+ * (s2Member) **Double Opt-In Article**. Updating inline documentation to include further details about Double Opt-Ins via [this KB article](http://www.s2member.com/kb/double-opt-in-checkbox/).
209
+ * (s2Member) **Compatibility**. Adding support for `$_SERVER['WP_DIR']` (to help developers with a particular edge case). For further details please see [this GitHub issue](https://github.com/WebSharks/s2Member/issues/39).
210
+ * (s2Member) **Auto-EOT Time Column**. This release adds an Auto-EOT Time column to the list of Users in the WordPress Dashboard. Note: it is possible to show/hide specific columns with the Screen Options tab in WordPress.
211
+ * (s2Member) **HTML Trimming**. Adding a new utility method to the s2Member codebase. This [method](https://github.com/WebSharks/s2Member/commit/aa19d23511e9c34a5cc00628285107da9a565594) helps cleanup HTML-based whitespace (and extra line breaks) that are injected inadvertently by some themes when site owners use the `[s2If]` shortcode.
212
+ * (s2Member) **Bug Fix**. Fixing an issue related to Login Redirections over SSL. For further details please see [this GitHub issue](https://github.com/WebSharks/s2Member/issues/59).
213
+ * (s2Member) **All Custom Capabilities**. If your site offers many different CCAPS (Custom Capabilities) and you'd like a way to sell someone access to all of them at once (without needing to list each of them one-by-one); this is now possible. This is accomplished by selling a customer the special CCAP `all_ccaps`. If the `current_user_can('access_s2member_ccap_all_ccaps')`, they will be granted access to ALL Custom Capabilities that you've implemented on the site (now, and in the future). For instance, if the `current_user_can('access_s2member_ccap_all_ccaps')` they can also `access_s2member_ccap_music` even if they don't actually have CCAP `music`. In short, `all_ccaps` grants a customer access to all CCAPS automatically.
214
+ * (s2Member) **E_NOTICE**. Updating several areas of the s2Member codebase in an ongoing effort to make s2Member behave as expected when running in `WP_DEBUG` mode. Note that `WP_DEBUG` is NOT recommended for a production site (this mode is reserved for developers only please).
215
+ * (s2Member) **Bug Fix**. Fixing a bug related to redirections over SSL in an edge case. See [this GitHub commit](https://github.com/WebSharks/s2Member/commit/881a8f513ff00d1932f33928c771cab38ab84dc7) if you'd like further details.
216
+ * (s2Member) **Bug Fix**. Fixing a bug in the way s2Member handles IP Restrictions in one particular area of the source code. See [this GitHub issue](https://github.com/WebSharks/s2Member/issues/63) if you'd like further details.
217
+ * (s2Member) **File Downloads (Content-Encoding)**. Adding a new configurable option for site owners that use protected File Downloads with s2Member. There is a known issue on some hosting platforms; and this new configurable option provides a workaround that is related to the `Content-Encoding` header. Please see: `Dashboard ⥱ s2Member ⥱ Download Options ⥱ Preventing GZIP Conflicts` to configure this new setting. See also [this GitHub issue](https://github.com/WebSharks/s2Member/issues/70) if you'd like further details.
218
+ * (s2Member) **Apache Compatibility**. Updating s2Member's `.htaccess` files to provide support for the `Require` directive supplied by the `authz_core_module` in the most recent versions of Apache. s2Member also maintains backward compatibility for the `allow/deny` directives used in previous versions of Apache.
219
+ * (s2Member Pro) **Gateway-Specific Variables**. Adding gateway-specific variables for use in email templates configured with s2Member. For further details please see [this GitHub issue](https://github.com/WebSharks/s2Member/issues/25).
220
+ * (s2Member) **Cosmetics**. Updating s2Member's adminitrative menu pages to enhance their appearance in the most recent versions of WordPress. Nothing significant, just minor tweaks.
221
+ * (s2Member Pro) **PayPal IPNs**. Adding support for `txn_type` values: `merch_pmt`, `mp_signup`, and `mp_cancel` to enhance s2Member's support for Billing Agreements when integrated together with a PayPal Pro (Payflow Edition) account that processes Express Checkout transactions. This also resolves a bug related to cancellation IPN processing in a specific scenario. Fixed in this release.
222
+ * (s2Member Pro) **[s2If][else]**. Requires s2Member Pro. This release adds support for a new `[else]` condition when using the `[s2If]` shortcode to protect parts of your content. For examples, please see: `Dashboard ⥱ s2Member ⥱ API Scripting ⥱ Simple Shortcode Conditionals`. See also: `Dashboard ⥱ s2Member ⥱ Restriction Options ⥱ Simple Shortcode Conditionals`.
223
+ * (s2Member Pro) **[s2If php=""]**. Requires s2Member Pro. This release adds support for a new `php` Shortcode Attribute; e.g. `[s2If php=""]`. This makes it possible to use arbitrary PHP code in your `[s2If]` shortcodes. For examples, please see: `Dashboard ⥱ s2Member ⥱ API Scripting ⥱ Simple Shortcode Conditionals`. **Note: this feature is disabled by default.** You must enable the `php` attribute for this to work as expected. Please see: `Dashboard ⥱ s2Member ⥱ Restriction Options ⥱ Simple Shortcode Conditionals` (with s2Member Pro installed).
224
+ * (s2Member) **Bug Fix**. Correcting an issue related to Login Redirections and an E_NOTICE. Please see [this GitHub issue](https://github.com/WebSharks/s2Member/issues/75) if you'd like further details.
225
+ * (s2Member Pro) **[s2Drip]**. Requires s2Member Pro. This release adds support for a new easy-to-use shortcode that can drip content to paying Members based on their Membership Level. For examples, please see: `Dashboard ⥱ s2Member ⥱ API Scripting ⥱ Content Dripping`.
226
+ * (s2Member Pro) **ClickBank**. Adding support for the `vtid` parameter in ClickBank Button Shortcodes. See [this GitHub issue](https://github.com/WebSharks/s2Member/issues/44) if you'd like further details.
227
+ * (s2Member Pro) **PayPal Express Checkout**. Updating PayPal Express Checkout cancellation links so they will automatically use the PayPal Merchant ID supplied by a site owner (i.e. PayPal's recommended behavior). If you'd like further details please see [this GitHub commit](https://github.com/WebSharks/s2Member-Pro/commit/5efbe35eed352868a956c94e51ab09f8e561892a).
228
+ * (s2Member Pro) **Pro Forms**. Adding a new filter for developers `s2member_pro_cancels_old_rp_before_new_rp`. This is true by default. If you'd like to prevent s2Member from terminating an existing Recurring Profile (before creating a new one); i.e. during an upgrade... you can set this to a FALSE value. Not recommended, but there are a few edge cases where it could be helpful for developers. See also [this GitHub commit](https://github.com/WebSharks/s2Member-Pro/commit/19a84c81070bb0e1869b5dbd9d0325cc458fd016).
229
+ * (s2Member Pro) **ClickBank Bug Fix**. Adding support for alphabetics in ClickBank Item Numbers. This bug impacted the ClickBank Button Generator only, it did not prevent alphabetics from being used in a raw Shortcode. Still, this has been resolved now. See also [this GitHub issue](https://github.com/WebSharks/s2Member/issues/46).
230
+ * (s2Member Pro) **PayPal Mobile Bug Fix**. This release corrects a bug related to the `MAXAMT` PayPal specification that is sent via Express Checkout on a mobile device. A symptom of this bug was to sometimes see PayPal's awkward default amount of `$25` when completing checkout on a mobile device. Fixed in this release.
231
+ * (s2Member Pro) **PayPal Express Checkout**. This release addresses an issue where a customer reaches PayPal.com with an item description that inadequately reads "Future payment" (i.e. missing the description provided by a site owner). PayPal's latest improvements have made it possible for s2Member to get this right. Resolved in this release.
232
+ * (s2Member/s2Member Pro) **Partial Refunds**. This release adds support for Partial Refunds in the s2Member EOT Behavior Options. See also [this GitHub issue](https://github.com/WebSharks/s2Member/issues/40).
233
+
234
+ = v140105 =
235
+
236
+ * (s2Member/s2Member Pro) **Compatibility**. Updated to support WordPress v3.8. Nothing significant, just minor UI tweaks in the Login/Registration Design for WordPress v3.8; e.g. `wp-login.php` got some minor improvements in this release of s2Member and s2Member Pro.
237
+ * (s2Member) **Compatibility**. PayPal's API for Subscription Cancellation Buttons was changed recently. PayPal now requires a Merchant ID instead of the site owner's email address. This issue has been causing an error when a user attempts to cancel a PayPal Subscription through an s2Member-generated PayPal Subscription Cancellation "Button" (i.e. this affects Buttons only, not Pro Forms). Fixed in this release. Site owners using PayPal Buttons should update their PayPal Merchant ID for s2Member. Please see: `Dashboard ⥱ s2Member ⥱ PayPal Options ⥱ Account Details`.
238
+ * (s2Member/s2Member Pro) **Compatibility**. Default s2Member option value for CSS/JS Lazy Loading is now off instead of on; e.g. s2Member's CSS/JS JavaScript libraries are now loaded on every page by default. Lazy loading must now be enabled by a site owner as a performance enhancement (optional). For further details, please see: `Dashboard ⥱ s2Member ⥱ General Options ⥱ CSS/JS Lazy Loading`.
239
+ * (s2Member Pro) **Remote Operations API**. This release introduces two new API methods; `auth_check_user` and `get_user`. These methods (combined with those which already exist in s2Member Pro) now make s2Member Pro's Remote Operations API a pleasure to work with. For further details, please see: `Dashboard ⥱ s2Member Pro ⥱ API Scripting ⥱ Pro Remote Operations API`. Here you will find the API Key for your installation, along with several code samples.
240
+ * (s2Member/s2Member Pro) **Logging**. s2Member's core payment gateway processors now log to files `gateway-core-ipn.log` and `gateway-core-rtn.log`. These log file names were changed in this release. In previous versions of s2Member these log entries were kept inside `paypal-ipn.log` and `paypal-rtn.log`.
241
+ * (s2Member/s2Member Pro) **Updates**. The XML/RSS feed box for the most recent s2Member Updates (for site owners only; in the Dashboard); has been updated to our newest feed location at: `http://feeds.feedburner.com/s2member`.
242
+ * (s2Member/s2Member Pro) **Bug Fix**. s2Member should follow redirects in API calls to Amazon.com. See: <https://github.com/WebSharks/s2Member/issues/35> for further details.
243
+ * (s2Member/s2Member Pro) **Bug Fix**. By default, do not count login IP Restrictions against users who can `edit_posts`. See: <https://github.com/WebSharks/s2Member/issues/32> for further details.
244
+ * (s2Member/s2Member Pro) **Bug Fix**. Sleep offset to `10` seconds for `subscr_eot`. See <https://github.com/WebSharks/s2Member/issues/34> for further details.
245
+ * (s2Member/s2Member Pro) **Enhancement**. Updating the "s2" icon in the Dashboard to our most recent version.
246
+ * (s2Member Pro) **Bug Fix**. s2Member Pro now accepts `TOO MANY FAILURES` as an EOT response type status under PayPal Pro (Payflow Edition) accounts. This was previously causing a problem against newer PayPal Pro accounts (w/ the Payflow Edition); whereby some customers who were reaching Max Failed Payments were not being demoted properly in all cases. Fixed in this release.
247
+ * (s2Member/s2Member Pro) **Compatibility**. Adding support for `$_SERVER['HTTP_AUTHORIZATION']` when s2Member is used for Remote Auth file hosting. Some servers do not support `$_SERVER['PHP_AUTH_USER']`. Instead, s2Member can get the username/password by parsing them out of `$_SERVER['HTTP_AUTHORIZATION']` when/if necessary. Fixed in this release.
248
+ * (s2Member/s2Member Pro) **PHP Debug Notices.** Updating s2Member's source code to further prevent PHP debug notices when running in `WP_DEBUG` mode. This is part of an ongoing effort keep s2Member running smoothly in PHP strict mode; and to maintain conformity with WordPress standards.
249
+ * (s2Member Pro) **Bug Fix**. Define `abbr_bytes()` method as static to prevent issues during automatic upgrades of s2Member Pro. Please see <https://github.com/WebSharks/s2Member/issues/37> for further details.
250
+ * (s2Member/s2Member Pro) **Backward Compatibility.** Updating calls to `get_post()`. We're adding a `NULL` argument via `$null` to prevent warnings in older releases of WordPress where an argument was required; e.g. `$null = NULL; get_post($null)`.
251
+
252
+ = v131126 =
253
+
254
+ * (s2Member Pro) **Google Wallet.** s2Member Pro now supports [Google Wallet for Digital Goods](https://developers.google.com/commerce/wallet/digital/).
255
+
256
+ In the past we offered support for Google "Checkout" (Google "Checkout" is no longer available as of November 2013). s2Member's previous integration with Google Checkout has now been fully updated to support Google "Wallet" for Digital Goods. To enable Google Wallet in your installation of s2Member Pro, please see: `Dashboard -› s2Member Pro -› Other Gateways -› Google Wallet`. For setup instructions, please see: `Dashboard -› s2Member Pro -› Google Options`.
257
+
258
+ At the time of this writing, there are no KB articles related to Google Wallet at s2Member.com (yet); these will come soon. Until then, you might find it helpful to review dev notes by Jason Caldwell (Lead Developer). Please see: <https://github.com/WebSharks/s2Member/issues/19>.
259
+
260
+ We also suggest that you review the documentation in your Dashboard under: `s2Member Pro -› Google Options` and `s2Member Pro -› Google Buttons`. If you were previously using Google "Checkout", please review [this notice posted by Google](https://support.google.com/checkout/sell/answer/3080449?hl=en).
261
+ * (s2Member/s2Member Pro) **Bootstrap Compatibility.** s2Member has been updated throughout to support the [Twitter Bootstrap](http://getbootstrap.com/) CSS framework when running on a WordPress theme that's been built on Bootstrap. For instance; profile editing forms, custom registration/profile fields, s2Member Pro Forms for checkout/registration; these will now look good on sites powered by Bootstrap. This change has no impact on functionality, only on appearance; and only IF your site is powered by Bootstrap. Throughout s2Member's HTML code we've added CSS class names that follow a Bootstrap standard. These Bootstrap classes are blended together with default structural styles that makes s2Member compatible with all WordPress themes. This way s2Member (and s2Member Pro) can produce a clean/professional appearance on just about any WordPress theme; and now Bootstrap is supported too!
262
+ * (s2Member Pro) **Configurable Emails.** We've added new configuration panels into the s2Member UI for a Modification Confirmation Email and also for the Custom Capability Confirmation Email. These are now configurable for all payment gateways integrated with s2Member Pro; e.g. AliPay, ccBill, ClickBank, Google Wallet, Authorize.Net, PayPal Standard, and PayPal Pro. These emails have always existed, but up until now customization required a WordPress filter. Now it's easier, you can customize these from the Dashboard! Please note: this feature comes only with s2Member Pro. As one example, please check your Dashboard under: `s2Member Pro -› PayPal Options -› Modification Confirmation Email`.
263
+ * (s2Member/s2Member Pro) **Snippets/Redirects.** Snippets and Redirects no longer carry the s2Member Restriction Options meta box in the Post/Page editing station; there's no need for Restrictions against these two special Post Types. This change, together with the latest improvements in these two plugins: [WP Snippets](http://wordpress.org/plugins/wp-snippets/) and [WP Redirects](http://wordpress.org/plugins/wp-redirects/) (also produced by our team) offer a more powerful solution now that all of these plugins are more compatible with each other.
264
+ * (s2Member/s2Member Pro) **Backward Compatibility.** Updating calls to `get_post()`. We're adding a `NULL` argument to prevent warnings in older releases of WordPress where an argument was required; e.g. `get_post(NULL)`.
265
+ * (s2Member/s2Member Pro) **Forward Compatibility.** Adding support for the `relative` scheme in SSL filters that deal with `set_url_scheme()` in the latest versions of WordPress. This improves s2Member's "force SSL mode" where a site owner sets the Custom Field for a Post/Page; e.g. `s2member_force_ssl` is set to `yes`. This change will better support themes/plugins that use absolute relative paths together with WordPress core functions like `site_url()` and `home_url()`.
266
+ * (s2Member/s2Member Pro) **PHP Debug Notices.** Updating s2Member's source code to further prevent PHP debug notices when running in `WP_DEBUG` mode. This is part of an ongoing effort keep s2Member running smoothly in PHP strict mode; and to maintain conformity with WordPress standards.
267
+ * (s2Member Pro) **Unlimited Membership Levels.** Updating the built-in software documentation for s2Member Pro to cover an edge case where a site owner many choose to exceed the recommended maximum for Membership Levels when running s2Member Pro. If you intend to use more than `100` Membership Levels (this is not recommended); but if you do, please see: `Dashboard -› s2Member Pro -› General Options -› Membership Levels/Labels` for the latest details on this.
268
+ * (s2Member/s2Member Pro) **Dropping IE8 Support.** s2Member and s2Member Pro will no longer support IE8 in any official capacity. s2Member's HTML output and CSS files have been cleaned up; and all hacks related to IE8 have been removed. Out with the old, in with the new! We need to keep s2Member up-to-date with the latest improvements offered by IE9 and other modern browsers. While s2Member may continue to function relatively well in IE8, hacks used in the past to accomodate edge cases in this buggy browser have been removed in favor of standards compliance.
269
+ * (s2Member/s2Member Pro) **Lazy Loading CSS/JS.** s2Member now offers site owners the option to enable/disable lazy loading of CSS/JS libraries provided by the s2Member software. For further details, please see: `Dashboard -› s2Member -› General Options -› CSS/JS Lazy Loading`.
270
+ * (s2Member/s2Member Pro) **Bug Fix.** s2Member and s2Member Pro have both been updated to prevent spaces in a comma-delimited list of Custom Capabilities; e.g. `ccaps="music, videos"` should be `ccaps="music,videos"` please. Spaces in this list have never been allowed, but now there is better server-side validation to prevent this from happening; reducing the chance of error when a site owner configures a Button or Pro Form shortcode with s2Member.
271
+ * (s2Member/s2Member Pro) **Other Minor Bug Fixes.** Please see: <https://github.com/WebSharks/s2Member/commits/000000-dev>
272
+
273
+ = v131109 =
274
+
275
+ * (s2Member/s2Member Pro) **UI Makeover** This release of s2Member upgrades all administrative UI panels.
276
+ * (s2Member/s2Member Pro) **Compatibility** Updating s2Member for compatibility with the coming release of both Quick Cache LITE and Quick Cache Pro for WordPress. These are not available publicly yet, but they are expected for release very soon. This release of s2Member is compatible with both the current and future releases of Quick Cache for WordPress.
277
+ * (s2Member/s2Member Pro) **Improvement (Speed)** Lazy load s2Member's JS file at all times. Done, this release will speed your site up for first-time visitors.
278
+ * (s2Member/s2Member Pro) **Improvement (Speed)** Lazy load s2Member's CSS file at all times. Done, this release will speed your site up for first-time visitors.
279
+ * (s2Member/s2Member Pro) **Improvement (Speed)** Load s2Member's JS library in the footer if at all possible (instead of the `<head>`). Done, this will improve the speed of your site for first-time visitors.
280
+ * (s2Member/s2Member Pro) **Debug Notices** Resolved all of the most obvious PHP notices when running s2Member in debug mode. This improvement impacts developers only.
281
+ * (s2Member/s2Member Pro) **Password Strength Meter** Removed dependence on `password-strength-meter` (a JavaScript library) from the WordPress core. This was causing some SSL issues for site owners. In the past it was necessary for s2Member to load an additional JS resource for registration/checkout and Pro Forms (`password-strength-meter`). Starting with this release, s2Member handles password strength meters all by itself, thereby avoiding the additional overhead; and also the issues associated with this core functionality over SSL pages. Fixed in this release.
282
+ * (s2Member/s2Member Pro) **Mobile Devices** The s2Stream shortcode (for protected audio/video files) was updated to better support mobile device playback. See also: <http://www.s2member.com/kb/jwplayer-s2stream-shortcodes/#s2stream-mobile-devices>.
283
+ * (s2Member Pro) **Checkout Options** Improving support for multiple Checkout Options. When a customer changes to a new Checkout Option by selecting an option from the drop-down menu in a Pro Form; this action will now result in a hash jump back to the location of the Pro Form on any given page; instead of to the top of the page, which could potentially result in a confusing experience on some sites (depending on the implementation). Aside: for developers, it's helpful to know that all s2Member Pro Forms now have a hashable ID `#s2p-form` that is cleaner than the longer (product-specific) IDs associated with Pro Forms; e.g. `s2member-pro-paypal-form...`, etc. If you need to hash a Pro Form, please use the more general `#s2p-form` on the end of a URL. This will take a customer directly to that Pro Form in the context of any given page.
284
+
285
+ = v131026 =
286
+
287
+ * (s2Member) **WordPress v3.7 Compatibility** s2Member further updated to support subtle changes in the WordPress v3.7 `wp-login.php` file. This release corrects a minor issue w/ patches applied by s2Member when running in a Multisite Network environment. If you are running s2Member on a Multisite Network, please be sure to run the automatic patcher provided in your Dashboard against WordPress v3.7 after updating to this release of s2Member.
288
+ * (s2Member Pro) **PayPal Central IPN** Updating the example file: `s2m-pro-extras/paypal-central-ipn.php` to use one of the latest PayPal IP addresses listed [here](https://ppmts.custhelp.com/app/answers/detail/a_id/92).
289
+
290
+ = v131025 =
291
+
292
+ * (s2Member) **WordPress v3.7 Compatibility** s2Member updated to support WordPress v3.7. s2Member remains compatible with WP v3.3 (or higher).
293
+ * (s2Member Pro) **New Feature: Simultaneous Login Monitoring** Available only w/ s2Member Pro. s2Member Pro has been updated to support configurations that limit the number of simultaneous logins a single username can receive. For further details, please see: `Dashboard -› s2Member -› Restriction Options -› Simultaneous Login Restrictions` (when s2Member Pro is installed).
294
+ * (s2Member) **Post Restrictions (#3)** Adding support for `all-[post type]` in addition to the existing `all-[post type]s` (plural) currently supported by s2Member's Restriction Options for Posts. This makes it possible for a site owner to type only the Post Type after the keyword prefix `all-`; and excluding the plural `s` in cases when this is necessary.
295
+ * (s2Member) **Documentation Update (#3)** Adding note in Download Options panel regarding `raw` shortcode tags around Shortcodes when using the inFocus theme. See also [this thread](http://mysitemyway.com/support/topic/infocus-adding-tags-into-plugin-content) for further details.
296
+ * (s2Member) **Documentation Cleanup (#12)** General cleanup in several s2Member panels to improve inline documentation that comes w/ the software. Branding improvements, padding adjustments, and subtle textual changes.
297
+ * (s2Member) **Bug Fix (#11)** Running `isset()` against `$cache_needs_updating` to prevent NOTICE when running in `WP_DEBUG` mode.
298
+ * (s2Member) **Optimization (#9)** Removing all image source files (.fla and .pspimage) from the official distribution package to reduce overall filesize.
299
+ * (s2Member) **Quick Start Video (#10)** Adding Quick Start playlist to Quick Start section.
300
+ * (s2Member) **UI (#6)** Reducing padding around section headers in s2Member option panels to reduce the amount of space these consume.
301
+ * (s2Member Pro) **SSL** Forcing all automatic updates of s2Member Pro to occur over SSL for improved security.
302
+ * (s2Member) **Login Welcome Page** Improving support for new feature (force HTTP redirection). See: `s2Member -› General Options -› Login Welcome Page` for details on how this feature works.
303
+ * (s2Member) **Bug Fix: Registration/Profile Fields** Adding space between checkboxes and their labels.
304
+ * (s2Member) **ClickBank IPN Filter** Adding a new filter to s2Member's ClickBank IPN handler for developers integrating s2Member in creative ways: `c_ws_plugin__s2member_pro_clickbank_notify_handles_completions`. Defaults to a TRUE value. Forcing this filter to a FALSE value will prevent s2Member from handling term completions via IPN communication; in cases where it's preferred that a site owner deal with this specific scenario manually.
305
+ * (s2Member) **Conformity** Updating calls to `$wpdb->escape` changing to `esc_sql` to conform w/ WordPress standards.
306
+ * (s2Member Pro) **Compatibility: Checkout Options** Improving theme support for Checkout Options created using Pro Forms by wrapping other Pro Form Shortcodes. Some site owners reported line break injections in the previous verison. Fixed in this release.
307
+ * (s2Member) **See also: s2Member Repo** https://github.com/WebSharks/s2Member/commits/000000-dev
308
+
309
+ = v130816 =
310
+
311
+ * (s2Member Pro) **Compatibility, ClickBank (#467)** Improving support for ClickBank PitchPlus Upsell Flows. Please see [this thread](http://www.s2member.com/forums/topic/clickbank-buttons-not-working/#post-55725) for further details.
312
+ * (s2Member/s2Member Pro) **User Search on Multisite Networks (#468)** User search functionality was partially broken for Child Blogs in a Multisite Network after some improvements were implemented in s2Member® v130731. The issue has now been corrected in this release for Multisite Networks. For further details, please see [this thread](http://www.s2member.com/forums/topic/user-search-no-longer-working/#post-55778).
313
+ * (s2Member/s2Member Pro) **Z-Index in Menu Pages (#461)** Stacking order against a WordPress® installation running a Dashboard with a collapsed sidebar menu (left side) was causing some UI problems. Fixed in this release.
314
+ * (s2Member/s2Member Pro) **SSL Compatibility (#437)** Adding a new option in the `s2Member® -› General Options -› Login Welcome Page` section. The default value for this new option is always `yes`. However, the default functionality can be turned off (if you prefer). This new option allows site owners to better integrate with a core WordPress® feature commonly referred to as `FORCE_SSL_LOGIN` and/or `FORCE_SSL_ADMIN`. This new feature can be used, or not. It is intended mainly for site owners running w/ `FORCE_SSL_LOGIN` and/or `FORCE_SSL_ADMIN`.
315
+ * (s2Member/s2Member Pro) **Login/Registration Design Option (#437)** Adding a new option in the `s2Member® -› General Options -› Login/Registration Design` section. This new option (found at the bottom of `s2Member® -› General Options -› Login/Registration Design`) allows a site owner to show/hide the `Back To Home Page` link at the bottom of the default WordPress® Login/Registration system. This can be useful for site owners running w/ `FORCE_SSL_LOGIN` and/or `FORCE_SSL_ADMIN`; where they would prefer NOT to link customers back to the main site under a default HTTPS link; but rather, create their own link and gain better control over this area of their site.
316
+ * (s2Member/s2Member Pro) **Videos (#467)** Updating internal documentation found in `Dashboard -› s2Member® -› Quick-Start`. Specifically, the video player here was integrated with an older version of the YouTube® API and was not working properly. Fixed in this release.
317
+
318
+ = v130802 =
319
+
320
+ * (s2Member Pro) **Compatibility, WordPress® v3.6** Updating s2Member® Pro Form templates and their underlying CSS. This update improves their appearance against the Twenty Thirteen theme that comes with WordPress® v3.6. Specifically, some of the Pro Form buttons were a little out of place in this new default theme. Fixed in this release.
321
+ * (s2Member Pro) **Compatibility, Checkout Options (#443)** Revision 3. Updating this feature to support a wider variety of WordPress® configurations and content filters. This update also resolves an empty `desc=""` attribute error reported by some site owners. Feature description... It is now possible to build dropdown menus offering your customers a variety of options using a Single Pro Form. This is accomplished quite easily using Shortcodes. For full details and examples, please check this section of your Dashboard in the latest release. See: `s2Member® -› PayPal® Pro Forms -› Wrapping Multiple Shortcodes as "Checkout Options"`. NOTE: this works for PayPal® Pro Forms, and ALSO for Authorize.Net Pro Forms.
322
+
323
+ = v130801 =
324
+
325
+ * (s2Member Pro) **New Feature; Checkout Options (#403)** Revision 2. Updating documentation on this new feature to prevent conufusion for site owners. s2Member® Pro now supports "Checkout Options". It is now possible to build dropdown menus offering your customers a variety of options using a Single Pro Form. This is accomplished quite easily using Shortcodes. For full details and examples, please check this section of your Dashboard in the latest release. See: `s2Member® -› PayPal® Pro Forms -› Wrapping Multiple Shortcodes as "Checkout Options"`. NOTE: this works for PayPal® Pro Forms, and ALSO for Authorize.Net Pro Forms.
326
+
327
+ = v130731 =
328
+
329
+ * (s2Member Pro) **New Feature; Checkout Options (#403)** s2Member® Pro now supports "Checkout Options". It is now possible to build dropdown menus offering your customers a variety of options using a Single Pro Form. This is accomplished quite easily using Shortcodes. For full details and examples, please check this section of your Dashboard in the latest release. See: `s2Member® -› PayPal® Pro Forms -› Wrapping Multiple Shortcodes as "Checkout Options"`. NOTE: this works for PayPal® Pro Forms, and ALSO for Authorize.Net Pro Forms.
330
+ * (s2Member Pro) **Free Checkout (#403)** It is now possible to offer a 100% free checkout experience using any of s2Member's Pro Form Shortcodes. In previous releases of s2Member® it was not possible to set the `ra=""` Attribute to a zero dollar amount. Now it is! This works for PayPal® Pro Forms, and also for Authorize.Net Pro Forms.
331
+ * (s2Member Pro) **100% Off Coupons (#403)** It is now possible to offer a 100% off coupon. This works for PayPal® Pro Forms, and also for Authorize.Net Pro Forms. See: `s2Member® -› Pro Coupon Codes` for details and examples.
332
+ * (s2Member Pro) **Expiration Date Dropdowns (#428)** This release improves all s2Member® Pro Form templates by adding dropdown menus for the customer's credit card expiration month/year instead of the simple text input field used in previous releases.
333
+ * (s2Member/s2Member Pro) **MySQL Wait Timeout (#349)** s2Member now automatically increases the MySQL `wait_timeout` to `300` seconds during s2Member processing routines. Reason for increase: should any 3rd party service API result in unexpected connection timeouts (such as PayPal, Authorize.Net, Amazon, MailChimp, AWeber, etc); this may cause a delay that could potentially exceed the default `wait_timeout` of `30` seconds on the MySQL resource handle that is global to all of WordPress. Increasing `wait_timeout` before transaction processing will decrease the chance of failure after a timeout is exceeded. Among other things, this resolves an elusive bug where there are mysterious 404 errors after checkout under the right scenario (e.g. when an unexpected timeout occurs). This may also resolve problems associated w/ some mysterious reports where emails were not sent during s2Member's attempt to complete post-processing of a transaction (and/or where other portions of post-processing failed under rare circumstances).
334
+ * (s2Member/s2Member Pro) **Alternative Views (#300)** This release gives s2Member® the ability to hide protected content in widgets that list protected WordPress® Pages. This is a new Alternative View in the Dashboard. See: `s2Member® -› Restriction Options -› Alternative Views` for further details please.
335
+ * (s2Member/s2Member Pro) **Documentation Update (#350)** Subtle improvements to the built-in documentation pertaining to s2Member's Automatic List Transitioning feature in the Dashboard. See: `s2Member® -› API/List Servers -› Automatic Unsubscribes` for further details please.
336
+ * (s2Member/s2Member Pro) **Bug Fix (#387)** In s2Member® Only mode, a recursive scan for the WordPress® `/wp-load.php` file was failing somtimes when/if a custom directory was configured for plugins. Fixed in this release. See [this thread](http://www.s2member.com/forums/topic/problem-with-wordpress-folder-search-code/) for further details.
337
+ * (s2Member/s2Member Pro) **Bug Fix (#418)** Fixed incorrect pagination of user search results in the Dashboard.
338
+ * (s2Member/s2Member Pro) **Bug Fix (#418)** Fixed slow query against user searches in the Dashboard.
339
+ * (s2Member/s2Member Pro) **Bug Fix (#418)** Fixed incorrect result totals under some rare scenarios in user search results.
340
+
341
+ = v130617 =
342
+
343
+ * (s2Member/s2Member Pro) **IP Restrictions (#148)** It is now possible to introduce a custom template file that controls the error message displayed when/if a user breaches security by exceeding your maximum unique IP addresses; as configured under `s2Member -› Restriction Options -› Unique IP Restrictions`. If you would like to use a custom template for this message, please copy the default template file from `/s2member/includes/templates/errors/ip-restrictions.php` and place this file into your active WordPress® theme directory (or into the `/wp-content/` directory if you prefer). s2Member will automatically find your custom template in one of these locations; and s2Member will use your custom template instead of the built-in default.
344
+ * (s2Member Pro) **Bug Fix (#302)** Updating Authorize.Net Pro Form Generator to support max days of `365` instead of `7`.
345
+ * (s2Member Pro) **Amazon S3 Secret Access Keys (#321)** Updating UI configuration panel to better explain what a Secret Access Key is; and adding a note about Secret Access Keys for Amazon S3 integration. Amazon® is deprecating Secret Access Keys, but they ARE still required for digitally signed URLs. This update changes nothing in s2Member's functionality. It simply adds some additional detail to a configuration field that will assist site owners integrating s2Member w/ Amazon S3 for the first time.
346
+ * (s2Member/s2Member Pro) **Translations (#317)** Updating `/s2member/includes/translations/translations.txt` (README file). Adding blurp about fuzzy translation entries in existing PO files that translate s2Member. This contains some additional tips on how to update existing PO files upon each release of s2Member and/or s2Member Pro.
347
+ * (s2Member/s2Member Pro) **Bug Fix (#321)** Fixing bug in `/s2member/includes/templates/cfg-files/s2-cross-xml.php` for S3 Buckets (resulting in `crossdomain.xml`). This file contained a parse error and was causing some problems for site owners integrating Adobe Flash content served via Amazon S3. Fixed in this release.
348
+ * (s2Member Pro) **PayPal Pro Forms (#315)** Adding note in the Dashboard here (`s2Member -› PayPal Pro Forms -› Shortcode Attributes Explained`). In the list of Shortcode Attributes we are adding a note regarding max character length for the `desc=""` Attribute in a PayPal Pro Form Shortcode. This can be as long as you like. However, all descriptions passed through PayPal® APIs are truncated automatically to 60 characters max (e.g. the maximum allowed length for PayPal® descriptions is 60 characters). Nothing new here, but we thought it would be a good idea to clarify this behavior in the documentation. Updated in this release.
349
+ * (s2Member Pro) **PayPal Pro Forms (#312)** Preventing the use of multiple Pro Forms in the same Post/Page. This has never been possible, it is known to break the functionality of s2Member Pro Forms. Please limit Pro Form Shortcodes to ONE for each Post/Page; and do NOT attempt to use more than one Pro Form Shortcode on the same Post/Page (at the same time). In this release we have added a friendly JavaScript alert/warning for site owners that attempt this, so that problems and confusion can be avoided in this unlikely scenario.
350
+
351
+ = v130513 =
352
+
353
+ * (s2Member/s2Member Pro) **s2Stream Shortcode Bug Fix (#256)** Fixing a bug first introduced in the previous release where we added support for `player_aspectratio`. This quick update corrects the PHP parse error at line #154 of `sc-files-in.inc.php`. It also corrects the behavior of the `player_height=""` and `player_aspectratio=""` Shortcode Attributes for the `s2Stream` Shortcode. Many thanks to everyone that reported this bug.
354
+ * (s2Member Pro) **Codestyling Localization** Removing symlink creator for Codestyleing Localization compatibility. There have been some reports of problems during WordPress® automatic upgrades (when/if the symlink exists). Until we can find a way to avoid this, we're disabling the automatic symlink generator. If you're running the Codestyling Localization plugin together with s2Member Pro, you will need to create the symlink yourself if you want to make s2Member fully compatible. Please create a symlink here: `/wp-content/plugins/s2member/s2member-pro` that points to the s2Member Pro directory: `/wp-content/plugins/s2member-pro`. See notes in previous changelog for further details on this.
355
+
356
+ **IMPORTANT NOTE:** If you upgraded previously to v130510 (and you ran the Codestyling Localization plugin together with s2Member® v130510 — at any time); please delete this symlink via FTP: `/wp-content/plugins/s2member/s2member-pro`. Please do this BEFORE attempting an automatic upgrade via WordPress®.
357
+
358
+ If you missed this note and you've already attempted an automatic upgrade, you will have trouble. Here's how to correct the problem.
359
+
360
+ 1. Log into your site via FTP and delete these two directories manually.
361
+ `/wp-content/plugins/s2member` and `/wp-content/plugins/s2member-pro`.
362
+
363
+ 2. Now, please follow the [instructions here](http://www.s2member.com/pro/#!s2_tab_jump=s2-pro-install-update) to upgrade s2Member® Pro manually.
364
+
365
+ = v130510 =
366
+
367
+ * (s2Member Pro) **Authorize.Net UK (and Other Currencies) (#104)** Adding support for Authorize.Net UK and other currencies too. s2Member Pro now officially supports Authorize.Net UK Edition. It is now possible to change your Authorize.Net Pro Form Shortcode Attribute `cc="USD"` to one of these values: `cc="USD"`, or `cc="CAD"` or `cc="EUR"` or `cc="GBP"`. For further details, please see: `Dashboard -› Authorize.Net Pro Forms -› Shortcode Attributes (Explained)`.
368
+ * (s2Member Pro) **ClickBank Skins (#227)** Adding support for the `cbskin=""` Shortcode Attribute. For further details, please see: `Dashboard -› ClickBank Buttons -› Shortcode Attributes (Explained)`.
369
+ * (s2Member Pro) **ClickBank PitchPlus Upsell Flows (#227)** Adding support for ClickBank PitchPlus Upsell Flows via new Shortcode Attributes: `cbfid=""`, `cbur=""`, `cbf="auto"`. s2Member Pro now officially supports ClickBank PitchPlus Upsell Flows. We support PitchPlus Basic and PitchPlus Advanced too. For further details, please see: `Dashboard -› ClickBank Buttons -› Shortcode Attributes (Explained)`.
370
+ * (s2Member/s2Member Pro) **Codestyling Localization** Adding automatic symlink creator for improved compatibility with the CodeStyling Localization plugin. A symlink is created automatically whenever the CodeStyling Localization plugin is installed, and s2Member® Pro is installed as well. The symlink allows the CodeStyling Localization plugin to scan files from the s2Member® Pro directory too; instead of only scanning the s2Member® Framework directory. s2Member and s2Member Pro are now both compatible with the Codestyling Localization plugin (optional).
371
+ * (s2Member/s2Member Pro) **Custom Templates w/ s2Stream Shortcode** Adding support for custom templates to be used in conjunction with the `s2Stream` Shortcode. It is now possible to take the default player templates from `/s2member/includes/templates/players/` and put these files inside your own WordPress® theme directory (or inside the `/wp-content/` directory). s2Member will automatically find your template files in these locations. Your custom template files will then be used instead of the built-in defaults.
372
+ * (s2Member/s2Member Pro) **Bug Fix (#59)** Resending a password to a User from the Dashboard (while changing the User's email address at the same time); resulted in the email being sent to the previous email address instead of the new one. Fixed in this release.
373
+ * (s2Member/s2Member Pro) **Bug Fix (#216)** Removing `-MultiViews` from s2Member's `.htaccess` file in the `/s2member-files/` directory. This improves compatibility with some Apache installations that simply have `AllowOverride All`; because `All` may not include `MultiViews` in some versions of Apache.
374
+ * (s2Member/s2Member Pro) **IP Restrictions (#149)** In the Dashboard, we now report if a User is at (or above) max allowable IPs; instead of reporting only if they have actually triggered an internal security breach (which times out quickly in most cases). Fixed in this release.
375
+ * (s2Member/s2Member Pro) **Enhancing JW Player Integration (#251)** Adding support for s2Stream Shortcode Attribute `player_aspectratio="12:5"` (as one example). See also [this post](http://www.longtailvideo.com/blog/32697/new-in-jw-player-responsive-design) at Longtail Video.
376
+ * (s2Member Pro) **Updating Payflow Integration (#193)** Removing DAILY `D` option for Payflow Recurring Billing. No longer supported by Payflow. However, s2Member will let a `D` value slip by Shortcode Attribute validation in case a site owner has arranged for this to become available against their Payflow account somehow; and to remain backward compatible with previous versions of s2Member Pro. Moving forward, it is NO longer possible to bill customers on a daily basis with PayPal Payments Pro (Payflow Edition). This is a PayPal limitation.
377
+ * (s2Member Pro) **Updating Payflow Integration w/ Payflow Bug Workaround (#193)** Updating Payflow integration to support Billing Agreement IDs (aka: `BAID` values) when working together with Payflow Express Checkout APIs (and where a site owner is charging on a recurring basis).
378
+
379
+ This improvement also allows s2Member to work around a Payflow bug where `BILLINGTYPE=RecurringPayments` results in error `#7 (Invalid/Expired TOKEN)` whenever Payflow attempts to rebill a customer. s2Member now sets `BILLINGTYPE=RecurringBilling`; and we pass `BAID=B-xxxxxx` instead of passing `TOKEN=xxxxxx`.
380
+
381
+ Site owners also need to [contact PayPal MTS](http://www.paypal.com/mts) and ask to have `Reference Transactions` (free) enabled for `Recurring Billing` service. ~ However, you ONLY need `Recurring Billing` service and `Reference Transactions` enabled IF you're operating a PayPal Payments Pro (Payflow Edition) account; and only IF you're charging customers on a recurring basis.
382
+
383
+ All of these changes related to Payflow (as detailed in this changelog entry), impact only ONE specific scenario.
384
+ - You have a PayPal Payments Pro (Payflow Edition) account.
385
+ - You charge your customers on a recurring basis.
386
+ - A customer chooses PayPal as their billing method during checkout.
387
+
388
+ No other part of s2Member's integration with Payflow was modified in this release.
389
+
390
+ For further details, please see [this thread](http://www.s2member.com/forums/topic/paypal-expired-security-token/page/2/) (or monitor the [s2Member KB](http://www.s2member.com/kb/) for new articles on this subject).
391
+ * (s2Member Pro) **Payflow API Docs** Updating `s2m-pro-extras.zip` to include the latest versions of the PayPal Pro (Payflow Edition) APIs. s2Member Pro customers can download this optional ZIP file from their My Account page at s2Member.com. These are extras only, they are NOT part of the s2Member application.
392
+ * (s2Member Pro) **Google Checkout Bug Fix (#214)** Updating s2Member's Google Checkout integration to properly support the `rrt` Shortcode Attribute. Fixed in this release. For further details please see [this thread](http://www.s2member.com/forums/topic/google-recurring-problem/#post-48218).
393
+ * (s2Member Pro) **Username Validation (#246)** Now forcing user input (during Pro Form registration) to lowercase on Multisite Networks to prevent unnecessary validation errors during checkout (saving a customer time). Also, s2Member now validates a customer's Username before it is passed through `sanitize_user()` (a core WordPress® function). This prevents confusion for a customer where certain characters were stripped out automatically, causing them problems when attempting to log in for the first time (e.g. the customer thinks their Username is `john~doe`; when it is actually `johndoe` because WordPress (when running a Multisite Network) removes anything that is NOT `a-z0-9 _.-@` (and s2Member removes whitespace as well).
394
+
395
+ = v130406 =
396
+
397
+ * (s2Member/s2Member Pro) **Multisite Networks (#145)** Bug fix on Multisite Networks related to User deletions and subsequent logins on child blogs. For further details, please see [this thread](http://www.s2member.com/forums/topic/deleted-users-can-log-in/#post-46738).
398
+ * (s2Member Pro) **New Feature (#59)** It is now possible to Edit a User in the Dashboard and check a box to have the User's password reset, and an email message sent automatically to the User/Member with a copy of the Username/Password. This requires s2Member® Pro.
399
+ * (s2Member Pro) **API Functions (#158)** New PayPal® Pro API Functions (`s2member_pro_paypal_rbp_for_user`, `s2member_pro_paypal_rbp_times_for_user`). These are for developers. For further details, please see [this article](http://www.s2member.com/codex/stable/s2member/api_functions/package-summary/) in the s2Member® Codex.
400
+ * (s2Member Pro) **API Functions (#158)** New PayPal® Pro (PayFlow® Edition) API Functions (`s2member_pro_payflow_rbp_for_user`, `s2member_pro_payflow_rbp_times_for_user`). These are for developers. For further details, please see [this article](http://www.s2member.com/codex/stable/s2member/api_functions/package-summary/) in the s2Member® Codex.
401
+
402
+ = v130404 =
403
+
404
+ * (s2Member Pro) **Compatibility (#108)** Updating s2Member® Pro's integration with Authorize.Net to allow charges up to `$99,999.00` (formerly `$10,000.00`).
405
+ * (s2Member/s2Member Pro) **User Searches (#91)** Updating `pre_user_query` filter to include `first_name/last_name` (instead of only the `display_name`).
406
+ * (s2Member/s2Member Pro) **bbPress Integration (#88)** Updating bbPress Role/Cap filter to exclude itself during bbPress deactivation. This was causing a loss of the `read` Capability inadvertently.
407
+ * (s2Member/s2Member Pro) **PayPal® 20% Rule (#100)** Removing mention of the PayPal® 20% rule/limitation in the inline documentation. We confirmed with PayPal this ridiculous rule no longer applies to PayPal Standard Buttons.
408
+ * (s2Member/s2Member Pro) **File Downloads (#73)** Fixed bug related to `%2F` in file download URLs leading to a `ccap` directory.
409
+ * (s2Member/s2Member Pro) **Debug Logging (#69)** Logging now disabled by default. New log recommendation/warning notices updated throughout all menu pages for s2Member®.
410
+ * (s2Member/s2Member Pro) **Debug Logging (#69)** Logging must now be disabled (and the logs directory must be non-existent or empty) for an s2Member® Security Badge to go green. There is only one way to bypass this security check. See KB Article: [s2Member® Security Badges](http://www.s2member.com/kb/security-badges/). Notices are displayed on activation of this version to warn site owners about this change.
411
+ * (s2Member/s2Member Pro) **JW Player (#121)** Adding CSS `class` attribute to all JW Player template files used in conjunction with the `s2Stream` shortcode. New CSS class name: `s2member-jwplayer-v6`.
412
+ * (s2Member/s2Member Pro) **JW Player (#121)** Adding support for percentage-based width/height values in `player_width="" player_height=""` attributes of an s2Stream shortcode that generates a JW Player. Example: `player_width="100%"`.
413
+
414
+ = v130221 =
415
+
416
+ * (s2Member/s2Member Pro) **Bug Fix (#41)** Custom Registration/Profile Fields with an ID that ended with `-[0-9]+` or `_[0-9]+` was failing JavaScript validation due to a parsing issue. Fixed in this release.
417
+ * (s2Member/s2Member Pro) **Bug Fix (#43)** A bug first introduced in the last release of s2Member® v130220 was preventing Administrative New User Notifications from being sent by s2Member®. Fixed in this release.
418
+
419
+ = v130220 =
420
+
421
+ * (s2Member Pro) **Feature Enhancement/User Exportation (#33)** Adding support for UTF-8 BOM in CSV User export files. Now a configurable option during User/Member Exportation.
422
+ * (s2Member/s2Member Pro) **Feature Enhancement/Emails (#21)** Adding additional Replacement Codes for New User Email Notifications (for both the User/Member Notification and also for the Administrator Notification). The following Replacement Codes are now possible: `%%role%%`, `%%label%%`, `%%level%%`, `%%ccaps%%`. Also adding four new Filters for developers. These include: `ws_plugin__s2member_welcome_email_sbj`, `ws_plugin__s2member_welcome_email_msg`, `ws_plugin__s2member_admin_new_user_email_sbj`, `ws_plugin__s2member_admin_new_user_email_msg`. See `Dashboard -› General Options -› Email Configuration` for further details.
423
+ * (s2Member/s2Member Pro) **Feature Enhancement/Emails (#30)** Adding support for PHP tags in the following emails: New User Notification, Administrative New User Notification, Signup Confirmation Email, Specific Post/Page Confirmation Email. See the relevant sections in your Dashboard for further details. Such as: `s2Member® -› General Options -› Email Configuration` and `s2Member® -› PayPal® Options -› Signup Confirmation Email`.
424
+ * (s2Member/s2Member Pro) **Feature Enhancement/Shortcodes (#23)** Adding support for the `lang=""` Attribute in PayPal Buttons, PayPal Pro Forms, and in Google Checkout Buttons. This is a bit different from the existing `lc=""` value. The `lc=""` value controls the interface at PayPal, while the `lang=""` value controls the language of the Standard and/or Express Checkout Button itself (with respect to s2Member®). For further details, please see: `Dashboard -› PayPal Buttons (or Pro Forms) -› Shortcode Attributes (Explained)`.
425
+ * (s2Member/s2Member Pro) **Bug Fix** Fixing bug in User Access Package. Now checking if `$cap_enabled` also is `TRUE`; just in case another plugin or hack file attempts to disable Custom Capabilities without removing them. Not likely, but we can support this easily with a quick update in this release. Note... this has no impact on s2Member's existing functionality. Custom Capabilities continue to work just as they always have.
426
+ * (s2Member/s2Member Pro) **Feature Enhancement/Logging** Adding new logger. Logs to file `reg-handler.log`. Includes all User/Member registrations handled by s2Member® (either directly or indirectly). Only if logging is enabled. For further details, please check your Dashboard here: `s2Member® -› Log Files (Debug)`.
427
+ * (s2Member/s2Member Pro) **Feature Enhancement/EOTs (#29)** Adding UI option for EOT Grace Time. For further details, please see: `Dashboard -› PayPal Options -› Automatic EOT Behavior`. Also adding a new Filter for developers: `ws_plugin__s2member_eot_grace_time`.
428
+ * (s2Member/s2Member Pro) **Feature Enhancement/EOTs** Adding UI option for EOT Custom Capability Removal. For further details, please see: `Dashboard -› PayPal Options -› Automatic EOT Behavior`. Also adding a new Filter for developers: `ws_plugin__s2member_remove_ccaps_during_eot_events`.
429
+ * (s2Member/s2Member Pro) **Feature Enhancement/s2Stream Shortcode (#32)** Adding additional support for JW Player™ Captions, Titles, Descriptions, and Media IDs (i.e. `player_title=""`, `player_description=""`, `player_mediaid=""`, `player_captions=""`). Please check the Shortcode Attributes tab in [this KB article](http://www.s2member.com/kb/jwplayer-s2stream-shortcodes/#using-s2stream-shortcodes) for further details.
430
+
431
+ = v130214 =
432
+
433
+ * **(Maintenance Release) Upgrade immediately.**
434
+ * (s2Member/s2Member Pro) **Log Viewer (#16)** Additional log file descriptions have been added to the Dashboard, along with some other UI enhancements in this section.
435
+ * (s2Member/s2Member Pro) **Bug Fix (#18)** Usernames consisting of all numeric values were not always being redirected to the Login Welcome Page upon logging in, even when s2Member® was configured to do so. Fixed in this release. Discussed in [this thread](http://www.s2member.com/forums/topic/subscribers-not-taken-to-welcome-page/page/2/#post-41663).
436
+ * (s2Member Pro) **Coupon Codes (#19)** Adding new Replacement Codes: `%%full_coupon_code%%`, `%%coupon_code%%` and `%%coupon_affiliate_id%%`. These are now available in all API Tracking Codes, in all Custom Return URLs for Pro Forms, and in most API Notifications.
437
+ * (s2Member Pro) **Coupon Codes (#19)** Deprecating the `%%affiliate_id%%` Replacement Code for tracking Affiliate Coupon Codes in favor of `%%coupon_affiliate_id%%`.
438
+ * (s2Member/s2Member Pro) **Last Login Time** Improving readability of Last Login Time in list of Users/Members.
439
+ * (s2Member/s2Member Pro) **Compatibility** Improving support for WordPress® v3.6-alpha with respect to `tabindex` values on `/wp-login.php`.
440
+ * (s2Member/s2Member Pro) **Compatibility** Bumping minimum WordPress® requirement from v3.2 up to v3.3. Starting with this release, s2Member® is no longer compatible with the much older WordPress® v3.2.
441
+
442
+ = v130213 =
443
+
444
+ * **(Maintenance Release) Upgrade immediately.**
445
+ * (s2Member Pro) **Compatibility (#13)** PayPal® Payments Pro, PayPal® Payments Pro (Payflow Edition), and Authorize.Net. s2Member® Pro now supports a recurring interval of Semi-Yearly (e.g. charges occur every six months). This has always been possible by manipulating Shortcode Attribues, but it's now officially supported by Pro Form Generators in your Dashboard — which come with s2Member® Pro.
446
+ * (s2Member Pro) **Compatibility (#13)** ClickBank® Recurring Products. ClickBank® has started allowing a Weekly recurring interval and stopped allowing Yearly. s2Member® has been updated in this release to support a Weekly recurring interval with ClickBank®; and to remove the Yearly option in the ClickBank® Button Generator.
447
+ * (s2Member Pro) **Compatibility (#13)** PayPal® Payments Pro (Payflow Edition). PayPal® Payments Pro (Payflow Edition) has started allowing a Daily recurring interval. s2Member® has been updated in this release to support a Daily recurring interval with PayPal® Payments Pro (Payflow Edition). Daily recurring intervals remain possible with PayPal® Pro accounts that do not include the additional Payflow API. This change simply adds official support for Daily recurring billing with PayPal® Payments Pro (Payflow Edition).
448
+ * (s2Member) **Debugging Assistance** Updating s2Member's PayPal® PDT/Auto-Return handler to better handle scenarios where a site owner is missing a PayPal® PDT Identity Token in their s2Member® configuration, or has incorrectly set the `custom=""` Shortcode Attribute in Payment Buttons generated with s2Member®. Administrative notices are now displayed in the Dashboard when/if this occurs and s2Member® can catch the issue during post-processing of a transaction.
449
+ * (s2Member/s2Member Pro) **General Code Cleanup** Removing all `/**/` markers in the s2Member® codebase. These were used in conjunction with PolyStyle® code formatting tools to preserve line breaks in the code. The WebSharks™ development team no longer uses PolyStyle®, making these obsolete now. Removed in this release to improve readability for developers.
450
+ * (s2Member/s2Member Pro) **General Code Cleanup** Removing all unnecessary uses of PHP's `eval()` function in s2Member's codebase. These were used to keep repetitive code all in a single line; part of a standard the WebSharks™ development team is now moving away from. Removed in this release to improve readability for developers; and to prevent unnecessary confusion.
451
+ * (s2Member/s2Member Pro) **Auto-EOT System** Updated s2Member's Auto-EOT System. s2Member® now leaves an additional note behind after a demotion, which references the Paid Subscr. Gateway and Paid Subscr. ID values before the demotion occurred. This way there is a better reference left behind after an automatic demotion occurs.
452
+ * (s2Member/s2Member Pro) **Searching Users** Updating search function in list of Users (i.e. `Dashboard -› Users -› [Search Box]`) to include the Administrative Notes field when searching for Users. This allows references to old Paid Subscr. IDs in the Administrative Notes field to be considered when searching Users/Members.
453
+ * (s2Member/s2Member Pro) **Last Login Time** Adding new User Option value (tracked by s2Member®). This option value tracks the last time each User/Member logged into your site. Ex: `get_user_option("s2member_last_login_time")`.
454
+ * (s2Member/s2Member Pro) **Last Login Time** Adding new User data column to list of Users in the Dashboard: `Last Login Time`.
455
+ * (s2Member/s2Member Pro) **Last Login Time** Adding new API Function: [`s2member_last_login_time()`](http://www.s2member.com/codex/stable/s2member/api_functions/package-summary/).
456
+ * (s2Member/s2Member Pro) **ezPHP** Updated all internal documentation references that pointed to Exec-PHP or the PHP Execution plugin as recommendations for developers that wish to integrate PHP tags into Posts/Pages/Widgets. These old references now point to the [ezPHP](http://www.s2member.com/kb/ezphp-plugin/) plugin by s2Member® Lead Developer: Jason Caldwell. s2Member® remains compatible with other PHP plugins, but we recommend [ezPHP](http://www.s2member.com/kb/ezphp-plugin/) for the best compatibility with both s2Member® and WordPress® itself.
457
+ * (s2Member/s2Member Pro) **Simple Shortcode Conditionals** Adding a [Simple Shortcode Conditionals](http://www.s2member.com/kb/simple-shortcode-conditionals/) section to `s2Member® -› Restriction Options` in the Dashboard. This way more site owners will be aware of this feature from the start.
458
+ * (s2Member/s2Member Pro) **Login/Registration Design** Login/Registration Design with s2Member® is now optional (e.g. this feature can be disabled now — if you prefer). See: `Dashboard -› s2Member® -› General Options -› Login/Registration Design`. This feature is enabled by default on all s2Member® installations.
459
+ * (s2Member/s2Member Pro) **Inline Documentation** Adding more links to KB articles throughout the Dashboard area.
460
+ * (s2Member/s2Member Pro) **Inline Documentation** Updating all spaced parenthesis like `( something... )` to remove the grammatical errors — by removing the extra spaces inside these brackets.
461
+ * (s2Member/s2Member Pro) **Inline Documentation** Removing all references to PriMoThemes and/or primothemes.com within the application itself. PriMoThemes is now s2Member® (as of Jan 2012 — it's been awhile; so time to remove these obviously).
462
+ * (s2Member/s2Member Pro) **Inline Documentation** Adding link to "more updates..." in the Dashboard, pointing to the s2Member® KB. Increasing number of recent KB udpates from 3 up to 5. These are visible from any s2Member® page in the Dashboard (top of the right-hand column).
463
+ * (s2Member/s2Member Pro) **Inline Documentation** Adding [s2Member® Pro](http://www.s2member.com/pro/) (a recommended upgrade) to the Quick-Start Guide for s2Member® — in the Dashboard.
464
+ * (s2Member/s2Member Pro) **Inline Documentation** Adding Troubleshooting section to the Quick-Start Guide for s2Member® — in the Dashboard.
465
+ * (s2Member/s2Member Pro) **Inline Documentation** Adding Perfect Theme section to the Quick-Start Guide for s2Member® — in the Dashboard.
466
+ * (s2Member/s2Member Pro) **Inline Documentation** Adding video tutorial to the `Dashboard -› s2Member® -› API / Scripting -› Custom Capabilities` section.
467
+ * (s2Member/s2Member Pro) **Logging Functionality** Adding an s2Member® Log Viewer to the Dashboard for all site owners; and also for s2Member® Support Reps to use when running diagnostics. See: `Dashboard -› s2Member® -› Log Files (Debug)` for further details.
468
+ * (s2Member/s2Member Pro) **Logging Functionality** Logging routines are now enabled by default on all new installations of s2Member®. Existing installations of s2Member® are advised to enable logging, by visiting this section of your Dashboard. See: `s2Member® -› PayPal® Options (or Authorize.Net, ClickBank, etc) -› Account Details -› Logging`.
469
+ * (s2Member/s2Member Pro) **Logging Functionality** Additional logging routines that will track all s2Member® HTTP communication within WordPress® is now enabled by default. This new log file will be located inside `/wp-content/plugins/s2member-logs`. It is named: `s2-http-api-debug.log`. See: `Dashboard -› s2Member® -› Log Files (Debug)` for further details.
470
+ * (s2Member/s2Member Pro) **Logging Functionality** Additional logging routines that will track *all* HTTP communication within WordPress® are now possible (these are quite extensive). See: `Dashboard -› s2Member® -› Log Files (Debug) -› Logging Configuration` for further details. This more extensive logging is disabled by default; it must be enabled by a site owner. For debugging only — this should NEVER be enabled on a live site.
471
+ * (s2Member/s2Member Pro) **Logging Functionality** Adding date/time to all log entries maintained by s2Member®.
472
+ * (s2Member/s2Member Pro) **GZIP Conflicts** Adding additional lines of defense against GZIP conflicts during file downloads, with calls to `@apache_setenv("no-gzip", "1")` in other areas — not just during public file downloads (e.g. also during User/Member exporations, log file downloads, etc).
473
+ * (s2Member/s2Member Pro) **GZIP Conflicts** Adding an additional line of defense against GZIP conflicts during file downloads, with this line now appearing in the `.htaccess` file snippet added by the s2Member® software application: `RewriteCond %{QUERY_STRING} (^|\?|&)no-gzip\=1`.
474
+ * (s2Member/s2Member Pro) **GZIP Conflicts** Adding an additional line of defense against GZIP conflicts during User/Member exporations, log file downloads, and other downloads that come straight from the Dashboard area to site owners via web browsers. s2Member® now sends `Content-Encoding: none` to prevent Apache's `mod_deflate` from interfering with s2Member® under these special scenarios. A `Content-Encoding: none` header value is technically invalid, but it's known to prevent issues with `mod_deflate`. Since a `Content-Encoding: none` header value is technically invalid, s2Member® does NOT implement this during public file downloads; where we need to provide wider support for a long list of devices that may choke on this incorrect value. This is only implemented for site owners in the administrative areas of WordPress; and only for file downloads related to CSV export files and logs.
475
+ * (s2Member/s2Member Pro) **Bug Fix** Fixed incorrect `preg_split` limit against `$paypal['item_number']` in IPN handler for `subscr_payment` and `subscr_cancel` transaction types. Doesn't appear to have affected anything negatively, but it was wrong none the less. Fixed in this release.
476
+ * (s2Member/s2Member Pro) **Bug Fix** Fixed incorrect handling of a single opt-in checkbox on BuddyPress registration forms, which was not being wrapped with s2Member's BuddyPress container divs at all times. A symptom of this bug was to see a checkbox on your BuddyPress registration that was out of alignment or out of position. Fixed in this release.
477
+ * (s2Member/s2Member Pro) **Compatibility** Updated all of s2Member's IPN handlers to accept `$_REQUEST` data for Proxy-related variables like `s2member_paypal_proxy_return_url`. This allows s2Member® itself to use `$_POST` variables for Proxy-related variables; and it further reduces the likelihood of 403 Forbidden errors caused by [paranoid Mod Security configurations](http://www.s2member.com/kb/mod-security-random-503-403-errors/). One issue this should help to correct, is a mysterious case where a `success=""` Shortcode Attribute is not working as you might expect. This can be caused by [paranoid Mod Security configurations](http://www.s2member.com/kb/mod-security-random-503-403-errors/) at places like HostGator®, because a URL is passing through a query string. This release will help to prevent this from becoming a problem, because `success=""` URLs will be passed through `$_POST` variables now in all Pro Form integrations.
478
+
479
+ = v130207 =
480
+
481
+ * **(Maintenance Release) Upgrade immediately.**
482
+ * (s2Member Pro) **Bug Fix (#2)** Modification Tracking Codes not working properly under s2Member's Authorize.Net integration. Fixed in this release. Discussed in [this thread](http://www.s2member.com/forums/topic/shareasale-integration-not-working/#post-40954).
483
+ * (s2Member) **Compatibility (#4)** PayPal® integrated into a site charging in the JPY currency was incorrectly limited to an amount of 10000.00. Fixed in this release. Discussed in [this thread](http://www.s2member.com/forums/topic/default-currency-can-i-change-it-to-yen/#post-40590).
484
+ * (s2Member) **Compatibility (#5)** Incorrect `tabindex` values in WordPress® v3.5+. Fixed in this release. Discussed in [this thread](http://www.s2member.com/forums/topic/tabindex-messed-up-on-registration-page/#post-40591).
485
+ * (s2Member/s2Member Pro) **Line Breaks (#3)** Some line breaks in both s2Member® and s2Member® Pro were converted to CRLF inadvertently in the previous release. No real harm done, but this was causing some problems for the s2Member® Server Scanner because it uses a checksum against installation files; which was being thrown off balance due to the unexpected line break style. Fixed in this release. A symptom of this bug was to see invalid checksums when running diagnostics with the s2Member® Server Scanner.
486
+ * (s2Member/s2Member Pro) **Compatibility (#6)** s2Member® File Downloads (audio/video files) with spaces in a file name were not always being handled properly. Fixed in this release. Discussed in [this thread](http://www.s2member.com/forums/topic/jwplayer-filename-bug/#post-40799).
487
+
488
+ = v130203 =
489
+
490
+ * **(New Release) Please read this changelog for important details.**
491
+ * (s2Member Pro) **Remote Ops API (`create_user`)** s2Member® Pro's Remote Operations API, for the `create_user` Operation has been updated to support a new specification: `modify_if_login_exists`. For further details, please check your s2Member® Pro Dashboard here: `s2Member® -› API / Scripting -› Remote Operations API`.
492
+ * (s2Member Pro) **Remote Ops API (`modify_user`,`delete_user`)** s2Member® Pro's Remote Operations API has been updated to support two additional Operations: `update_user` and `delete_user`. For further details on these new Operations, please check your s2Member® Pro Dashboard here: `s2Member® -› API / Scripting -› Remote Operations API`.
493
+ * (s2Member Pro) **Remote Ops API (`init` hook priority)** s2Member® Pro's Remote Operations API has been updated to prevent conflicts when running in concert with BuddyPress v1.6.4+. Hook priority now running at default value of `11`, right after BuddyPress v1.6.4 at hook priority `10`.
494
+ * (s2Member/s2Member Pro) **s2Stream Shortcode (#88)** s2Member® now supports JW Player® license keys (for the professional edition) using Shortcode Attribute `player_key=""` (or they can be specified sitewide via JavaScript provided by Longtail Video — optional). See [this discussion](http://www.s2member.com/forums/topic/jwplayer-shortcode-for-poster-not-working/#post-40435). See also: [this KB article](http://www.s2member.com/kb/jwplayer-s2stream-shortcodes/#using-s2stream-shortcodes).
495
+ * (s2Member/s2Member Pro) **s2Stream Shortcode (#88)** Bug fix. The s2Stream Shortcode was not working properly (with respect to a specific Shortcode Attribute: `player_image=""`). Fixed in this release. See [this discussion](http://www.s2member.com/forums/topic/jwplayer-shortcode-for-poster-not-working/#post-40128). See also: [this KB article](http://www.s2member.com/kb/jwplayer-s2stream-shortcodes/#using-s2stream-shortcodes).
496
+ * (s2Member Pro) **User Exportation (#89)** s2Member® Pro's User Exportation now includes separate data columns for each Custom Registration/Profile Field that you've configured with s2Member®. Also, s2Member® Pro will now include ALL Custom Registration/Profile Fields (even if there is no value associated with certain Fields, for specific Users/Members — e.g. empty column values will now be included by s2Member® Pro). This provides a more consistent/readable CSV export file; a major improvement. Discussed in [this KB article](http://www.s2member.com/kb/importing-updating-users/#custom-registration-profile-fields).
497
+ * (s2Member Pro) **User Importation (#89)** s2Member® Pro's User/Member Import format changed in this release (with respect to Custom Registration/Profile Fields only). If you are importing Custom Registration/Profile Fields, please review [this KB article](http://www.s2member.com/kb/importing-updating-users/#custom-registration-profile-fields) before you import new Users/Members or mass update any existing Users/Members. ALSO NOTE: User/Member CSV Export Files generated by previous versions of s2Member® Pro (if they contained any Custom Registration/Profile Fields) will NOT be compatible with this latest release (e.g. you should NOT attempt to re-import those old files in an effort to mass update existing Users/Members). Please generate a new User/Member CSV Export File in the latest release of s2Member® Pro before attempting to edit and/or mass update existing Users/Members with applications like MS Excel or OpenOffice.
498
+
499
+ = v130123 =
500
+
501
+ * **(Maintenance Release) Upgrade immediately.**
502
+ * (s2Member/s2Member Pro) **s2Stream Shortcode (#78)** s2Member® now supports JW Player® license keys using Shortcode Attribute `player_key=""`. See [this KB article](http://www.s2member.com/kb/jwplayer-s2stream-shortcodes/) please. Also discussed in [this thread](http://www.s2member.com/forums/topic/new-jw-player-6-s2-video-audio-shortcodes/#post-38768).
503
+ * (s2Member/s2Member Pro) **s2Stream Shortcode (#79)** s2Member® now supports JW Player® [Advanced Option Blocks](http://www.longtailvideo.com/support/jw-player/28839/embedding-the-player) using Shortcode Attribute `player_option_blocks=""`. Example: `player_option_blocks="sharing:{}"`. See [this KB article](http://www.s2member.com/kb/jwplayer-s2stream-shortcodes/) please. Also discussed in [this thread](http://www.s2member.com/forums/topic/new-jw-player-6-s2-video-audio-shortcodes/#post-38768).
504
+ * (s2Member Pro) **User Exportation (#80)** s2Member® Pro User Exportation now occurs with MySQL `ORDER BY ID`, instead of no `ORDER BY` at all. This helps to prevent confusion and buggy behavior. Discussed in [this thread](http://www.s2member.com/forums/topic/user-export-not-working-properly/#post-39123).
505
+ * (s2Member Pro) **User Exportation (#81)** s2Member Pro's User Exportation now supports the exporation of up to `1000` User/Member table rows at once. Of course it remains possible to export ALL of your Users/Members with s2Member® Pro. All we've done here is bump the default limit from `250` up to `1000` at a time. In addition, there is a new Filter making it possible to extend this limit further on servers that can handle it. Use Filter: `ws_plugin__s2member_pro_export_users_limit` if you would like to export more Users all at once. See also: `Dashboard -› s2Member® Pro -› User/Member Exportation`.
506
+ * (s2Member/s2Member Pro) **KB Articles** Inline documentation updated in some areas, with a few links pointing to helpful/related KB articles.
507
+
508
+ = v130121 =
509
+
510
+ * **(Maintenance Release) Upgrade immediately.**
511
+ * **New Feature** s2Member® now comes with a new Shortcode `[s2Stream file_download="video.mp4" player="jwplayer-v6" ... /]`, making it MUCH easier for site owners to implemement RTMP streams of audio/video content. For further details, please check your Dashboard under: `s2Member® -› Download Options -› JW Player® v6 and RTMP Protocol Examples`. See also: `s2Member® -› Download Options -› Shortcode Attributes (Explained)`.
512
+ * **Compatibility (#75)** Updated s2Member's local file storage engine (for File Downloads via s2Member®), to support special characters in file names. Discussed in [this thread](http://www.s2member.com/forums/topic/problem-with-quotes-in-filename-downloads/#post-38395).
513
+ * **Bug Fix (#71)** A bug first introduced in the previous release of v130116, where we added support for byte-range requests to s2Member's File Download functionality, was causing multiple byte-range requests (processed by s2Member) to count against each User/Member as multiple File Downloads. Fixed in this release.
514
+ * **Compatibility** Updated s2Member's integration with Amazon® S3 to extend the default 30 second connection timeout (which was too conservative for many integrations) up to 24 hours by default, making it match the same as s2Member's Amazon® CloudFront connection timeout. For further details, please check your Dashboard under: `s2Member® -› Download Options -› Amazon® S3/CDN Storage -› Dev Note w/Technical Details`. It is possible to modify this connection timeout through a Filter discussed there.
515
+
516
+ = v130116 =
517
+
518
+ * **(Maintenance Release) Upgrade immediately.**
519
+ * **Compatibility (#39)** Updated codes samples for JW Player®, to include the `mp4:` prefix when implementing RTMP streams against MP4 video files. Discussed in [this thread](http://www.s2member.com/forums/topic/cloudfront-subfolder-streaming-error/#post-35750).
520
+ * **Compatibility (#51)** Updated Payflow® API to support recurring billing every six months. Discussed in [this thread](http://www.s2member.com/forums/topic/payflow-error-6-month-recurring-membership/#post-36053).
521
+ * **Bug Fix (#69)** Updated multisite user imporation routine, to support a specific scenario not covered under WordPress v3.5. Discussed in [this thread](http://www.s2member.com/forums/topic/users-on-multisite/).
522
+ * **Feature Improvement (#71)** s2Member® has been updated to support byte-range requests with it's default local file storage engine, served from the `/s2member-files/` directory. s2Member® has always supported byte-range requests when integrated with Amazon® CloudFront. Now it supports byte-range requests in it's default local storage engine too. This will improve compatibility with mobile devices, iTunes™ and other devices that use byte-range requests. Discussed in [this thread](http://www.s2member.com/forums/topic/any-way-to-set-accept-ranges-for-downloads/#post-15871).
523
+
524
+ = v121213 =
525
+
526
+ * ... trimmed away at v121213.
527
+ * Initial release: v1.0.
checksum.txt CHANGED
@@ -1 +1 @@
1
- 880cf4b36bfab2c644bde04a14c3be1d
1
+ a1daeda86ea085763a0951505fad6b5f
includes/classes/access-cap-times.inc.php CHANGED
@@ -27,6 +27,10 @@ if(!class_exists('c_ws_plugin__s2member_access_cap_times'))
27
  */
28
  class c_ws_plugin__s2member_access_cap_times
29
  {
 
 
 
 
30
 
31
  /**
32
  * @var array Previous array of user CAPS.
@@ -130,16 +134,18 @@ if(!class_exists('c_ws_plugin__s2member_access_cap_times'))
130
 
131
  $ac_times = get_user_option('s2member_access_cap_times', $user_id);
132
  if(!is_array($ac_times)) $ac_times = array();
133
- $time = (float)time();
 
 
134
 
135
  foreach($caps['prev'] as $_cap => $_was_enabled)
136
  if($_was_enabled && empty($caps['now'][$_cap]))
137
- $ac_times[number_format(($time += .0001), 4, '.', '')] = '-'.$_cap;
138
  unset($_cap, $_was_enabled);
139
 
140
  foreach($caps['now'] as $_cap => $_now_enabled)
141
  if($_now_enabled && empty($caps['prev'][$_cap]))
142
- $ac_times[number_format(($time += .0001), 4, '.', '')] = $_cap;
143
  unset($_cap, $_now_enabled);
144
 
145
  update_user_option($user_id, 's2member_access_cap_times', $ac_times);
27
  */
28
  class c_ws_plugin__s2member_access_cap_times
29
  {
30
+ /**
31
+ * @var string Current log time increment.
32
+ */
33
+ protected static $log_time = NULL;
34
 
35
  /**
36
  * @var array Previous array of user CAPS.
134
 
135
  $ac_times = get_user_option('s2member_access_cap_times', $user_id);
136
  if(!is_array($ac_times)) $ac_times = array();
137
+
138
+ if(!isset(self::$log_time))
139
+ self::$log_time = (float)time();
140
 
141
  foreach($caps['prev'] as $_cap => $_was_enabled)
142
  if($_was_enabled && empty($caps['now'][$_cap]))
143
+ $ac_times[number_format((self::$log_time += .0001), 4, '.', '')] = '-'.$_cap;
144
  unset($_cap, $_was_enabled);
145
 
146
  foreach($caps['now'] as $_cap => $_now_enabled)
147
  if($_now_enabled && empty($caps['prev'][$_cap]))
148
+ $ac_times[number_format((self::$log_time += .0001), 4, '.', '')] = $_cap;
149
  unset($_cap, $_now_enabled);
150
 
151
  update_user_option($user_id, 's2member_access_cap_times', $ac_times);
includes/classes/auto-eots.inc.php CHANGED
@@ -95,7 +95,7 @@ if (!class_exists ("c_ws_plugin__s2member_auto_eots"))
95
  * Can also be Filtered with `ws_plugin__s2member_auto_eot_system_per_process`.
96
  * @return null
97
  */
98
- public static function auto_eot_system ($per_process = 3)
99
  {
100
  global /* Need global DB obj. */ $wpdb;
101
  global /* Multisite. */ $current_site, $current_blog;
95
  * Can also be Filtered with `ws_plugin__s2member_auto_eot_system_per_process`.
96
  * @return null
97
  */
98
+ public static function auto_eot_system ($per_process = 6)
99
  {
100
  global /* Need global DB obj. */ $wpdb;
101
  global /* Multisite. */ $current_site, $current_blog;
includes/classes/custom-reg-fields.inc.php CHANGED
@@ -790,5 +790,52 @@ if(!class_exists("c_ws_plugin__s2member_custom_reg_fields"))
790
 
791
  return apply_filters('c_ws_plugin__s2member_custom_reg_field_validation_errors', $errors, get_defined_vars());
792
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
793
  }
794
  }
790
 
791
  return apply_filters('c_ws_plugin__s2member_custom_reg_field_validation_errors', $errors, get_defined_vars());
792
  }
793
+
794
+ /**
795
+ * Adds filters to `get_user_option` for Custom Field mapping
796
+ */
797
+ public static function add_filters_get_user_option()
798
+ {
799
+ if(!($fields = json_decode($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["custom_reg_fields"], TRUE)))
800
+ return; // Nothing to do in this case.
801
+
802
+ foreach($fields as $_field => $_config)
803
+ {
804
+ add_filter('get_user_option_' . $_field, 'c_ws_plugin__s2member_custom_reg_fields::do_filter_get_user_option', 20, 3);
805
+ add_filter('get_user_option_s2_' . $_field, 'c_ws_plugin__s2member_custom_reg_fields::do_filter_get_user_option', 20, 3);
806
+ }
807
+ unset($_field, $_config); // Housekeeping.
808
+ }
809
+
810
+ /**
811
+ * Filter for `get_user_option` queries. For Custom Field mapping.
812
+ *
813
+ * @param bool|string $what_wp_says The current field value, if WordPress has found one. Otherwise, FALSE.
814
+ * @param string $option_name Field slug/name being queried
815
+ * @param WP_User $user WP_User object related to the `get_user_option` query
816
+ *
817
+ * @return mixed
818
+ */
819
+ public static function do_filter_get_user_option($what_wp_says, $option_name, $user)
820
+ {
821
+ if($what_wp_says !== FALSE)
822
+ return $what_wp_says;
823
+
824
+ if(!($user instanceof WP_User) || !$user->exists())
825
+ return $what_wp_says;
826
+
827
+ if(!($user_fields = get_user_option("s2member_custom_fields", $user->ID)))
828
+ return $what_wp_says;
829
+
830
+ if(isset($user_fields[$option_name]))
831
+ return $user_fields[$option_name];
832
+
833
+ if(stripos($option_name, 's2_') === 0)
834
+ if(($real_name = preg_replace('/^s2_/i', '', $option_name)))
835
+ if(isset($user_fields[$real_name]))
836
+ return $user_fields[$real_name];
837
+
838
+ return $what_wp_says;
839
+ }
840
  }
841
  }
includes/classes/files-in.inc.php CHANGED
@@ -215,7 +215,7 @@ if(!class_exists('c_ws_plugin__s2member_files_in'))
215
  {
216
  $user_previous_file_downloads++; // Previous files always count against this User/Member.
217
 
218
- $_user_file_download_access_log_entry = & $user_file_download_access_log[$user_file_download_access_log_entry_key];
219
  $_user_already_downloaded_this_file = $_user_already_downloaded_a_streaming_variation_of_this_file = FALSE;
220
 
221
  if($user_file_download_access_log_entry['file'] === $req['file_download']) // Already downloaded this file? If yes, mark this flag as true.
@@ -475,7 +475,7 @@ if(!class_exists('c_ws_plugin__s2member_files_in'))
475
 
476
  $chunk_size = apply_filters('ws_plugin__s2member_file_downloads_chunk_size', 2097152, get_defined_vars());
477
 
478
- while($_bytes_to_read) // While we have bytes to read here.
479
  {
480
  $_bytes_to_read -= ($_reading = ($_bytes_to_read > $chunk_size) ? $chunk_size : $_bytes_to_read);
481
  echo fread($resource, $_reading); // Serve file in chunks (default chunk size is 2MB).
215
  {
216
  $user_previous_file_downloads++; // Previous files always count against this User/Member.
217
 
218
+ $_user_file_download_access_log_entry = &$user_file_download_access_log[$user_file_download_access_log_entry_key];
219
  $_user_already_downloaded_this_file = $_user_already_downloaded_a_streaming_variation_of_this_file = FALSE;
220
 
221
  if($user_file_download_access_log_entry['file'] === $req['file_download']) // Already downloaded this file? If yes, mark this flag as true.
475
 
476
  $chunk_size = apply_filters('ws_plugin__s2member_file_downloads_chunk_size', 2097152, get_defined_vars());
477
 
478
+ while($_bytes_to_read > 0) // While we have bytes to read here.
479
  {
480
  $_bytes_to_read -= ($_reading = ($_bytes_to_read > $chunk_size) ? $chunk_size : $_bytes_to_read);
481
  echo fread($resource, $_reading); // Serve file in chunks (default chunk size is 2MB).
includes/classes/login-customizations.inc.php CHANGED
@@ -99,7 +99,7 @@ if(!class_exists('c_ws_plugin__s2member_login_customizations'))
99
  $i = apply_filters('ws_plugin__s2member_login_header_styles_important', ' !important', get_defined_vars());
100
  $a = apply_filters('ws_plugin__s2member_login_header_styles_array_after_open', $a, get_defined_vars());
101
 
102
- $a[] = 'html, body { border:0'.$i.'; padding: 10px; background:none'.$i.'; }';
103
  $a[] = 'html { background-color:#'.$GLOBALS['WS_PLUGIN__']['s2member']['o']['login_reg_background_color'].$i.'; }';
104
  $a[] = 'html { background-image:url('.$GLOBALS['WS_PLUGIN__']['s2member']['o']['login_reg_background_image'].')'.$i.'; }';
105
  $a[] = 'html { background-repeat:'.$GLOBALS['WS_PLUGIN__']['s2member']['o']['login_reg_background_image_repeat'].$i.'; }';
99
  $i = apply_filters('ws_plugin__s2member_login_header_styles_important', ' !important', get_defined_vars());
100
  $a = apply_filters('ws_plugin__s2member_login_header_styles_array_after_open', $a, get_defined_vars());
101
 
102
+ $a[] = 'html, body { border:0'.$i.'; background:none'.$i.'; }';
103
  $a[] = 'html { background-color:#'.$GLOBALS['WS_PLUGIN__']['s2member']['o']['login_reg_background_color'].$i.'; }';
104
  $a[] = 'html { background-image:url('.$GLOBALS['WS_PLUGIN__']['s2member']['o']['login_reg_background_image'].')'.$i.'; }';
105
  $a[] = 'html { background-repeat:'.$GLOBALS['WS_PLUGIN__']['s2member']['o']['login_reg_background_image_repeat'].$i.'; }';
includes/classes/mailchimp.inc.php CHANGED
@@ -94,7 +94,7 @@ if(!class_exists('c_ws_plugin__s2member_mailchimp'))
94
 
95
  if(($_mc['interest_groups_title'] = trim($_mc['interest_groups_title'])))
96
  if(($_mc['interest_groups'] = $_mc['interest_groups'] ? preg_split('/\|/', trim($_mc['interest_groups']), NULL, PREG_SPLIT_NO_EMPTY) : array()))
97
- $_mc['interest_groups'] = array('GROUPINGS' => array(array('name' => $_mc['interest_groups_title'], 'groups' => implode(',', $_mc['interest_groups']))));
98
 
99
  if(!$_mc['list_id']) continue; // List ID is missing now; after parsing interest groups.
100
  }
@@ -175,7 +175,7 @@ if(!class_exists('c_ws_plugin__s2member_mailchimp'))
175
 
176
  if(($_mc['interest_groups_title'] = trim($_mc['interest_groups_title'])))
177
  if(($_mc['interest_groups'] = $_mc['interest_groups'] ? preg_split('/\|/', trim($_mc['interest_groups']), NULL, PREG_SPLIT_NO_EMPTY) : array()))
178
- $_mc['interest_groups'] = array('GROUPINGS' => array(array('name' => $_mc['interest_groups_title'], 'groups' => implode(',', $_mc['interest_groups']))));
179
 
180
  if(!$_mc['list_id']) continue; // List ID is missing now; after parsing interest groups.
181
  }
@@ -215,4 +215,4 @@ if(!class_exists('c_ws_plugin__s2member_mailchimp'))
215
  return self::unsubscribe($old_args) && self::subscribe($new_args);
216
  }
217
  }
218
- }
94
 
95
  if(($_mc['interest_groups_title'] = trim($_mc['interest_groups_title'])))
96
  if(($_mc['interest_groups'] = $_mc['interest_groups'] ? preg_split('/\|/', trim($_mc['interest_groups']), NULL, PREG_SPLIT_NO_EMPTY) : array()))
97
+ $_mc['interest_groups'] = array('GROUPINGS' => array(array('name' => $_mc['interest_groups_title'], 'groups' => $_mc['interest_groups'])));
98
 
99
  if(!$_mc['list_id']) continue; // List ID is missing now; after parsing interest groups.
100
  }
175
 
176
  if(($_mc['interest_groups_title'] = trim($_mc['interest_groups_title'])))
177
  if(($_mc['interest_groups'] = $_mc['interest_groups'] ? preg_split('/\|/', trim($_mc['interest_groups']), NULL, PREG_SPLIT_NO_EMPTY) : array()))
178
+ $_mc['interest_groups'] = array('GROUPINGS' => array(array('name' => $_mc['interest_groups_title'], 'groups' => $_mc['interest_groups'])));
179
 
180
  if(!$_mc['list_id']) continue; // List ID is missing now; after parsing interest groups.
181
  }
215
  return self::unsubscribe($old_args) && self::subscribe($new_args);
216
  }
217
  }
218
+ }
includes/classes/meta-boxes.inc.php CHANGED
@@ -49,7 +49,7 @@ if (!class_exists ("c_ws_plugin__s2member_meta_boxes"))
49
  $excluded_types = apply_filters("ws_plugin__s2member_add_meta_boxes_excluded_types", $excluded_types, get_defined_vars ());
50
 
51
  if (in_array($type, array_keys (get_post_types ())) && !in_array($type, $excluded_types))
52
- add_meta_box ("ws-plugin--s2member-security", "s2Member", "c_ws_plugin__s2member_meta_box_security::security_meta_box", $type, "side", "high");
53
 
54
  do_action("ws_plugin__s2member_after_add_meta_boxes", get_defined_vars ());
55
 
49
  $excluded_types = apply_filters("ws_plugin__s2member_add_meta_boxes_excluded_types", $excluded_types, get_defined_vars ());
50
 
51
  if (in_array($type, array_keys (get_post_types ())) && !in_array($type, $excluded_types))
52
+ add_meta_box ("ws-plugin--s2member-security", "s2Member", "c_ws_plugin__s2member_meta_box_security::security_meta_box", $type, "side", "high");
53
 
54
  do_action("ws_plugin__s2member_after_add_meta_boxes", get_defined_vars ());
55
 
includes/classes/mms-patches.inc.php CHANGED
@@ -79,7 +79,7 @@ if (!class_exists ("c_ws_plugin__s2member_mms_patches"))
79
  if (file_exists ($wp_login_file) && ($wp_login = file_get_contents ($wp_login_file)) && is_writable ($wp_login_file))
80
  {
81
  if ((($wp_login_written = file_put_contents ($wp_login_file, preg_replace ($wp_login_section, $wp_login_replace, $wp_login, 1, $wp_login_patched))) && $wp_login_patched) || ($wp_login_patched_already = $wp_login_patched = strpos ($wp_login, $wp_login_replace)))
82
- ($display_notices) ? c_ws_plugin__s2member_admin_notices::display_admin_notice ('Your <code>/wp-login.php</code> file ' . (($wp_login_patched_already) ? 'is patched' : 'has been patched successfully') . '.') : null;
83
  else if (!$wp_login_written) // Otherwise, we need to report that /wp-login.php could NOT be updated. Possibly a permissions error.
84
  ($display_notices) ? c_ws_plugin__s2member_admin_notices::display_admin_notice ('Your <code>/wp-login.php</code> file could NOT be patched. Patch NOT written.', true) : null;
85
  else if (!$wp_login_patched) // Otherwise, we need to report that /wp-login.php could NOT be updated. Wrong WordPress version?
@@ -95,7 +95,7 @@ if (!class_exists ("c_ws_plugin__s2member_mms_patches"))
95
  if (file_exists ($load_file) && ($load = file_get_contents ($load_file)) && is_writable ($load_file))
96
  {
97
  if ((($load_written = file_put_contents ($load_file, preg_replace ($load_section, $load_replace, $load, 1, $load_patched))) && $load_patched) || ($load_patched_already = $load_patched = strpos ($load, $load_replace)))
98
- ($display_notices) ? c_ws_plugin__s2member_admin_notices::display_admin_notice ('Your <code>/wp-includes/load.php</code> file ' . (($load_patched_already) ? 'is patched' : 'has been patched successfully') . '.') : null;
99
  else if (!$load_written) // Otherwise, we need to report that /wp-includes/load.php could NOT be updated. Possibly a permissions error.
100
  ($display_notices) ? c_ws_plugin__s2member_admin_notices::display_admin_notice ('Your <code>/wp-includes/load.php</code> file could NOT be patched. Patch NOT written.', true) : null;
101
  else if (!$load_patched) // Otherwise, we need to report that /wp-includes/load.php could NOT be updated. Wrong WordPress version?
@@ -105,13 +105,13 @@ if (!class_exists ("c_ws_plugin__s2member_mms_patches"))
105
  ($display_notices) ? c_ws_plugin__s2member_admin_notices::display_admin_notice ('Your <code>/wp-includes/load.php</code> file could NOT be patched. File NOT writable.', true) : null;
106
 
107
  $user_new_file = ABSPATH . "wp-admin/user-new.php";
108
- $user_new_section = "/([\r\n\t\s ]+)(wpmu_signup_user( *?)\(( *?)\\\$new_user_login,( *?)\\\$_REQUEST\[( *?)'email'( *?)\],( *?)array( *?)\(( *?)'add_to_blog'( *?)\=\>( *?)\\\$wpdb->blogid,( *?)'new_role'( *?)\=\>( *?)\\\$_REQUEST\[( *?)'role'( *?)\]( *?)\)( *?)\);)/";
109
  $user_new_replace = "\n\t\t\t// Modified for full plugin compatiblity.\n\t\t\t//wpmu_signup_user( \$new_user_login, \$_REQUEST[ 'email' ], array( 'add_to_blog' => \$wpdb->blogid, 'new_role' => \$_REQUEST[ 'role' ] ) );\n\t\t\twpmu_signup_user( \$new_user_login, \$_REQUEST[ 'email' ], apply_filters( 'add_signup_meta', array( 'add_to_blog' => \$wpdb->blogid, 'new_role' => \$_REQUEST[ 'role' ] ) ) );";
110
 
111
  if (file_exists ($user_new_file) && ($user_new = file_get_contents ($user_new_file)) && is_writable ($user_new_file))
112
  {
113
  if ((($user_new_written = file_put_contents ($user_new_file, preg_replace ($user_new_section, $user_new_replace, $user_new, 1, $user_new_patched))) && $user_new_patched) || ($user_new_patched_already = $user_new_patched = strpos ($user_new, $user_new_replace)))
114
- ($display_notices) ? c_ws_plugin__s2member_admin_notices::display_admin_notice ('Your <code>/wp-admin/user-new.php</code> file ' . (($user_new_patched_already) ? 'is patched' : 'has been patched successfully') . '.') : null;
115
  else if (!$user_new_written) // Otherwise, we need to report that /wp-admin/user-new.php could NOT be updated. Possibly a permissions error.
116
  ($display_notices) ? c_ws_plugin__s2member_admin_notices::display_admin_notice ('Your <code>/wp-admin/user-new.php</code> file could NOT be patched. Patch NOT written.', true) : null;
117
  else if (!$user_new_patched) // Otherwise, we need to report that /wp-admin/user-new.php could NOT be updated. Wrong WordPress version?
@@ -127,7 +127,7 @@ if (!class_exists ("c_ws_plugin__s2member_mms_patches"))
127
  if (file_exists ($ms_functions_file) && ($ms_functions = file_get_contents ($ms_functions_file)) && is_writable ($ms_functions_file))
128
  {
129
  if ((($ms_functions_written = file_put_contents ($ms_functions_file, preg_replace ($ms_functions_section, $ms_functions_replace, $ms_functions, 1, $ms_functions_patched))) && $ms_functions_patched) || ($ms_functions_patched_already = $ms_functions_patched = strpos ($ms_functions, $ms_functions_replace)))
130
- ($display_notices) ? c_ws_plugin__s2member_admin_notices::display_admin_notice ('Your <code>/wp-includes/ms-functions.php</code> file ' . (($ms_functions_patched_already) ? 'is patched' : 'has been patched successfully') . '.') : null;
131
  else if (!$ms_functions_written) // Otherwise, we need to report that /wp-includes/ms-functions.php could NOT be updated. Possibly a permissions error.
132
  ($display_notices) ? c_ws_plugin__s2member_admin_notices::display_admin_notice ('Your <code>/wp-includes/ms-functions.php</code> file could NOT be patched. Patch NOT written.', true) : null;
133
  else if (!$ms_functions_patched) // Otherwise, we need to report that /wp-includes/ms-functions.php could NOT be updated. Wrong WordPress version?
79
  if (file_exists ($wp_login_file) && ($wp_login = file_get_contents ($wp_login_file)) && is_writable ($wp_login_file))
80
  {
81
  if ((($wp_login_written = file_put_contents ($wp_login_file, preg_replace ($wp_login_section, $wp_login_replace, $wp_login, 1, $wp_login_patched))) && $wp_login_patched) || ($wp_login_patched_already = $wp_login_patched = strpos ($wp_login, $wp_login_replace)))
82
+ ($display_notices) ? c_ws_plugin__s2member_admin_notices::display_admin_notice ('Your <code>/wp-login.php</code> file ' . (!empty($wp_login_patched_already) ? 'is patched' : 'has been patched successfully') . '.') : null;
83
  else if (!$wp_login_written) // Otherwise, we need to report that /wp-login.php could NOT be updated. Possibly a permissions error.
84
  ($display_notices) ? c_ws_plugin__s2member_admin_notices::display_admin_notice ('Your <code>/wp-login.php</code> file could NOT be patched. Patch NOT written.', true) : null;
85
  else if (!$wp_login_patched) // Otherwise, we need to report that /wp-login.php could NOT be updated. Wrong WordPress version?
95
  if (file_exists ($load_file) && ($load = file_get_contents ($load_file)) && is_writable ($load_file))
96
  {
97
  if ((($load_written = file_put_contents ($load_file, preg_replace ($load_section, $load_replace, $load, 1, $load_patched))) && $load_patched) || ($load_patched_already = $load_patched = strpos ($load, $load_replace)))
98
+ ($display_notices) ? c_ws_plugin__s2member_admin_notices::display_admin_notice ('Your <code>/wp-includes/load.php</code> file ' . (!empty($load_patched_already) ? 'is patched' : 'has been patched successfully') . '.') : null;
99
  else if (!$load_written) // Otherwise, we need to report that /wp-includes/load.php could NOT be updated. Possibly a permissions error.
100
  ($display_notices) ? c_ws_plugin__s2member_admin_notices::display_admin_notice ('Your <code>/wp-includes/load.php</code> file could NOT be patched. Patch NOT written.', true) : null;
101
  else if (!$load_patched) // Otherwise, we need to report that /wp-includes/load.php could NOT be updated. Wrong WordPress version?
105
  ($display_notices) ? c_ws_plugin__s2member_admin_notices::display_admin_notice ('Your <code>/wp-includes/load.php</code> file could NOT be patched. File NOT writable.', true) : null;
106
 
107
  $user_new_file = ABSPATH . "wp-admin/user-new.php";
108
+ $user_new_section = "/([\r\n\t\s ]+)(wpmu_signup_user( *?)\(( *?)\\\$new_user_login,( *?)(?:\\\$new_user_email|\\\$_REQUEST\[( *?)'email'( *?)\]),( *?)array( *?)\(( *?)'add_to_blog'( *?)\=\>( *?)\\\$wpdb->blogid,( *?)'new_role'( *?)\=\>( *?)\\\$_REQUEST\[( *?)'role'( *?)\]( *?)\)( *?)\);)/";
109
  $user_new_replace = "\n\t\t\t// Modified for full plugin compatiblity.\n\t\t\t//wpmu_signup_user( \$new_user_login, \$_REQUEST[ 'email' ], array( 'add_to_blog' => \$wpdb->blogid, 'new_role' => \$_REQUEST[ 'role' ] ) );\n\t\t\twpmu_signup_user( \$new_user_login, \$_REQUEST[ 'email' ], apply_filters( 'add_signup_meta', array( 'add_to_blog' => \$wpdb->blogid, 'new_role' => \$_REQUEST[ 'role' ] ) ) );";
110
 
111
  if (file_exists ($user_new_file) && ($user_new = file_get_contents ($user_new_file)) && is_writable ($user_new_file))
112
  {
113
  if ((($user_new_written = file_put_contents ($user_new_file, preg_replace ($user_new_section, $user_new_replace, $user_new, 1, $user_new_patched))) && $user_new_patched) || ($user_new_patched_already = $user_new_patched = strpos ($user_new, $user_new_replace)))
114
+ ($display_notices) ? c_ws_plugin__s2member_admin_notices::display_admin_notice ('Your <code>/wp-admin/user-new.php</code> file ' . (!empty($user_new_patched_already) ? 'is patched' : 'has been patched successfully') . '.') : null;
115
  else if (!$user_new_written) // Otherwise, we need to report that /wp-admin/user-new.php could NOT be updated. Possibly a permissions error.
116
  ($display_notices) ? c_ws_plugin__s2member_admin_notices::display_admin_notice ('Your <code>/wp-admin/user-new.php</code> file could NOT be patched. Patch NOT written.', true) : null;
117
  else if (!$user_new_patched) // Otherwise, we need to report that /wp-admin/user-new.php could NOT be updated. Wrong WordPress version?
127
  if (file_exists ($ms_functions_file) && ($ms_functions = file_get_contents ($ms_functions_file)) && is_writable ($ms_functions_file))
128
  {
129
  if ((($ms_functions_written = file_put_contents ($ms_functions_file, preg_replace ($ms_functions_section, $ms_functions_replace, $ms_functions, 1, $ms_functions_patched))) && $ms_functions_patched) || ($ms_functions_patched_already = $ms_functions_patched = strpos ($ms_functions, $ms_functions_replace)))
130
+ ($display_notices) ? c_ws_plugin__s2member_admin_notices::display_admin_notice ('Your <code>/wp-includes/ms-functions.php</code> file ' . (!empty($ms_functions_patched_already) ? 'is patched' : 'has been patched successfully') . '.') : null;
131
  else if (!$ms_functions_written) // Otherwise, we need to report that /wp-includes/ms-functions.php could NOT be updated. Possibly a permissions error.
132
  ($display_notices) ? c_ws_plugin__s2member_admin_notices::display_admin_notice ('Your <code>/wp-includes/ms-functions.php</code> file could NOT be patched. Patch NOT written.', true) : null;
133
  else if (!$ms_functions_patched) // Otherwise, we need to report that /wp-includes/ms-functions.php could NOT be updated. Wrong WordPress version?
includes/classes/paypal-notify-in-merch-pmt.inc.php DELETED
@@ -1,77 +0,0 @@
1
- <?php
2
- /**
3
- * s2Member's PayPal IPN handler (inner processing routine).
4
- *
5
- * Copyright: © 2009-2011
6
- * {@link http://www.websharks-inc.com/ WebSharks, Inc.}
7
- * (coded in the USA)
8
- *
9
- * Released under the terms of the GNU General Public License.
10
- * You should have received a copy of the GNU General Public License,
11
- * along with this software. In the main directory, see: /licensing/
12
- * If not, see: {@link http://www.gnu.org/licenses/}.
13
- *
14
- * @package s2Member\PayPal
15
- * @since 140326
16
- */
17
- if (realpath (__FILE__) === realpath ($_SERVER["SCRIPT_FILENAME"]))
18
- exit("Do not access this file directly.");
19
-
20
- if (!class_exists ("c_ws_plugin__s2member_paypal_notify_in_merch_pmt"))
21
- {
22
- /**
23
- * s2Member's PayPal IPN handler (inner processing routine).
24
- *
25
- * @package s2Member\PayPal
26
- * @since 140326
27
- */
28
- class c_ws_plugin__s2member_paypal_notify_in_merch_pmt
29
- {
30
- /**
31
- * s2Member's PayPal IPN handler (inner processing routine).
32
- *
33
- * @package s2Member\PayPal
34
- * @since 140326
35
- *
36
- * @param array $vars Required. An array of defined variables passed by {@link s2Member\PayPal\c_ws_plugin__s2member_paypal_notify_in::paypal_notify()}.
37
- * @return array|bool The original ``$paypal`` array passed in (extracted) from ``$vars``, or false when conditions do NOT apply.
38
- */
39
- public static function cp ($vars = array()) // Conditional phase for ``c_ws_plugin__s2member_paypal_notify_in::paypal_notify()``.
40
- {
41
- extract($vars, EXTR_OVERWRITE | EXTR_REFS); // Extract all vars passed in from: ``c_ws_plugin__s2member_paypal_notify_in::paypal_notify()``.
42
-
43
- if (!empty($paypal["txn_type"]) && preg_match ("/^merch_pmt$/i", $paypal["txn_type"]))
44
- {
45
- foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;
46
- do_action("ws_plugin__s2member_during_paypal_notify_before_merch_pmt", get_defined_vars ());
47
- unset($__refs, $__v);
48
-
49
- if (!get_transient ($transient_ipn = "s2m_ipn_" . md5 ("s2member_transient_" . $_paypal_s)) && set_transient ($transient_ipn, time (), 31556926 * 10))
50
- {
51
- $paypal["s2member_log"][] = "s2Member `txn_type` identified as ( `merch_pmt` ).";
52
-
53
- $processing = $during = true; // Yes, we ARE processing this.
54
-
55
- $paypal["s2member_log"][] = "The `txn_type` does not require any action on the part of s2Member.";
56
- $paypal["s2member_log"][] = "s2Member Pro handles Merch Pmts on-site, with an IPN proxy.";
57
-
58
- foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;
59
- do_action("ws_plugin__s2member_during_paypal_notify_during_merch_pmt", get_defined_vars ());
60
- unset($__refs, $__v);
61
- }
62
- else // Else, this is a duplicate IPN. Must stop here.
63
- {
64
- $paypal["s2member_log"][] = "Not processing. Duplicate IPN.";
65
- $paypal["s2member_log"][] = "s2Member `txn_type` identified as ( `merch_pmt` ).";
66
- $paypal["s2member_log"][] = "Duplicate IPN. Already processed. This IPN will be ignored.";
67
- }
68
- foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;
69
- do_action("ws_plugin__s2member_during_paypal_notify_after_merch_pmt", get_defined_vars ());
70
- unset($__refs, $__v);
71
-
72
- return apply_filters("c_ws_plugin__s2member_paypal_notify_in_merch_pmt", $paypal, get_defined_vars ());
73
- }
74
- else return apply_filters("c_ws_plugin__s2member_paypal_notify_in_merch_pmt", false, get_defined_vars ());
75
- }
76
- }
77
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
includes/classes/paypal-notify-in-sp-refund-reversal.inc.php CHANGED
@@ -1,150 +1,159 @@
1
  <?php
2
  /**
3
- * s2Member's PayPal IPN handler (inner processing routine).
4
- *
5
- * Copyright: © 2009-2011
6
- * {@link http://www.websharks-inc.com/ WebSharks, Inc.}
7
- * (coded in the USA)
8
- *
9
- * Released under the terms of the GNU General Public License.
10
- * You should have received a copy of the GNU General Public License,
11
- * along with this software. In the main directory, see: /licensing/
12
- * If not, see: {@link http://www.gnu.org/licenses/}.
13
- *
14
- * @package s2Member\PayPal
15
- * @since 110720
16
- */
17
- if (realpath (__FILE__) === realpath ($_SERVER["SCRIPT_FILENAME"]))
18
- exit ("Do not access this file directly.");
19
-
20
- if (!class_exists ("c_ws_plugin__s2member_paypal_notify_in_sp_refund_reversal"))
 
 
 
 
 
 
 
 
21
  {
22
  /**
23
- * s2Member's PayPal IPN handler (inner processing routine).
24
- *
25
- * @package s2Member\PayPal
26
- * @since 110720
27
- */
28
- class c_ws_plugin__s2member_paypal_notify_in_sp_refund_reversal
 
 
 
 
 
 
 
 
 
 
 
 
 
 
29
  {
30
- /**
31
- * s2Member's PayPal IPN handler (inner processing routine).
32
- *
33
- * @package s2Member\PayPal
34
- * @since 110720
35
- *
36
- * @param array $vars Required. An array of defined variables passed by {@link s2Member\PayPal\c_ws_plugin__s2member_paypal_notify_in::paypal_notify()}.
37
- * @return array|bool The original ``$paypal`` array passed in (extracted) from ``$vars``, or false when conditions do NOT apply.
38
- */
39
- public static function cp ($vars = array()) // Conditional phase for ``c_ws_plugin__s2member_paypal_notify_in::paypal_notify()``.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
40
  {
41
- extract ($vars, EXTR_OVERWRITE | EXTR_REFS); // Extract all vars passed in from: ``c_ws_plugin__s2member_paypal_notify_in::paypal_notify()``.
42
-
43
- if (((!empty($paypal["txn_type"]) && preg_match ("/^new_case$/i", $paypal["txn_type"]) && !empty($paypal["case_type"]) && preg_match ("/^chargeback$/i", $paypal["case_type"]))
44
- || (!empty($paypal["payment_status"]) && preg_match ("/^(refunded|reversed|reversal)$/i", $paypal["payment_status"])) /* The "txn_type" is irrelevant in these special situations. */)
45
- && ((!empty($paypal["item_number"]) || ($paypal["item_number"] = c_ws_plugin__s2member_paypal_utilities::paypal_pro_item_number ($paypal))) && preg_match ($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["sp_access_item_number_regex"], $paypal["item_number"]))
46
- && (!empty($paypal["item_name"]) || ($paypal["item_name"] = c_ws_plugin__s2member_paypal_utilities::paypal_pro_item_name ($paypal)) || ($paypal["item_name"] = $_SERVER["HTTP_HOST"]))
47
- && (!empty($paypal["payer_email"])) && (!empty($paypal["parent_txn_id"])) && (!empty($paypal["parent_txn_baid"]) || ($paypal["parent_txn_baid"] = $paypal["parent_txn_id"]))
48
- && (!empty($paypal["parent_txn_cid"]) || ($paypal["parent_txn_cid"] = $paypal["parent_txn_id"])))
49
- {
50
- foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;
51
- do_action("ws_plugin__s2member_during_paypal_notify_before_sp_refund_reversal", get_defined_vars ());
52
- unset($__refs, $__v);
53
-
54
- if (!get_transient ($transient_ipn = "s2m_ipn_" . md5 ("s2member_transient_" . $_paypal_s)) && set_transient ($transient_ipn, time (), 31556926 * 10))
55
- {
56
- $paypal["s2member_log"][] = "s2Member `txn_type` identified as ( `[empty or irrelevant]` ) w/ `payment_status` ( `refunded|reversed|reversal` ) - or - `new_case` w/ `case_type` ( `chargeback` ).";
57
-
58
- $paypal["ip"] = (preg_match ("/ip address/i", $paypal["option_name2"]) && $paypal["option_selection2"]) ? $paypal["option_selection2"] : "";
59
- $paypal["ip"] = (!$paypal["ip"] && preg_match ("/^[a-z0-9]+~[0-9\.]+$/i", $paypal["invoice"])) ? preg_replace ("/^[a-z0-9]+~/i", "", $paypal["invoice"]) : $paypal["ip"];
60
-
61
- $processing = $during = true; // Yes, we ARE processing this.
62
- /*
63
- Refunds and chargeback reversals. This is excluded from the processing check.
64
- In other words, s2Member sends `Refund/Reversal` Notifications ANYTIME a Refund/Reversal occurs; even if s2Member did not process it otherwise.
65
- Since this routine ignores the processing check, it is *possible* that Refund/Reversal Notification URLs will be contacted more than once.
66
- If you're writing scripts that depend on Refund/Reversal Notifications, please keep this in mind.
67
- */
68
- if ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["sp_ref_rev_notification_urls"] && is_array($cv = preg_split ("/\|/", $paypal["custom"])))
69
- {
70
- foreach (preg_split ("/[\r\n\t]+/", $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["sp_ref_rev_notification_urls"]) as $url)
71
-
72
- if (($url = preg_replace ("/%%cv([0-9]+)%%/ei", 'urlencode(trim(@$cv[$1]))', $url)) && ($url = preg_replace ("/%%parent_txn_id%%/i", c_ws_plugin__s2member_utils_strings::esc_refs (urlencode ($paypal["parent_txn_id"])), $url)))
73
- if (($url = preg_replace ("/%%parent_txn_baid%%/i", c_ws_plugin__s2member_utils_strings::esc_refs (urlencode ($paypal["parent_txn_baid"])), $url)) && ($url = preg_replace ("/%%parent_txn_cid%%/i", c_ws_plugin__s2member_utils_strings::esc_refs (urlencode ($paypal["parent_txn_cid"])), $url)))
74
- if (($url = preg_replace ("/%%item_number%%/i", c_ws_plugin__s2member_utils_strings::esc_refs (urlencode ($paypal["item_number"])), $url)) && ($url = preg_replace ("/%%item_name%%/i", c_ws_plugin__s2member_utils_strings::esc_refs (urlencode ($paypal["item_name"])), $url)))
75
- if (($url = preg_replace ("/%%-amount%%/i", c_ws_plugin__s2member_utils_strings::esc_refs (urlencode ($paypal["mc_gross"])), $url)) && ($url = preg_replace ("/%%-fee%%/i", c_ws_plugin__s2member_utils_strings::esc_refs (urlencode ($paypal["mc_fee"])), $url)))
76
- if (($url = preg_replace ("/%%first_name%%/i", c_ws_plugin__s2member_utils_strings::esc_refs (urlencode ($paypal["first_name"])), $url)) && ($url = preg_replace ("/%%last_name%%/i", c_ws_plugin__s2member_utils_strings::esc_refs (urlencode ($paypal["last_name"])), $url)))
77
- if (($url = preg_replace ("/%%full_name%%/i", c_ws_plugin__s2member_utils_strings::esc_refs (urlencode (trim ($paypal["first_name"] . " " . $paypal["last_name"]))), $url)))
78
- if (($url = preg_replace ("/%%payer_email%%/i", c_ws_plugin__s2member_utils_strings::esc_refs (urlencode ($paypal["payer_email"])), $url)))
79
- if (($url = preg_replace ("/%%user_ip%%/i", c_ws_plugin__s2member_utils_strings::esc_refs (urlencode ($paypal["ip"])), $url)))
80
-
81
- if (($url = trim (preg_replace ("/%%(.+?)%%/i", "", $url))))
82
- c_ws_plugin__s2member_utils_urls::remote ($url);
83
-
84
- $paypal["s2member_log"][] = "Specific Post/Page ~ Refund/Reversal Notification URLs have been processed.";
85
- }
86
- if ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["sp_ref_rev_notification_recipients"] && is_array($cv = preg_split ("/\|/", $paypal["custom"])))
87
- {
88
- $msg = $sbj = "(s2Member / API Notification Email) - Specific Post/Page ~ Refund/Reversal";
89
- $msg .= "\n\n"; // Spacing in the message body.
90
-
91
- $msg .= "parent_txn_id: %%parent_txn_id%%\n";
92
- $msg .= "parent_txn_baid: %%parent_txn_baid%%\n";
93
- $msg .= "parent_txn_cid: %%parent_txn_cid%%\n";
94
- $msg .= "item_number: %%item_number%%\n";
95
- $msg .= "item_name: %%item_name%%\n";
96
- $msg .= "-amount: %%-amount%%\n";
97
- $msg .= "-fee: %%-fee%%\n";
98
- $msg .= "first_name: %%first_name%%\n";
99
- $msg .= "last_name: %%last_name%%\n";
100
- $msg .= "full_name: %%full_name%%\n";
101
- $msg .= "payer_email: %%payer_email%%\n";
102
- $msg .= "user_ip: %%user_ip%%\n";
103
-
104
- $msg .= "cv0: %%cv0%%\n";
105
- $msg .= "cv1: %%cv1%%\n";
106
- $msg .= "cv2: %%cv2%%\n";
107
- $msg .= "cv3: %%cv3%%\n";
108
- $msg .= "cv4: %%cv4%%\n";
109
- $msg .= "cv5: %%cv5%%\n";
110
- $msg .= "cv6: %%cv6%%\n";
111
- $msg .= "cv7: %%cv7%%\n";
112
- $msg .= "cv8: %%cv8%%\n";
113
- $msg .= "cv9: %%cv9%%";
114
-
115
- if (($msg = preg_replace ("/%%cv([0-9]+)%%/ei", 'trim(@$cv[$1])', $msg)) && ($msg = preg_replace ("/%%parent_txn_id%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($paypal["parent_txn_id"]), $msg)))
116
- if (($msg = preg_replace ("/%%parent_txn_baid%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($paypal["parent_txn_baid"]), $msg)) && ($msg = preg_replace ("/%%parent_txn_cid%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($paypal["parent_txn_cid"]), $msg)))
117
- if (($msg = preg_replace ("/%%item_number%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($paypal["item_number"]), $msg)) && ($msg = preg_replace ("/%%item_name%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($paypal["item_name"]), $msg)))
118
- if (($msg = preg_replace ("/%%-amount%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($paypal["mc_gross"]), $msg)) && ($msg = preg_replace ("/%%-fee%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($paypal["mc_fee"]), $msg)))
119
- if (($msg = preg_replace ("/%%first_name%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($paypal["first_name"]), $msg)) && ($msg = preg_replace ("/%%last_name%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($paypal["last_name"]), $msg)))
120
- if (($msg = preg_replace ("/%%full_name%%/i", c_ws_plugin__s2member_utils_strings::esc_refs (trim ($paypal["first_name"] . " " . $paypal["last_name"])), $msg)))
121
- if (($msg = preg_replace ("/%%payer_email%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($paypal["payer_email"]), $msg)))
122
- if (($msg = preg_replace ("/%%user_ip%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($paypal["ip"]), $msg)))
123
-
124
- if ($sbj && ($msg = trim (preg_replace ("/%%(.+?)%%/i", "", $msg)))) // Still have a ``$sbj`` and a ``$msg``?
125
-
126
- foreach (c_ws_plugin__s2member_utils_strings::parse_emails ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["sp_ref_rev_notification_recipients"]) as $recipient)
127
- wp_mail ($recipient, apply_filters("ws_plugin__s2member_sp_ref_rev_notification_email_sbj", $sbj, get_defined_vars ()), apply_filters("ws_plugin__s2member_sp_ref_rev_notification_email_msg", $msg, get_defined_vars ()), "Content-Type: text/plain; charset=UTF-8");
128
-
129
- $paypal["s2member_log"][] = "Specific Post/Page ~ Refund/Reversal Notification Emails have been processed.";
130
- }
131
- foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;
132
- do_action("ws_plugin__s2member_during_paypal_notify_during_sp_refund_reversal", get_defined_vars ());
133
- unset($__refs, $__v);
134
- }
135
- else // Else, this is a duplicate IPN. Must stop here.
136
- {
137
- $paypal["s2member_log"][] = "Not processing. Duplicate IPN.";
138
- $paypal["s2member_log"][] = "s2Member `txn_type` identified as ( `[empty or irrelevant]` ) w/ `payment_status` ( `refunded|reversed|reversal` ) - or - `new_case` w/ `case_type` ( `chargeback` ).";
139
- $paypal["s2member_log"][] = "Duplicate IPN. Already processed. This IPN will be ignored.";
140
- }
141
- foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;
142
- do_action("ws_plugin__s2member_during_paypal_notify_after_sp_refund_reversal", get_defined_vars ());
143
- unset($__refs, $__v);
144
-
145
- return apply_filters("c_ws_plugin__s2member_paypal_notify_in_sp_refund_reversal", $paypal, get_defined_vars ());
146
- }
147
- else return apply_filters("c_ws_plugin__s2member_paypal_notify_in_sp_refund_reversal", false, get_defined_vars ());
148
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
149
  }
150
- }
 
 
 
1
  <?php
2
  /**
3
+ * s2Member's PayPal IPN handler (inner processing routine).
4
+ *
5
+ * Copyright: © 2009-2011
6
+ * {@link http://www.websharks-inc.com/ WebSharks, Inc.}
7
+ * (coded in the USA)
8
+ *
9
+ * Released under the terms of the GNU General Public License.
10
+ * You should have received a copy of the GNU General Public License,
11
+ * along with this software. In the main directory, see: /licensing/
12
+ * If not, see: {@link http://www.gnu.org/licenses/}.
13
+ *
14
+ * @package s2Member\PayPal
15
+ * @since 110720
16
+ */
17
+ if(realpath(__FILE__) === realpath($_SERVER['SCRIPT_FILENAME']))
18
+ exit ('Do not access this file directly.');
19
+
20
+ if(!class_exists('c_ws_plugin__s2member_paypal_notify_in_sp_refund_reversal'))
21
+ {
22
+ /**
23
+ * s2Member's PayPal IPN handler (inner processing routine).
24
+ *
25
+ * @package s2Member\PayPal
26
+ * @since 110720
27
+ */
28
+ class c_ws_plugin__s2member_paypal_notify_in_sp_refund_reversal
29
  {
30
  /**
31
+ * s2Member's PayPal IPN handler (inner processing routine).
32
+ *
33
+ * @package s2Member\PayPal
34
+ * @since 110720
35
+ *
36
+ * @param array $vars Required. An array of defined variables passed by {@link s2Member\PayPal\c_ws_plugin__s2member_paypal_notify_in::paypal_notify()}.
37
+ *
38
+ * @return array|bool The original ``$paypal`` array passed in (extracted) from ``$vars``, or false when conditions do NOT apply.
39
+ */
40
+ public static function cp($vars = array()) // Conditional phase for ``c_ws_plugin__s2member_paypal_notify_in::paypal_notify()``.
41
+ {
42
+ extract($vars, EXTR_OVERWRITE | EXTR_REFS); // Extract all vars passed in from: ``c_ws_plugin__s2member_paypal_notify_in::paypal_notify()``.
43
+
44
+ if(((!empty($paypal['txn_type']) && preg_match('/^new_case$/i', $paypal['txn_type']) && !empty($paypal['case_type']) && preg_match('/^chargeback$/i', $paypal['case_type']))
45
+ || (!empty($paypal['payment_status']) && preg_match('/^(refunded|reversed|reversal)$/i', $paypal['payment_status'])) /* The 'txn_type' is irrelevant in these special situations. */)
46
+ && ((!empty($paypal['item_number']) || ($paypal['item_number'] = c_ws_plugin__s2member_paypal_utilities::paypal_pro_item_number($paypal))) && preg_match($GLOBALS['WS_PLUGIN__']['s2member']['c']['sp_access_item_number_regex'], $paypal['item_number']))
47
+ && (!empty($paypal['item_name']) || ($paypal['item_name'] = c_ws_plugin__s2member_paypal_utilities::paypal_pro_item_name($paypal)) || ($paypal['item_name'] = $_SERVER['HTTP_HOST']))
48
+ && (!empty($paypal['payer_email'])) && (!empty($paypal['parent_txn_id'])) && (!empty($paypal['parent_txn_baid']) || ($paypal['parent_txn_baid'] = $paypal['parent_txn_id']))
49
+ && (!empty($paypal['parent_txn_cid']) || ($paypal['parent_txn_cid'] = $paypal['parent_txn_id']))
50
+ )
51
  {
52
+ foreach(array_keys(get_defined_vars()) as $__v) $__refs[$__v] =& $$__v;
53
+ do_action('ws_plugin__s2member_during_paypal_notify_before_sp_refund_reversal', get_defined_vars());
54
+ unset($__refs, $__v);
55
+
56
+ if(!get_transient($transient_ipn = 's2m_ipn_'.md5('s2member_transient_'.$_paypal_s)) && set_transient($transient_ipn, time(), 31556926 * 10))
57
+ {
58
+ $paypal['s2member_log'][] = 's2Member `txn_type` identified as ( `[empty or irrelevant]` ) w/ `payment_status` ( `refunded|reversed|reversal` ) - or - `new_case` w/ `case_type` ( `chargeback` ).';
59
+
60
+ $paypal['ip'] = (preg_match('/ip address/i', $paypal['option_name2']) && $paypal['option_selection2']) ? $paypal['option_selection2'] : '';
61
+ $paypal['ip'] = (!$paypal['ip'] && preg_match('/^[a-z0-9]+~[0-9\.]+$/i', $paypal['invoice'])) ? preg_replace('/^[a-z0-9]+~/i', '', $paypal['invoice']) : $paypal['ip'];
62
+
63
+ $paypal['currency'] = strtoupper($paypal['mc_currency']); // Normalize input currency.
64
+ $paypal['currency_symbol'] = c_ws_plugin__s2member_utils_cur::symbol($paypal['currency']);
65
+
66
+ $processing = $during = TRUE; // Yes, we ARE processing this.
67
+ /*
68
+ Refunds and chargeback reversals. This is excluded from the processing check.
69
+ In other words, s2Member sends `Refund/Reversal` Notifications ANYTIME a Refund/Reversal occurs; even if s2Member did not process it otherwise.
70
+ Since this routine ignores the processing check, it is *possible* that Refund/Reversal Notification URLs will be contacted more than once.
71
+ If you're writing scripts that depend on Refund/Reversal Notifications, please keep this in mind.
72
+ */
73
+ if($GLOBALS['WS_PLUGIN__']['s2member']['o']['sp_ref_rev_notification_urls'] && is_array($cv = preg_split('/\|/', $paypal['custom'])))
74
+ {
75
+ foreach(preg_split('/['."\r\n\t".']+/', $GLOBALS['WS_PLUGIN__']['s2member']['o']['sp_ref_rev_notification_urls']) as $url)
76
+
77
+ if(($url = preg_replace('/%%cv([0-9]+)%%/ei', 'urlencode(trim(@$cv[$1]))', $url)) && ($url = preg_replace('/%%parent_txn_id%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($paypal['parent_txn_id'])), $url)))
78
+ if(($url = preg_replace('/%%parent_txn_baid%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($paypal['parent_txn_baid'])), $url)) && ($url = preg_replace('/%%parent_txn_cid%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($paypal['parent_txn_cid'])), $url)))
79
+ if(($url = preg_replace('/%%item_number%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($paypal['item_number'])), $url)) && ($url = preg_replace('/%%item_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($paypal['item_name'])), $url)))
80
+ if(($url = preg_replace('/%%currency%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($paypal['currency'])), $url)) && ($url = preg_replace('/%%currency_symbol%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($paypal['currency_symbol'])), $url)))
81
+ if(($url = preg_replace('/%%-amount%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($paypal['mc_gross'])), $url)) && ($url = preg_replace('/%%-fee%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($paypal['mc_fee'])), $url)))
82
+ if(($url = preg_replace('/%%first_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($paypal['first_name'])), $url)) && ($url = preg_replace('/%%last_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($paypal['last_name'])), $url)))
83
+ if(($url = preg_replace('/%%full_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode(trim($paypal['first_name'].' '.$paypal['last_name']))), $url)))
84
+ if(($url = preg_replace('/%%payer_email%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($paypal['payer_email'])), $url)))
85
+ if(($url = preg_replace('/%%user_ip%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($paypal['ip'])), $url)))
86
+
87
+ if(($url = trim(preg_replace('/%%(.+?)%%/i', '', $url))))
88
+ c_ws_plugin__s2member_utils_urls::remote($url);
89
+
90
+ $paypal['s2member_log'][] = 'Specific Post/Page ~ Refund/Reversal Notification URLs have been processed.';
91
+ }
92
+ if($GLOBALS['WS_PLUGIN__']['s2member']['o']['sp_ref_rev_notification_recipients'] && is_array($cv = preg_split('/\|/', $paypal['custom'])))
93
  {
94
+ $msg = $sbj = '(s2Member / API Notification Email) - Specific Post/Page ~ Refund/Reversal';
95
+ $msg .= "\n\n"; // Spacing in the message body.
96
+
97
+ $msg .= 'parent_txn_id: %%parent_txn_id%%'."\n";
98
+ $msg .= 'parent_txn_baid: %%parent_txn_baid%%'."\n";
99
+ $msg .= 'parent_txn_cid: %%parent_txn_cid%%'."\n";
100
+ $msg .= 'item_number: %%item_number%%'."\n";
101
+ $msg .= 'item_name: %%item_name%%'."\n";
102
+ $msg .= 'currency: %%currency%%'."\n";
103
+ $msg .= 'currency_symbol: %%currency_symbol%%'."\n";
104
+ $msg .= '-amount: %%-amount%%'."\n";
105
+ $msg .= '-fee: %%-fee%%'."\n";
106
+ $msg .= 'first_name: %%first_name%%'."\n";
107
+ $msg .= 'last_name: %%last_name%%'."\n";
108
+ $msg .= 'full_name: %%full_name%%'."\n";
109
+ $msg .= 'payer_email: %%payer_email%%'."\n";
110
+ $msg .= 'user_ip: %%user_ip%%'."\n";
111
+
112
+ $msg .= 'cv0: %%cv0%%'."\n";
113
+ $msg .= 'cv1: %%cv1%%'."\n";
114
+ $msg .= 'cv2: %%cv2%%'."\n";
115
+ $msg .= 'cv3: %%cv3%%'."\n";
116
+ $msg .= 'cv4: %%cv4%%'."\n";
117
+ $msg .= 'cv5: %%cv5%%'."\n";
118
+ $msg .= 'cv6: %%cv6%%'."\n";
119
+ $msg .= 'cv7: %%cv7%%'."\n";
120
+ $msg .= 'cv8: %%cv8%%'."\n";
121
+ $msg .= 'cv9: %%cv9%%';
122
+
123
+ if(($msg = preg_replace('/%%cv([0-9]+)%%/ei', 'trim(@$cv[$1])', $msg)) && ($msg = preg_replace('/%%parent_txn_id%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['parent_txn_id']), $msg)))
124
+ if(($msg = preg_replace('/%%parent_txn_baid%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['parent_txn_baid']), $msg)) && ($msg = preg_replace('/%%parent_txn_cid%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['parent_txn_cid']), $msg)))
125
+ if(($msg = preg_replace('/%%item_number%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['item_number']), $msg)) && ($msg = preg_replace('/%%item_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['item_name']), $msg)))
126
+ if(($msg = preg_replace('/%%currency%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['currency']), $msg)) && ($msg = preg_replace('/%%currency_symbol%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['currency_symbol']), $msg)))
127
+ if(($msg = preg_replace('/%%-amount%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['mc_gross']), $msg)) && ($msg = preg_replace('/%%-fee%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['mc_fee']), $msg)))
128
+ if(($msg = preg_replace('/%%first_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['first_name']), $msg)) && ($msg = preg_replace('/%%last_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['last_name']), $msg)))
129
+ if(($msg = preg_replace('/%%full_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(trim($paypal['first_name'].' '.$paypal['last_name'])), $msg)))
130
+ if(($msg = preg_replace('/%%payer_email%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['payer_email']), $msg)))
131
+ if(($msg = preg_replace('/%%user_ip%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['ip']), $msg)))
132
+
133
+ if($sbj && ($msg = trim(preg_replace('/%%(.+?)%%/i', '', $msg)))) // Still have a ``$sbj`` and a ``$msg``?
134
+
135
+ foreach(c_ws_plugin__s2member_utils_strings::parse_emails($GLOBALS['WS_PLUGIN__']['s2member']['o']['sp_ref_rev_notification_recipients']) as $recipient)
136
+ wp_mail($recipient, apply_filters('ws_plugin__s2member_sp_ref_rev_notification_email_sbj', $sbj, get_defined_vars()), apply_filters('ws_plugin__s2member_sp_ref_rev_notification_email_msg', $msg, get_defined_vars()), 'Content-Type: text/plain; charset=UTF-8');
137
+
138
+ $paypal['s2member_log'][] = 'Specific Post/Page ~ Refund/Reversal Notification Emails have been processed.';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
139
  }
140
+ foreach(array_keys(get_defined_vars()) as $__v) $__refs[$__v] =& $$__v;
141
+ do_action('ws_plugin__s2member_during_paypal_notify_during_sp_refund_reversal', get_defined_vars());
142
+ unset($__refs, $__v);
143
+ }
144
+ else // Else, this is a duplicate IPN. Must stop here.
145
+ {
146
+ $paypal['s2member_log'][] = 'Not processing. Duplicate IPN.';
147
+ $paypal['s2member_log'][] = 's2Member `txn_type` identified as ( `[empty or irrelevant]` ) w/ `payment_status` ( `refunded|reversed|reversal` ) - or - `new_case` w/ `case_type` ( `chargeback` ).';
148
+ $paypal['s2member_log'][] = 'Duplicate IPN. Already processed. This IPN will be ignored.';
149
+ }
150
+ foreach(array_keys(get_defined_vars()) as $__v) $__refs[$__v] =& $$__v;
151
+ do_action('ws_plugin__s2member_during_paypal_notify_after_sp_refund_reversal', get_defined_vars());
152
+ unset($__refs, $__v);
153
+
154
+ return apply_filters('c_ws_plugin__s2member_paypal_notify_in_sp_refund_reversal', $paypal, get_defined_vars());
155
  }
156
+ else return apply_filters('c_ws_plugin__s2member_paypal_notify_in_sp_refund_reversal', FALSE, get_defined_vars());
157
+ }
158
+ }
159
+ }
includes/classes/paypal-notify-in-subscr-modify-w-level.inc.php CHANGED
@@ -1,366 +1,379 @@
1
  <?php
2
  /**
3
- * s2Member's PayPal IPN handler (inner processing routine).
4
- *
5
- * Copyright: © 2009-2011
6
- * {@link http://www.websharks-inc.com/ WebSharks, Inc.}
7
- * (coded in the USA)
8
- *
9
- * Released under the terms of the GNU General Public License.
10
- * You should have received a copy of the GNU General Public License,
11
- * along with this software. In the main directory, see: /licensing/
12
- * If not, see: {@link http://www.gnu.org/licenses/}.
13
- *
14
- * @package s2Member\PayPal
15
- * @since 110720
16
- */
17
- if (realpath (__FILE__) === realpath ($_SERVER["SCRIPT_FILENAME"]))
18
- exit("Do not access this file directly.");
19
-
20
- if (!class_exists ("c_ws_plugin__s2member_paypal_notify_in_subscr_modify_w_level"))
 
 
 
 
 
 
 
 
21
  {
22
  /**
23
- * s2Member's PayPal IPN handler (inner processing routine).
24
- *
25
- * @package s2Member\PayPal
26
- * @since 110720
27
- */
28
- class c_ws_plugin__s2member_paypal_notify_in_subscr_modify_w_level
 
 
 
 
 
 
 
 
 
 
 
 
 
29
  {
30
- /**
31
- * s2Member's PayPal IPN handler (inner processing routine).
32
- *
33
- * @package s2Member\PayPal
34
- * @since 110720
35
- *
36
- * @param array $vars Required. An array of defined variables passed by {@link s2Member\PayPal\c_ws_plugin__s2member_paypal_notify_in::paypal_notify()}.
37
- * @return array|bool The original ``$paypal`` array passed in (extracted) from ``$vars``, or false when conditions do NOT apply.
38
- */
39
- public static function cp ($vars = array()) // Conditional phase for ``c_ws_plugin__s2member_paypal_notify_in::paypal_notify()``.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
40
  {
41
- extract($vars, EXTR_OVERWRITE | EXTR_REFS); // Extract all vars passed in from: ``c_ws_plugin__s2member_paypal_notify_in::paypal_notify()``.
 
 
 
 
 
 
 
42
 
43
- if ((!empty($paypal["txn_type"]) && preg_match ("/^subscr_modify$/i", $paypal["txn_type"]))
44
- && (!empty($paypal["item_number"]) && preg_match ($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["membership_item_number_w_level_regex"], $paypal["item_number"]))
45
- && (!empty($paypal["subscr_id"])) && (!empty($paypal["payer_email"]))
46
- && (!empty($paypal["subscr_baid"]) || ($paypal["subscr_baid"] = $paypal["subscr_id"]))
47
- && (!empty($paypal["subscr_cid"]) || ($paypal["subscr_cid"] = $paypal["subscr_id"])))
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
48
  {
49
- foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;
50
- do_action("ws_plugin__s2member_during_paypal_notify_before_subscr_modify", get_defined_vars ());
51
- unset($__refs, $__v);
52
-
53
- if (!get_transient ($transient_ipn = "s2m_ipn_" . md5 ("s2member_transient_" . $_paypal_s)) && set_transient ($transient_ipn, time (), 31556926 * 10))
54
- {
55
- $paypal["s2member_log"][] = "s2Member `txn_type` identified as ( `subscr_modify` ).";
56
-
57
- list ($paypal["level"], $paypal["ccaps"]/*, $paypal["eotper"] */) = preg_split ("/\:/", $paypal["item_number"], 2);
58
-
59
- $paypal["ip"] = (preg_match ("/ip address/i", $paypal["option_name2"]) && $paypal["option_selection2"]) ? $paypal["option_selection2"] : "";
60
- $paypal["ip"] = (!$paypal["ip"] && preg_match ("/^[a-z0-9]+~[0-9\.]+$/i", $paypal["invoice"])) ? preg_replace ("/^[a-z0-9]+~/i", "", $paypal["invoice"]) : $paypal["ip"];
61
-
62
- $paypal["period1"] = (preg_match ("/^[1-9]/", $paypal["period1"])) ? $paypal["period1"] : "0 D"; // Defaults to "0 D" (zero days).
63
- $paypal["mc_amount1"] = (strlen ($paypal["mc_amount1"]) && $paypal["mc_amount1"] > 0) ? $paypal["mc_amount1"] : "0.00"; // "0.00".
64
-
65
- $paypal["initial_term"] = (preg_match ("/^[1-9]/", $paypal["period1"])) ? $paypal["period1"] : "0 D"; // Defaults to "0 D" (zero days).
66
- $paypal["initial"] = (strlen ($paypal["mc_amount1"]) && preg_match ("/^[1-9]/", $paypal["period1"])) ? $paypal["mc_amount1"] : $paypal["mc_amount3"];
67
- $paypal["regular"] = $paypal["mc_amount3"]; // This is the Regular Payment Amount that is charged to the Customer. Always required by PayPal.
68
- $paypal["regular_term"] = $paypal["period3"]; // This is just set to keep a standard; this way both initial_term & regular_term are available.
69
- $paypal["recurring"] = ($paypal["recurring"]) ? $paypal["mc_amount3"] : "0"; // If non-recurring, this should be zero, otherwise Regular.
70
-
71
- $ipn_signup_vars = $paypal; unset($ipn_signup_vars["s2member_log"]); // Create array of IPN signup vars w/o s2member_log.
72
-
73
- if (($user_id = c_ws_plugin__s2member_utils_users::get_user_id_with ($paypal["subscr_id"])) && is_object ($user = new WP_User ($user_id)) && $user->ID)
74
- {
75
- if (!$user->has_cap ("administrator")) // Do NOT process this routine on Administrators.
76
- {
77
- $processing = $modifying = $during = true; // Yes, we ARE processing this.
78
-
79
- foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;
80
- do_action("ws_plugin__s2member_during_paypal_notify_during_before_subscr_modify", get_defined_vars ());
81
- do_action("ws_plugin__s2member_during_collective_mods", $user_id, get_defined_vars (), "ipn-upgrade-downgrade", "modification", "s2member_level" . $paypal["level"]);
82
- unset($__refs, $__v);
83
-
84
- $fields = get_user_option ("s2member_custom_fields", $user_id); // These will be needed in the routines below.
85
- $user_reg_ip = get_user_option ("s2member_registration_ip", $user_id); // Original IP during Registration.
86
- $user_reg_ip = $paypal["ip"] = ($user_reg_ip) ? $user_reg_ip : $paypal["ip"]; // Now merge conditionally.
87
-
88
- if (is_multisite () && !is_user_member_of_blog ($user_id)) // Must have a Role on this Blog.
89
- {
90
- add_existing_user_to_blog(array("user_id" => $user_id, "role" => "s2member_level" . $paypal["level"]));
91
- $user = new WP_User ($user_id);
92
- }
93
- $current_role = c_ws_plugin__s2member_user_access::user_access_role ($user);
94
-
95
- if ($current_role !== "s2member_level" . $paypal["level"]) // Only if we need to.
96
- $user->set_role ("s2member_level" . $paypal["level"]); // (upgrade/downgrade)
97
-
98
- if ($paypal["ccaps"] && preg_match ("/^-all/", str_replace ("+", "", $paypal["ccaps"])))
99
- foreach ($user->allcaps as $cap => $cap_enabled)
100
- if (preg_match ("/^access_s2member_ccap_/", $cap))
101
- $user->remove_cap ($ccap = $cap);
102
-
103
- if ($paypal["ccaps"] && preg_replace ("/^-all[\r\n\t\s;,]*/", "", str_replace ("+", "", $paypal["ccaps"])))
104
- foreach (preg_split ("/[\r\n\t\s;,]+/", preg_replace ("/^-all[\r\n\t\s;,]*/", "", str_replace ("+", "", $paypal["ccaps"]))) as $ccap)
105
- if (strlen ($ccap = trim (strtolower (preg_replace ("/[^a-z_0-9]/i", "", $ccap)))))
106
- $user->add_cap ("access_s2member_ccap_" . $ccap);
107
-
108
- update_user_option ($user_id, "s2member_subscr_gateway", $paypal["subscr_gateway"]);
109
- update_user_option ($user_id, "s2member_subscr_id", $paypal["subscr_id"]);
110
- update_user_option ($user_id, "s2member_subscr_baid", $paypal["subscr_baid"]);
111
- update_user_option ($user_id, "s2member_subscr_cid", $paypal["subscr_cid"]);
112
-
113
- update_user_option ($user_id, "s2member_custom", $paypal["custom"]);
114
-
115
- if (!get_user_option ("s2member_registration_ip", $user_id))
116
- update_user_option ($user_id, "s2member_registration_ip", $paypal["ip"]);
117
-
118
- update_user_option ($user_id, "s2member_ipn_signup_vars", $ipn_signup_vars);
119
-
120
- delete_user_option ($user_id, "s2member_file_download_access_log");
121
-
122
- delete_user_option ($user_id, "s2member_auto_eot_time");
123
-
124
- $pr_times = get_user_option ("s2member_paid_registration_times", $user_id);
125
- $pr_times["level"] = (!$pr_times["level"]) ? time () : $pr_times["level"]; // Preserves existing.
126
- $pr_times["level" . $paypal["level"]] = (!$pr_times["level" . $paypal["level"]]) ? time () : $pr_times["level" . $paypal["level"]];
127
- update_user_option ($user_id, "s2member_paid_registration_times", $pr_times); // Update now.
128
-
129
- c_ws_plugin__s2member_user_notes::clear_user_note_lines ($user_id, "/^Demoted by s2Member\:/");
130
- c_ws_plugin__s2member_user_notes::clear_user_note_lines ($user_id, "/^Paid Subscr\. ID @ time of demotion\:/");
131
-
132
- $paypal["s2member_log"][] = "s2Member Level/Capabilities updated on Subscription modification.";
133
-
134
- $sbj = $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["modification_email_subject"]; // The same for standard and w/ Pro Forms.
135
- $msg = $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["modification_email_message"]; // The same for standard and w/ Pro Forms.
136
- $rec = $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["modification_email_recipients"]; // The same for standard and w/ Pro Forms.
137
-
138
- if (($rec = preg_replace ("/%%cv([0-9]+)%%/ei", 'trim(@$cv[$1])', $rec)) && ($rec = preg_replace ("/%%subscr_id%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($paypal["subscr_id"]), $rec)))
139
- if (($rec = preg_replace ("/%%subscr_baid%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($paypal["subscr_baid"]), $rec)) && ($rec = preg_replace ("/%%subscr_cid%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($paypal["subscr_cid"]), $rec)))
140
- if (($rec = preg_replace ("/%%initial%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($paypal["initial"]), $rec)) && ($rec = preg_replace ("/%%regular%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($paypal["regular"]), $rec)))
141
- if (($rec = preg_replace ("/%%initial_term%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($paypal["initial_term"]), $rec)) && ($rec = preg_replace ("/%%regular_term%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($paypal["regular_term"]), $rec)))
142
- if (($rec = preg_replace ("/%%initial_cycle%%/i", c_ws_plugin__s2member_utils_strings::esc_refs (c_ws_plugin__s2member_utils_time::period_term ($paypal["initial_term"])), $rec)) && ($rec = preg_replace ("/%%regular_cycle%%/i", c_ws_plugin__s2member_utils_strings::esc_refs (c_ws_plugin__s2member_utils_time::period_term ($paypal["regular_term"], $paypal["recurring"])), $rec)))
143
- if (($rec = preg_replace ("/%%recurring%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($paypal["recurring"]), $rec)) && ($rec = preg_replace ("/%%recurring\/regular_cycle%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ((($paypal["recurring"]) ? $paypal["recurring"] . " / " . c_ws_plugin__s2member_utils_time::period_term ($paypal["regular_term"], true) : "0 / non-recurring")), $rec)))
144
- if (($rec = preg_replace ("/%%item_number%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($paypal["item_number"]), $rec)) && ($rec = preg_replace ("/%%item_name%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($paypal["item_name"]), $rec)))
145
- if (($rec = preg_replace ("/%%first_name%%/i", c_ws_plugin__s2member_utils_strings::esc_dq (c_ws_plugin__s2member_utils_strings::esc_refs ($paypal["first_name"])), $rec)) && ($rec = preg_replace ("/%%last_name%%/i", c_ws_plugin__s2member_utils_strings::esc_dq (c_ws_plugin__s2member_utils_strings::esc_refs ($paypal["last_name"])), $rec)))
146
- if (($rec = preg_replace ("/%%full_name%%/i", c_ws_plugin__s2member_utils_strings::esc_dq (c_ws_plugin__s2member_utils_strings::esc_refs (trim ($paypal["first_name"] . " " . $paypal["last_name"]))), $rec))) // **NOTE** c_ws_plugin__s2member_utils_strings::esc_dq() is applied here. (ex. "N\"ame" <email>).
147
- if (($rec = preg_replace ("/%%payer_email%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($paypal["payer_email"]), $rec)))
148
-
149
- if (($rec = preg_replace ("/%%user_first_name%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($user->first_name), $rec)) && ($rec = preg_replace ("/%%user_last_name%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($user->last_name), $rec)))
150
- if (($rec = preg_replace ("/%%user_full_name%%/i", c_ws_plugin__s2member_utils_strings::esc_refs (trim ($user->first_name . " " . $user->last_name)), $rec)))
151
- if (($rec = preg_replace ("/%%user_email%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($user->user_email), $rec)))
152
- if (($rec = preg_replace ("/%%user_login%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($user->user_login), $rec)))
153
- if (($rec = preg_replace ("/%%user_ip%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($user_reg_ip), $rec)))
154
- if (($rec = preg_replace ("/%%user_id%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($user_id), $rec)))
155
-
156
- if (($sbj = preg_replace ("/%%cv([0-9]+)%%/ei", 'trim(@$cv[$1])', $sbj)) && ($sbj = preg_replace ("/%%subscr_id%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($paypal["subscr_id"]), $sbj)))
157
- if (($sbj = preg_replace ("/%%subscr_baid%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($paypal["subscr_baid"]), $sbj)) && ($sbj = preg_replace ("/%%subscr_cid%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($paypal["subscr_cid"]), $sbj)))
158
- if (($sbj = preg_replace ("/%%initial%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($paypal["initial"]), $sbj)) && ($sbj = preg_replace ("/%%regular%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($paypal["regular"]), $sbj)))
159
- if (($sbj = preg_replace ("/%%initial_term%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($paypal["initial_term"]), $sbj)) && ($sbj = preg_replace ("/%%regular_term%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($paypal["regular_term"]), $sbj)))
160
- if (($sbj = preg_replace ("/%%initial_cycle%%/i", c_ws_plugin__s2member_utils_strings::esc_refs (c_ws_plugin__s2member_utils_time::period_term ($paypal["initial_term"])), $sbj)) && ($sbj = preg_replace ("/%%regular_cycle%%/i", c_ws_plugin__s2member_utils_strings::esc_refs (c_ws_plugin__s2member_utils_time::period_term ($paypal["regular_term"], $paypal["recurring"])), $sbj)))
161
- if (($sbj = preg_replace ("/%%recurring%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($paypal["recurring"]), $sbj)) && ($sbj = preg_replace ("/%%recurring\/regular_cycle%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ((($paypal["recurring"]) ? $paypal["recurring"] . " / " . c_ws_plugin__s2member_utils_time::period_term ($paypal["regular_term"], true) : "0 / non-recurring")), $sbj)))
162
- if (($sbj = preg_replace ("/%%item_number%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($paypal["item_number"]), $sbj)) && ($sbj = preg_replace ("/%%item_name%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($paypal["item_name"]), $sbj)))
163
- if (($sbj = preg_replace ("/%%first_name%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($paypal["first_name"]), $sbj)) && ($sbj = preg_replace ("/%%last_name%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($paypal["last_name"]), $sbj)))
164
- if (($sbj = preg_replace ("/%%full_name%%/i", c_ws_plugin__s2member_utils_strings::esc_refs (trim ($paypal["first_name"] . " " . $paypal["last_name"])), $sbj)))
165
- if (($sbj = preg_replace ("/%%payer_email%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($paypal["payer_email"]), $sbj)))
166
-
167
- if (($sbj = preg_replace ("/%%user_first_name%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($user->first_name), $sbj)) && ($sbj = preg_replace ("/%%user_last_name%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($user->last_name), $sbj)))
168
- if (($sbj = preg_replace ("/%%user_full_name%%/i", c_ws_plugin__s2member_utils_strings::esc_refs (trim ($user->first_name . " " . $user->last_name)), $sbj)))
169
- if (($sbj = preg_replace ("/%%user_email%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($user->user_email), $sbj)))
170
- if (($sbj = preg_replace ("/%%user_login%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($user->user_login), $sbj)))
171
- if (($sbj = preg_replace ("/%%user_ip%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($user_reg_ip), $sbj)))
172
- if (($sbj = preg_replace ("/%%user_id%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($user_id), $sbj)))
173
-
174
- if (($msg = preg_replace ("/%%cv([0-9]+)%%/ei", 'trim(@$cv[$1])', $msg)) && ($msg = preg_replace ("/%%subscr_id%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($paypal["subscr_id"]), $msg)))
175
- if (($msg = preg_replace ("/%%subscr_baid%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($paypal["subscr_baid"]), $msg)) && ($msg = preg_replace ("/%%subscr_cid%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($paypal["subscr_cid"]), $msg)))
176
- if (($msg = preg_replace ("/%%initial%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($paypal["initial"]), $msg)) && ($msg = preg_replace ("/%%regular%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($paypal["regular"]), $msg)))
177
- if (($msg = preg_replace ("/%%initial_term%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($paypal["initial_term"]), $msg)) && ($msg = preg_replace ("/%%regular_term%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($paypal["regular_term"]), $msg)))
178
- if (($msg = preg_replace ("/%%initial_cycle%%/i", c_ws_plugin__s2member_utils_strings::esc_refs (c_ws_plugin__s2member_utils_time::period_term ($paypal["initial_term"])), $msg)) && ($msg = preg_replace ("/%%regular_cycle%%/i", c_ws_plugin__s2member_utils_strings::esc_refs (c_ws_plugin__s2member_utils_time::period_term ($paypal["regular_term"], $paypal["recurring"])), $msg)))
179
- if (($msg = preg_replace ("/%%recurring%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($paypal["recurring"]), $msg)) && ($msg = preg_replace ("/%%recurring\/regular_cycle%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ((($paypal["recurring"]) ? $paypal["recurring"] . " / " . c_ws_plugin__s2member_utils_time::period_term ($paypal["regular_term"], true) : "0 / non-recurring")), $msg)))
180
- if (($msg = preg_replace ("/%%item_number%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($paypal["item_number"]), $msg)) && ($msg = preg_replace ("/%%item_name%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($paypal["item_name"]), $msg)))
181
- if (($msg = preg_replace ("/%%first_name%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($paypal["first_name"]), $msg)) && ($msg = preg_replace ("/%%last_name%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($paypal["last_name"]), $msg)))
182
- if (($msg = preg_replace ("/%%full_name%%/i", c_ws_plugin__s2member_utils_strings::esc_refs (trim ($paypal["first_name"] . " " . $paypal["last_name"])), $msg)))
183
- if (($msg = preg_replace ("/%%payer_email%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($paypal["payer_email"]), $msg)))
184
-
185
- if (($msg = preg_replace ("/%%user_first_name%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($user->first_name), $msg)) && ($msg = preg_replace ("/%%user_last_name%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($user->last_name), $msg)))
186
- if (($msg = preg_replace ("/%%user_full_name%%/i", c_ws_plugin__s2member_utils_strings::esc_refs (trim ($user->first_name . " " . $user->last_name)), $msg)))
187
- if (($msg = preg_replace ("/%%user_email%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($user->user_email), $msg)))
188
- if (($msg = preg_replace ("/%%user_login%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($user->user_login), $msg)))
189
- if (($msg = preg_replace ("/%%user_ip%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($user_reg_ip), $msg)))
190
- if (($msg = preg_replace ("/%%user_id%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($user_id), $msg)))
191
- {
192
- if (is_array($fields) && !empty($fields)) foreach /* Custom Registration/Profile Fields. */ ($fields as $var => $val)
193
- {
194
- $rec = preg_replace ("/%%" . preg_quote ($var, "/") . "%%/i", c_ws_plugin__s2member_utils_strings::esc_refs (maybe_serialize ($val)), $rec);
195
- $sbj = preg_replace ("/%%" . preg_quote ($var, "/") . "%%/i", c_ws_plugin__s2member_utils_strings::esc_refs (maybe_serialize ($val)), $sbj);
196
- $msg = preg_replace ("/%%" . preg_quote ($var, "/") . "%%/i", c_ws_plugin__s2member_utils_strings::esc_refs (maybe_serialize ($val)), $msg);
197
- }
198
- if (($rec = trim (preg_replace ("/%%(.+?)%%/i", "", $rec))) && ($sbj = trim (preg_replace ("/%%(.+?)%%/i", "", $sbj))) && ($msg = trim (preg_replace ("/%%(.+?)%%/i", "", $msg))))
199
- {
200
- if (!is_multisite () || !c_ws_plugin__s2member_utils_conds::is_multisite_farm () || is_main_site ())
201
- {
202
- $sbj = c_ws_plugin__s2member_utilities::evl($sbj, get_defined_vars());
203
- $msg = c_ws_plugin__s2member_utilities::evl($msg, get_defined_vars());
204
- }
205
- foreach /* Go through a possible list of recipients. */(c_ws_plugin__s2member_utils_strings::parse_emails ($rec) as $recipient)
206
- c_ws_plugin__s2member_email_configs::email_config () . wp_mail ($recipient, apply_filters("ws_plugin__s2member_modification_email_sbj", $sbj, get_defined_vars ()), apply_filters("ws_plugin__s2member_modification_email_msg", $msg, get_defined_vars ()), "From: \"" . preg_replace ('/"/', "'", $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["reg_email_from_name"]) . "\" <" . $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["reg_email_from_email"] . ">\r\nContent-Type: text/plain; charset=UTF-8") . c_ws_plugin__s2member_email_configs::email_config_release ();
207
-
208
- $paypal["s2member_log"][] = "Modification Confirmation Email sent to: " . $rec . ".";
209
- }
210
- }
211
- if ($processing && $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["modification_notification_urls"] && is_array($cv = preg_split ("/\|/", $paypal["custom"])))
212
- {
213
- foreach (preg_split ("/[\r\n\t]+/", $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["modification_notification_urls"]) as $url)
214
-
215
- if (($url = preg_replace ("/%%cv([0-9]+)%%/ei", 'urlencode(trim(@$cv[$1]))', $url)) && ($url = preg_replace ("/%%subscr_id%%/i", c_ws_plugin__s2member_utils_strings::esc_refs (urlencode ($paypal["subscr_id"])), $url)))
216
- if (($url = preg_replace ("/%%subscr_baid%%/i", c_ws_plugin__s2member_utils_strings::esc_refs (urlencode ($paypal["subscr_baid"])), $url)) && ($url = preg_replace ("/%%subscr_cid%%/i", c_ws_plugin__s2member_utils_strings::esc_refs (urlencode ($paypal["subscr_cid"])), $url)))
217
- if (($url = preg_replace ("/%%initial%%/i", c_ws_plugin__s2member_utils_strings::esc_refs (urlencode ($paypal["initial"])), $url)) && ($url = preg_replace ("/%%regular%%/i", c_ws_plugin__s2member_utils_strings::esc_refs (urlencode ($paypal["regular"])), $url)) && ($url = preg_replace ("/%%recurring%%/i", c_ws_plugin__s2member_utils_strings::esc_refs (urlencode ($paypal["recurring"])), $url)))
218
- if (($url = preg_replace ("/%%initial_term%%/i", c_ws_plugin__s2member_utils_strings::esc_refs (urlencode ($paypal["initial_term"])), $url)) && ($url = preg_replace ("/%%regular_term%%/i", c_ws_plugin__s2member_utils_strings::esc_refs (urlencode ($paypal["regular_term"])), $url)))
219
- if (($url = preg_replace ("/%%item_number%%/i", c_ws_plugin__s2member_utils_strings::esc_refs (urlencode ($paypal["item_number"])), $url)) && ($url = preg_replace ("/%%item_name%%/i", c_ws_plugin__s2member_utils_strings::esc_refs (urlencode ($paypal["item_name"])), $url)))
220
- if (($url = preg_replace ("/%%first_name%%/i", c_ws_plugin__s2member_utils_strings::esc_refs (urlencode ($paypal["first_name"])), $url)) && ($url = preg_replace ("/%%last_name%%/i", c_ws_plugin__s2member_utils_strings::esc_refs (urlencode ($paypal["last_name"])), $url)))
221
- if (($url = preg_replace ("/%%full_name%%/i", c_ws_plugin__s2member_utils_strings::esc_refs (urlencode (trim ($paypal["first_name"] . " " . $paypal["last_name"]))), $url)))
222
- if (($url = preg_replace ("/%%payer_email%%/i", c_ws_plugin__s2member_utils_strings::esc_refs (urlencode ($paypal["payer_email"])), $url)))
223
-
224
- if (($url = preg_replace ("/%%user_first_name%%/i", c_ws_plugin__s2member_utils_strings::esc_refs (urlencode ($user->first_name)), $url)) && ($url = preg_replace ("/%%user_last_name%%/i", c_ws_plugin__s2member_utils_strings::esc_refs (urlencode ($user->last_name)), $url)))
225
- if (($url = preg_replace ("/%%user_full_name%%/i", c_ws_plugin__s2member_utils_strings::esc_refs (urlencode (trim ($user->first_name . " " . $user->last_name))), $url)))
226
- if (($url = preg_replace ("/%%user_email%%/i", c_ws_plugin__s2member_utils_strings::esc_refs (urlencode ($user->user_email)), $url)))
227
- if (($url = preg_replace ("/%%user_login%%/i", c_ws_plugin__s2member_utils_strings::esc_refs (urlencode ($user->user_login)), $url)))
228
- if (($url = preg_replace ("/%%user_ip%%/i", c_ws_plugin__s2member_utils_strings::esc_refs (urlencode ($user_reg_ip)), $url)))
229
- if (($url = preg_replace ("/%%user_id%%/i", c_ws_plugin__s2member_utils_strings::esc_refs (urlencode ($user_id)), $url)))
230
- {
231
- if (is_array($fields) && !empty($fields))
232
- foreach /* Custom Registration/Profile Fields. */ ($fields as $var => $val)
233
- if (!($url = preg_replace ("/%%" . preg_quote ($var, "/") . "%%/i", c_ws_plugin__s2member_utils_strings::esc_refs (urlencode (maybe_serialize ($val))), $url)))
234
- break;
235
-
236
- if (($url = trim (preg_replace ("/%%(.+?)%%/i", "", $url))))
237
- c_ws_plugin__s2member_utils_urls::remote ($url);
238
- }
239
- $paypal["s2member_log"][] = "Modification Notification URLs have been processed.";
240
- }
241
- if ($processing && $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["modification_notification_recipients"] && is_array($cv = preg_split ("/\|/", $paypal["custom"])))
242
- {
243
- $msg = $sbj = "(s2Member / API Notification Email) - Modification";
244
- $msg .= "\n\n"; // Spacing in the message body.
245
-
246
- $msg .= "subscr_id: %%subscr_id%%\n";
247
- $msg .= "subscr_baid: %%subscr_baid%%\n";
248
- $msg .= "subscr_cid: %%subscr_cid%%\n";
249
- $msg .= "initial: %%initial%%\n";
250
- $msg .= "regular: %%regular%%\n";
251
- $msg .= "recurring: %%recurring%%\n";
252
- $msg .= "initial_term: %%initial_term%%\n";
253
- $msg .= "regular_term: %%regular_term%%\n";
254
- $msg .= "item_number: %%item_number%%\n";
255
- $msg .= "item_name: %%item_name%%\n";
256
- $msg .= "first_name: %%first_name%%\n";
257
- $msg .= "last_name: %%last_name%%\n";
258
- $msg .= "full_name: %%full_name%%\n";
259
- $msg .= "payer_email: %%payer_email%%\n";
260
-
261
- $msg .= "user_first_name: %%user_first_name%%\n";
262
- $msg .= "user_last_name: %%user_last_name%%\n";
263
- $msg .= "user_full_name: %%user_full_name%%\n";
264
- $msg .= "user_email: %%user_email%%\n";
265
- $msg .= "user_login: %%user_login%%\n";
266
- $msg .= "user_ip: %%user_ip%%\n";
267
- $msg .= "user_id: %%user_id%%\n";
268
-
269
- if (is_array($fields) && !empty($fields))
270
- foreach ($fields as $var => $val)
271
- $msg .= $var . ": %%" . $var . "%%\n";
272
-
273
- $msg .= "cv0: %%cv0%%\n";
274
- $msg .= "cv1: %%cv1%%\n";
275
- $msg .= "cv2: %%cv2%%\n";
276
- $msg .= "cv3: %%cv3%%\n";
277
- $msg .= "cv4: %%cv4%%\n";
278
- $msg .= "cv5: %%cv5%%\n";
279
- $msg .= "cv6: %%cv6%%\n";
280
- $msg .= "cv7: %%cv7%%\n";
281
- $msg .= "cv8: %%cv8%%\n";
282
- $msg .= "cv9: %%cv9%%";
283
-
284
- if (($msg = preg_replace ("/%%cv([0-9]+)%%/ei", 'trim(@$cv[$1])', $msg)) && ($msg = preg_replace ("/%%subscr_id%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($paypal["subscr_id"]), $msg)))
285
- if (($msg = preg_replace ("/%%subscr_baid%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($paypal["subscr_baid"]), $msg)) && ($msg = preg_replace ("/%%subscr_cid%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($paypal["subscr_cid"]), $msg)))
286
- if (($msg = preg_replace ("/%%initial%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($paypal["initial"]), $msg)) && ($msg = preg_replace ("/%%regular%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($paypal["regular"]), $msg)) && ($msg = preg_replace ("/%%recurring%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($paypal["recurring"]), $msg)))
287
- if (($msg = preg_replace ("/%%initial_term%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($paypal["initial_term"]), $msg)) && ($msg = preg_replace ("/%%regular_term%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($paypal["regular_term"]), $msg)))
288
- if (($msg = preg_replace ("/%%item_number%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($paypal["item_number"]), $msg)) && ($msg = preg_replace ("/%%item_name%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($paypal["item_name"]), $msg)))
289
- if (($msg = preg_replace ("/%%first_name%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($paypal["first_name"]), $msg)) && ($msg = preg_replace ("/%%last_name%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($paypal["last_name"]), $msg)))
290
- if (($msg = preg_replace ("/%%full_name%%/i", c_ws_plugin__s2member_utils_strings::esc_refs (trim ($paypal["first_name"] . " " . $paypal["last_name"])), $msg)))
291
- if (($msg = preg_replace ("/%%payer_email%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($paypal["payer_email"]), $msg)))
292
-
293
- if (($msg = preg_replace ("/%%user_first_name%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($user->first_name), $msg)) && ($msg = preg_replace ("/%%user_last_name%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($user->last_name), $msg)))
294
- if (($msg = preg_replace ("/%%user_full_name%%/i", c_ws_plugin__s2member_utils_strings::esc_refs (trim ($user->first_name . " " . $user->last_name)), $msg)))
295
- if (($msg = preg_replace ("/%%user_email%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($user->user_email), $msg)))
296
- if (($msg = preg_replace ("/%%user_login%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($user->user_login), $msg)))
297
- if (($msg = preg_replace ("/%%user_ip%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($user_reg_ip), $msg)))
298
- if (($msg = preg_replace ("/%%user_id%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($user_id), $msg)))
299
- {
300
- if (is_array($fields) && !empty($fields))
301
- foreach /* Custom Registration/Profile Fields. */ ($fields as $var => $val)
302
- if (!($msg = preg_replace ("/%%" . preg_quote ($var, "/") . "%%/i", c_ws_plugin__s2member_utils_strings::esc_refs (maybe_serialize ($val)), $msg)))
303
- break;
304
-
305
- if ($sbj && ($msg = trim (preg_replace ("/%%(.+?)%%/i", "", $msg)))) // Still have a ``$sbj`` and a ``$msg``?
306
-
307
- foreach (c_ws_plugin__s2member_utils_strings::parse_emails ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["modification_notification_recipients"]) as $recipient)
308
- wp_mail ($recipient, apply_filters("ws_plugin__s2member_modification_notification_email_sbj", $sbj, get_defined_vars ()), apply_filters("ws_plugin__s2member_modification_notification_email_msg", $msg, get_defined_vars ()), "Content-Type: text/plain; charset=UTF-8");
309
- }
310
- $paypal["s2member_log"][] = "Modification Notification Emails have been processed.";
311
- }
312
- if ($processing && ($code = $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["modification_tracking_codes"]) && is_array($cv = preg_split ("/\|/", $paypal["custom"])))
313
- {
314
- if (($code = preg_replace ("/%%cv([0-9]+)%%/ei", 'trim(@$cv[$1])', $code)) && ($code = preg_replace ("/%%subscr_id%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($paypal["subscr_id"]), $code)))
315
- if (($code = preg_replace ("/%%subscr_baid%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($paypal["subscr_baid"]), $code)) && ($code = preg_replace ("/%%subscr_cid%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($paypal["subscr_cid"]), $code)))
316
- if (($code = preg_replace ("/%%initial%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($paypal["initial"]), $code)) && ($code = preg_replace ("/%%regular%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($paypal["regular"]), $code)) && ($code = preg_replace ("/%%recurring%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($paypal["recurring"]), $code)))
317
- if (($code = preg_replace ("/%%initial_term%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($paypal["initial_term"]), $code)) && ($code = preg_replace ("/%%regular_term%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($paypal["regular_term"]), $code)))
318
- if (($code = preg_replace ("/%%item_number%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($paypal["item_number"]), $code)) && ($code = preg_replace ("/%%item_name%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($paypal["item_name"]), $code)))
319
- if (($code = preg_replace ("/%%first_name%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($paypal["first_name"]), $code)) && ($code = preg_replace ("/%%last_name%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($paypal["last_name"]), $code)))
320
- if (($code = preg_replace ("/%%full_name%%/i", c_ws_plugin__s2member_utils_strings::esc_refs (trim ($paypal["first_name"] . " " . $paypal["last_name"])), $code)))
321
- if (($code = preg_replace ("/%%payer_email%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($paypal["payer_email"]), $code)))
322
- {
323
- if (($code = preg_replace ("/%%user_first_name%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($user->first_name), $code)) && ($code = preg_replace ("/%%user_last_name%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($user->last_name), $code)))
324
- if (($code = preg_replace ("/%%user_full_name%%/i", c_ws_plugin__s2member_utils_strings::esc_refs (trim ($user->first_name . " " . $user->last_name)), $code)))
325
- if (($code = preg_replace ("/%%user_email%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($user->user_email), $code)))
326
- if (($code = preg_replace ("/%%user_login%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($user->user_login), $code)))
327
- if (($code = preg_replace ("/%%user_ip%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($user_reg_ip), $code)))
328
- if (($code = preg_replace ("/%%user_id%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($user_id), $code)))
329
- {
330
- if (is_array($fields) && !empty($fields))
331
- foreach /* Custom Registration/Profile Fields. */ ($fields as $var => $val)
332
- if (!($code = preg_replace ("/%%" . preg_quote ($var, "/") . "%%/i", c_ws_plugin__s2member_utils_strings::esc_refs (maybe_serialize ($val)), $code)))
333
- break;
334
-
335
- if (($code = trim (preg_replace ("/%%(.+?)%%/i", "", $code)))) // This gets stored into a Transient Queue.
336
- {
337
- $paypal["s2member_log"][] = "Storing Modification Tracking Codes into a Transient Queue. These will be processed on-site.";
338
- set_transient ("s2m_" . md5 ("s2member_transient_modification_tracking_codes_" . $paypal["subscr_id"]), $code, 43200);
339
- }
340
- }
341
- }
342
- }
343
- foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;
344
- do_action("ws_plugin__s2member_during_paypal_notify_during_subscr_modify", get_defined_vars ());
345
- unset($__refs, $__v);
346
- }
347
- else $paypal["s2member_log"][] = "Unable to modify Subscription. The existing User ID is associated with an Administrator. Stopping here. Otherwise, an Administrator could lose access.";
348
- }
349
- else $paypal["s2member_log"][] = "Unable to modify Subscription. Could not get the existing User ID from the DB.";
350
- }
351
- else // Else, this is a duplicate IPN. Must stop here.
352
- {
353
- $paypal["s2member_log"][] = "Not processing. Duplicate IPN.";
354
- $paypal["s2member_log"][] = "s2Member `txn_type` identified as ( `subscr_modify` ).";
355
- $paypal["s2member_log"][] = "Duplicate IPN. Already processed. This IPN will be ignored.";
356
- }
357
- foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;
358
- do_action("ws_plugin__s2member_during_paypal_notify_after_subscr_modify", get_defined_vars ());
359
- unset($__refs, $__v);
360
-
361
- return apply_filters("c_ws_plugin__s2member_paypal_notify_in_subscr_modify_w_level", $paypal, get_defined_vars ());
362
  }
363
- else return apply_filters("c_ws_plugin__s2member_paypal_notify_in_subscr_modify_w_level", false, get_defined_vars ());
 
 
 
 
364
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
365
  }
366
- }
 
 
 
1
  <?php
2
  /**
3
+ * s2Member's PayPal IPN handler (inner processing routine).
4
+ *
5
+ * Copyright: © 2009-2011
6
+ * {@link http://www.websharks-inc.com/ WebSharks, Inc.}
7
+ * (coded in the USA)
8
+ *
9
+ * Released under the terms of the GNU General Public License.
10
+ * You should have received a copy of the GNU General Public License,
11
+ * along with this software. In the main directory, see: /licensing/
12
+ * If not, see: {@link http://www.gnu.org/licenses/}.
13
+ *
14
+ * @package s2Member\PayPal
15
+ * @since 110720
16
+ */
17
+ if(realpath(__FILE__) === realpath($_SERVER['SCRIPT_FILENAME']))
18
+ exit('Do not access this file directly.');
19
+
20
+ if(!class_exists('c_ws_plugin__s2member_paypal_notify_in_subscr_modify_w_level'))
21
+ {
22
+ /**
23
+ * s2Member's PayPal IPN handler (inner processing routine).
24
+ *
25
+ * @package s2Member\PayPal
26
+ * @since 110720
27
+ */
28
+ class c_ws_plugin__s2member_paypal_notify_in_subscr_modify_w_level
29
  {
30
  /**
31
+ * s2Member's PayPal IPN handler (inner processing routine).
32
+ *
33
+ * @package s2Member\PayPal
34
+ * @since 110720
35
+ *
36
+ * @param array $vars Required. An array of defined variables passed by {@link s2Member\PayPal\c_ws_plugin__s2member_paypal_notify_in::paypal_notify()}.
37
+ *
38
+ * @return array|bool The original ``$paypal`` array passed in (extracted) from ``$vars``, or false when conditions do NOT apply.
39
+ */
40
+ public static function cp($vars = array()) // Conditional phase for ``c_ws_plugin__s2member_paypal_notify_in::paypal_notify()``.
41
+ {
42
+ extract($vars, EXTR_OVERWRITE | EXTR_REFS); // Extract all vars passed in from: ``c_ws_plugin__s2member_paypal_notify_in::paypal_notify()``.
43
+
44
+ if((!empty($paypal['txn_type']) && preg_match('/^subscr_modify$/i', $paypal['txn_type']))
45
+ && (!empty($paypal['item_number']) && preg_match($GLOBALS['WS_PLUGIN__']['s2member']['c']['membership_item_number_w_level_regex'], $paypal['item_number']))
46
+ && (!empty($paypal['subscr_id'])) && (!empty($paypal['payer_email']))
47
+ && (!empty($paypal['subscr_baid']) || ($paypal['subscr_baid'] = $paypal['subscr_id']))
48
+ && (!empty($paypal['subscr_cid']) || ($paypal['subscr_cid'] = $paypal['subscr_id']))
49
+ )
50
  {
51
+ foreach(array_keys(get_defined_vars()) as $__v) $__refs[$__v] =& $$__v;
52
+ do_action('ws_plugin__s2member_during_paypal_notify_before_subscr_modify', get_defined_vars());
53
+ unset($__refs, $__v);
54
+
55
+ if(!get_transient($transient_ipn = 's2m_ipn_'.md5('s2member_transient_'.$_paypal_s)) && set_transient($transient_ipn, time(), 31556926 * 10))
56
+ {
57
+ $paypal['s2member_log'][] = 's2Member `txn_type` identified as ( `subscr_modify` ).';
58
+
59
+ list ($paypal['level'], $paypal['ccaps']/*, $paypal['eotper'] */) = preg_split('/\:/', $paypal['item_number'], 2);
60
+
61
+ $paypal['ip'] = (preg_match('/ip address/i', $paypal['option_name2']) && $paypal['option_selection2']) ? $paypal['option_selection2'] : '';
62
+ $paypal['ip'] = (!$paypal['ip'] && preg_match('/^[a-z0-9]+~[0-9\.]+$/i', $paypal['invoice'])) ? preg_replace('/^[a-z0-9]+~/i', '', $paypal['invoice']) : $paypal['ip'];
63
+
64
+ $paypal['period1'] = (preg_match('/^[1-9]/', $paypal['period1'])) ? $paypal['period1'] : '0 D'; // Defaults to '0 D' (zero days).
65
+ $paypal['mc_amount1'] = (strlen($paypal['mc_amount1']) && $paypal['mc_amount1'] > 0) ? $paypal['mc_amount1'] : '0.00'; // '0.00'.
66
+
67
+ $paypal['initial_term'] = (preg_match('/^[1-9]/', $paypal['period1'])) ? $paypal['period1'] : '0 D'; // Defaults to '0 D' (zero days).
68
+ $paypal['initial'] = (strlen($paypal['mc_amount1']) && preg_match('/^[1-9]/', $paypal['period1'])) ? $paypal['mc_amount1'] : $paypal['mc_amount3'];
69
+ $paypal['regular'] = $paypal['mc_amount3']; // This is the Regular Payment Amount that is charged to the Customer. Always required by PayPal.
70
+ $paypal['regular_term'] = $paypal['period3']; // This is just set to keep a standard; this way both initial_term & regular_term are available.
71
+ $paypal['recurring'] = ($paypal['recurring']) ? $paypal['mc_amount3'] : '0'; // If non-recurring, this should be zero, otherwise Regular.
72
+ $paypal['currency'] = strtoupper($paypal['mc_currency']); // Normalize input currency.
73
+ $paypal['currency_symbol'] = c_ws_plugin__s2member_utils_cur::symbol($paypal['currency']);
74
+
75
+ $ipn_signup_vars = $paypal;
76
+ unset($ipn_signup_vars['s2member_log']); // Create array of IPN signup vars w/o s2member_log.
77
+
78
+ if(($user_id = c_ws_plugin__s2member_utils_users::get_user_id_with($paypal['subscr_id'])) && is_object($user = new WP_User ($user_id)) && $user->ID)
79
  {
80
+ if(!$user->has_cap('administrator')) // Do NOT process this routine on Administrators.
81
+ {
82
+ $processing = $modifying = $during = TRUE; // Yes, we ARE processing this.
83
+
84
+ foreach(array_keys(get_defined_vars()) as $__v) $__refs[$__v] =& $$__v;
85
+ do_action('ws_plugin__s2member_during_paypal_notify_during_before_subscr_modify', get_defined_vars());
86
+ do_action('ws_plugin__s2member_during_collective_mods', $user_id, get_defined_vars(), 'ipn-upgrade-downgrade', 'modification', 's2member_level'.$paypal['level']);
87
+ unset($__refs, $__v);
88
 
89
+ $fields = get_user_option('s2member_custom_fields', $user_id); // These will be needed in the routines below.
90
+ $user_reg_ip = get_user_option('s2member_registration_ip', $user_id); // Original IP during Registration.
91
+ $user_reg_ip = $paypal['ip'] = ($user_reg_ip) ? $user_reg_ip : $paypal['ip']; // Now merge conditionally.
92
+
93
+ if(is_multisite() && !is_user_member_of_blog($user_id)) // Must have a Role on this Blog.
94
+ {
95
+ add_existing_user_to_blog(array('user_id' => $user_id, 'role' => 's2member_level'.$paypal['level']));
96
+ $user = new WP_User ($user_id);
97
+ }
98
+ $current_role = c_ws_plugin__s2member_user_access::user_access_role($user);
99
+
100
+ if($current_role !== 's2member_level'.$paypal['level']) // Only if we need to.
101
+ $user->set_role('s2member_level'.$paypal['level']); // (upgrade/downgrade)
102
+
103
+ if($paypal['ccaps'] && preg_match('/^-all/', str_replace('+', '', $paypal['ccaps'])))
104
+ foreach($user->allcaps as $cap => $cap_enabled)
105
+ if(preg_match('/^access_s2member_ccap_/', $cap))
106
+ $user->remove_cap($ccap = $cap);
107
+
108
+ if($paypal['ccaps'] && preg_replace('/^-all['."\r\n\t".'\s;,]*/', '', str_replace('+', '', $paypal['ccaps'])))
109
+ foreach(preg_split('/['."\r\n\t".'\s;,]+/', preg_replace('/^-all['."\r\n\t".'\s;,]*/', '', str_replace('+', '', $paypal['ccaps']))) as $ccap)
110
+ if(strlen($ccap = trim(strtolower(preg_replace('/[^a-z_0-9]/i', '', $ccap)))))
111
+ $user->add_cap('access_s2member_ccap_'.$ccap);
112
+
113
+ update_user_option($user_id, 's2member_subscr_gateway', $paypal['subscr_gateway']);
114
+ update_user_option($user_id, 's2member_subscr_id', $paypal['subscr_id']);
115
+ update_user_option($user_id, 's2member_subscr_baid', $paypal['subscr_baid']);
116
+ update_user_option($user_id, 's2member_subscr_cid', $paypal['subscr_cid']);
117
+
118
+ update_user_option($user_id, 's2member_custom', $paypal['custom']);
119
+
120
+ if(!get_user_option('s2member_registration_ip', $user_id))
121
+ update_user_option($user_id, 's2member_registration_ip', $paypal['ip']);
122
+
123
+ update_user_option($user_id, 's2member_ipn_signup_vars', $ipn_signup_vars);
124
+
125
+ delete_user_option($user_id, 's2member_file_download_access_log');
126
+
127
+ delete_user_option($user_id, 's2member_auto_eot_time');
128
+
129
+ $pr_times = get_user_option('s2member_paid_registration_times', $user_id);
130
+ $pr_times['level'] = (!$pr_times['level']) ? time() : $pr_times['level']; // Preserves existing.
131
+ $pr_times['level'.$paypal['level']] = (!$pr_times['level'.$paypal['level']]) ? time() : $pr_times['level'.$paypal['level']];
132
+ update_user_option($user_id, 's2member_paid_registration_times', $pr_times); // Update now.
133
+
134
+ c_ws_plugin__s2member_user_notes::clear_user_note_lines($user_id, '/^Demoted by s2Member\:/');
135
+ c_ws_plugin__s2member_user_notes::clear_user_note_lines($user_id, '/^Paid Subscr\. ID @ time of demotion\:/');
136
+
137
+ $paypal['s2member_log'][] = 's2Member Level/Capabilities updated on Subscription modification.';
138
+
139
+ $sbj = $GLOBALS['WS_PLUGIN__']['s2member']['o']['modification_email_subject']; // The same for standard and w/ Pro Forms.
140
+ $msg = $GLOBALS['WS_PLUGIN__']['s2member']['o']['modification_email_message']; // The same for standard and w/ Pro Forms.
141
+ $rec = $GLOBALS['WS_PLUGIN__']['s2member']['o']['modification_email_recipients']; // The same for standard and w/ Pro Forms.
142
+
143
+ if(($rec = preg_replace('/%%cv([0-9]+)%%/ei', 'trim(@$cv[$1])', $rec)) && ($rec = preg_replace('/%%subscr_id%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['subscr_id']), $rec)))
144
+ if(($rec = preg_replace('/%%subscr_baid%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['subscr_baid']), $rec)) && ($rec = preg_replace('/%%subscr_cid%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['subscr_cid']), $rec)))
145
+ if(($rec = preg_replace('/%%currency%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['currency']), $rec)) && ($rec = preg_replace('/%%currency_symbol%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['currency_symbol']), $rec)))
146
+ if(($rec = preg_replace('/%%initial%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['initial']), $rec)) && ($rec = preg_replace('/%%regular%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['regular']), $rec)))
147
+ if(($rec = preg_replace('/%%initial_term%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['initial_term']), $rec)) && ($rec = preg_replace('/%%regular_term%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['regular_term']), $rec)))
148
+ if(($rec = preg_replace('/%%initial_cycle%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(c_ws_plugin__s2member_utils_time::period_term($paypal['initial_term'])), $rec)) && ($rec = preg_replace('/%%regular_cycle%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(c_ws_plugin__s2member_utils_time::period_term($paypal['regular_term'], $paypal['recurring'])), $rec)))
149
+ if(($rec = preg_replace('/%%recurring%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['recurring']), $rec)) && ($rec = preg_replace('/%%recurring\/regular_cycle%%/i', c_ws_plugin__s2member_utils_strings::esc_refs((($paypal['recurring']) ? $paypal['recurring'].' / '.c_ws_plugin__s2member_utils_time::period_term($paypal['regular_term'], TRUE) : '0 / non-recurring')), $rec)))
150
+ if(($rec = preg_replace('/%%item_number%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['item_number']), $rec)) && ($rec = preg_replace('/%%item_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['item_name']), $rec)))
151
+ if(($rec = preg_replace('/%%first_name%%/i', c_ws_plugin__s2member_utils_strings::esc_dq(c_ws_plugin__s2member_utils_strings::esc_refs($paypal['first_name'])), $rec)) && ($rec = preg_replace('/%%last_name%%/i', c_ws_plugin__s2member_utils_strings::esc_dq(c_ws_plugin__s2member_utils_strings::esc_refs($paypal['last_name'])), $rec)))
152
+ if(($rec = preg_replace('/%%full_name%%/i', c_ws_plugin__s2member_utils_strings::esc_dq(c_ws_plugin__s2member_utils_strings::esc_refs(trim($paypal['first_name'].' '.$paypal['last_name']))), $rec))) // **NOTE** c_ws_plugin__s2member_utils_strings::esc_dq() is applied here. (ex. 'N\'ame' <email>).
153
+ if(($rec = preg_replace('/%%payer_email%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['payer_email']), $rec)))
154
+
155
+ if(($rec = preg_replace('/%%user_first_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($user->first_name), $rec)) && ($rec = preg_replace('/%%user_last_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($user->last_name), $rec)))
156
+ if(($rec = preg_replace('/%%user_full_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(trim($user->first_name.' '.$user->last_name)), $rec)))
157
+ if(($rec = preg_replace('/%%user_email%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($user->user_email), $rec)))
158
+ if(($rec = preg_replace('/%%user_login%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($user->user_login), $rec)))
159
+ if(($rec = preg_replace('/%%user_ip%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($user_reg_ip), $rec)))
160
+ if(($rec = preg_replace('/%%user_id%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($user_id), $rec)))
161
+
162
+ if(($sbj = preg_replace('/%%cv([0-9]+)%%/ei', 'trim(@$cv[$1])', $sbj)) && ($sbj = preg_replace('/%%subscr_id%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['subscr_id']), $sbj)))
163
+ if(($sbj = preg_replace('/%%subscr_baid%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['subscr_baid']), $sbj)) && ($sbj = preg_replace('/%%subscr_cid%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['subscr_cid']), $sbj)))
164
+ if(($sbj = preg_replace('/%%currency%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['currency']), $sbj)) && ($sbj = preg_replace('/%%currency_symbol%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['currency_symbol']), $sbj)))
165
+ if(($sbj = preg_replace('/%%initial%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['initial']), $sbj)) && ($sbj = preg_replace('/%%regular%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['regular']), $sbj)))
166
+ if(($sbj = preg_replace('/%%initial_term%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['initial_term']), $sbj)) && ($sbj = preg_replace('/%%regular_term%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['regular_term']), $sbj)))
167
+ if(($sbj = preg_replace('/%%initial_cycle%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(c_ws_plugin__s2member_utils_time::period_term($paypal['initial_term'])), $sbj)) && ($sbj = preg_replace('/%%regular_cycle%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(c_ws_plugin__s2member_utils_time::period_term($paypal['regular_term'], $paypal['recurring'])), $sbj)))
168
+ if(($sbj = preg_replace('/%%recurring%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['recurring']), $sbj)) && ($sbj = preg_replace('/%%recurring\/regular_cycle%%/i', c_ws_plugin__s2member_utils_strings::esc_refs((($paypal['recurring']) ? $paypal['recurring'].' / '.c_ws_plugin__s2member_utils_time::period_term($paypal['regular_term'], TRUE) : '0 / non-recurring')), $sbj)))
169
+ if(($sbj = preg_replace('/%%item_number%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['item_number']), $sbj)) && ($sbj = preg_replace('/%%item_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['item_name']), $sbj)))
170
+ if(($sbj = preg_replace('/%%first_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['first_name']), $sbj)) && ($sbj = preg_replace('/%%last_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['last_name']), $sbj)))
171
+ if(($sbj = preg_replace('/%%full_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(trim($paypal['first_name'].' '.$paypal['last_name'])), $sbj)))
172
+ if(($sbj = preg_replace('/%%payer_email%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['payer_email']), $sbj)))
173
+
174
+ if(($sbj = preg_replace('/%%user_first_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($user->first_name), $sbj)) && ($sbj = preg_replace('/%%user_last_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($user->last_name), $sbj)))
175
+ if(($sbj = preg_replace('/%%user_full_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(trim($user->first_name.' '.$user->last_name)), $sbj)))
176
+ if(($sbj = preg_replace('/%%user_email%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($user->user_email), $sbj)))
177
+ if(($sbj = preg_replace('/%%user_login%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($user->user_login), $sbj)))
178
+ if(($sbj = preg_replace('/%%user_ip%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($user_reg_ip), $sbj)))
179
+ if(($sbj = preg_replace('/%%user_id%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($user_id), $sbj)))
180
+
181
+ if(($msg = preg_replace('/%%cv([0-9]+)%%/ei', 'trim(@$cv[$1])', $msg)) && ($msg = preg_replace('/%%subscr_id%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['subscr_id']), $msg)))
182
+ if(($msg = preg_replace('/%%subscr_baid%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['subscr_baid']), $msg)) && ($msg = preg_replace('/%%subscr_cid%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['subscr_cid']), $msg)))
183
+ if(($msg = preg_replace('/%%currency%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['currency']), $msg)) && ($msg = preg_replace('/%%currency_symbol%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['currency_symbol']), $msg)))
184
+ if(($msg = preg_replace('/%%initial%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['initial']), $msg)) && ($msg = preg_replace('/%%regular%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['regular']), $msg)))
185
+ if(($msg = preg_replace('/%%initial_term%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['initial_term']), $msg)) && ($msg = preg_replace('/%%regular_term%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['regular_term']), $msg)))
186
+ if(($msg = preg_replace('/%%initial_cycle%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(c_ws_plugin__s2member_utils_time::period_term($paypal['initial_term'])), $msg)) && ($msg = preg_replace('/%%regular_cycle%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(c_ws_plugin__s2member_utils_time::period_term($paypal['regular_term'], $paypal['recurring'])), $msg)))
187
+ if(($msg = preg_replace('/%%recurring%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['recurring']), $msg)) && ($msg = preg_replace('/%%recurring\/regular_cycle%%/i', c_ws_plugin__s2member_utils_strings::esc_refs((($paypal['recurring']) ? $paypal['recurring'].' / '.c_ws_plugin__s2member_utils_time::period_term($paypal['regular_term'], TRUE) : '0 / non-recurring')), $msg)))
188
+ if(($msg = preg_replace('/%%item_number%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['item_number']), $msg)) && ($msg = preg_replace('/%%item_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['item_name']), $msg)))
189
+ if(($msg = preg_replace('/%%first_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['first_name']), $msg)) && ($msg = preg_replace('/%%last_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['last_name']), $msg)))
190
+ if(($msg = preg_replace('/%%full_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(trim($paypal['first_name'].' '.$paypal['last_name'])), $msg)))
191
+ if(($msg = preg_replace('/%%payer_email%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['payer_email']), $msg)))
192
+
193
+ if(($msg = preg_replace('/%%user_first_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($user->first_name), $msg)) && ($msg = preg_replace('/%%user_last_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($user->last_name), $msg)))
194
+ if(($msg = preg_replace('/%%user_full_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(trim($user->first_name.' '.$user->last_name)), $msg)))
195
+ if(($msg = preg_replace('/%%user_email%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($user->user_email), $msg)))
196
+ if(($msg = preg_replace('/%%user_login%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($user->user_login), $msg)))
197
+ if(($msg = preg_replace('/%%user_ip%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($user_reg_ip), $msg)))
198
+ if(($msg = preg_replace('/%%user_id%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($user_id), $msg)))
199
+ {
200
+ if(is_array($fields) && !empty($fields)) foreach($fields as $var => $val/* Custom Registration/Profile Fields. */)
201
+ {
202
+ $rec = preg_replace('/%%'.preg_quote($var, '/').'%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(maybe_serialize($val)), $rec);
203
+ $sbj = preg_replace('/%%'.preg_quote($var, '/').'%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(maybe_serialize($val)), $sbj);
204
+ $msg = preg_replace('/%%'.preg_quote($var, '/').'%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(maybe_serialize($val)), $msg);
205
+ }
206
+ if(($rec = trim(preg_replace('/%%(.+?)%%/i', '', $rec))) && ($sbj = trim(preg_replace('/%%(.+?)%%/i', '', $sbj))) && ($msg = trim(preg_replace('/%%(.+?)%%/i', '', $msg))))
207
+ {
208
+ if(!is_multisite() || !c_ws_plugin__s2member_utils_conds::is_multisite_farm() || is_main_site())
209
+ {
210
+ $sbj = c_ws_plugin__s2member_utilities::evl($sbj, get_defined_vars());
211
+ $msg = c_ws_plugin__s2member_utilities::evl($msg, get_defined_vars());
212
+ }
213
+ foreach(c_ws_plugin__s2member_utils_strings::parse_emails($rec) as $recipient /* Go through a possible list of recipients. */)
214
+ c_ws_plugin__s2member_email_configs::email_config().wp_mail($recipient, apply_filters('ws_plugin__s2member_modification_email_sbj', $sbj, get_defined_vars()), apply_filters('ws_plugin__s2member_modification_email_msg', $msg, get_defined_vars()), 'From: "'.preg_replace('/"/', "'", $GLOBALS['WS_PLUGIN__']['s2member']['o']['reg_email_from_name']).'" <'.$GLOBALS['WS_PLUGIN__']['s2member']['o']['reg_email_from_email'].'>'."\r\n".'Content-Type: text/plain; charset=UTF-8').c_ws_plugin__s2member_email_configs::email_config_release();
215
+
216
+ $paypal['s2member_log'][] = 'Modification Confirmation Email sent to: '.$rec.'.';
217
+ }
218
+ }
219
+ if($processing && $GLOBALS['WS_PLUGIN__']['s2member']['o']['modification_notification_urls'] && is_array($cv = preg_split('/\|/', $paypal['custom'])))
220
+ {
221
+ foreach(preg_split('/['."\r\n\t".']+/', $GLOBALS['WS_PLUGIN__']['s2member']['o']['modification_notification_urls']) as $url)
222
+
223
+ if(($url = preg_replace('/%%cv([0-9]+)%%/ei', 'urlencode(trim(@$cv[$1]))', $url)) && ($url = preg_replace('/%%subscr_id%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($paypal['subscr_id'])), $url)))
224
+ if(($url = preg_replace('/%%subscr_baid%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($paypal['subscr_baid'])), $url)) && ($url = preg_replace('/%%subscr_cid%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($paypal['subscr_cid'])), $url)))
225
+ if(($url = preg_replace('/%%currency%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($paypal['currency'])), $url)) && ($url = preg_replace('/%%currency_symbol%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($paypal['currency_symbol'])), $url)))
226
+ if(($url = preg_replace('/%%initial%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($paypal['initial'])), $url)) && ($url = preg_replace('/%%regular%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($paypal['regular'])), $url)) && ($url = preg_replace('/%%recurring%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($paypal['recurring'])), $url)))
227
+ if(($url = preg_replace('/%%initial_term%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($paypal['initial_term'])), $url)) && ($url = preg_replace('/%%regular_term%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($paypal['regular_term'])), $url)))
228
+ if(($url = preg_replace('/%%item_number%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($paypal['item_number'])), $url)) && ($url = preg_replace('/%%item_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($paypal['item_name'])), $url)))
229
+ if(($url = preg_replace('/%%first_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($paypal['first_name'])), $url)) && ($url = preg_replace('/%%last_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($paypal['last_name'])), $url)))
230
+ if(($url = preg_replace('/%%full_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode(trim($paypal['first_name'].' '.$paypal['last_name']))), $url)))
231
+ if(($url = preg_replace('/%%payer_email%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($paypal['payer_email'])), $url)))
232
+
233
+ if(($url = preg_replace('/%%user_first_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($user->first_name)), $url)) && ($url = preg_replace('/%%user_last_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($user->last_name)), $url)))
234
+ if(($url = preg_replace('/%%user_full_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode(trim($user->first_name.' '.$user->last_name))), $url)))
235
+ if(($url = preg_replace('/%%user_email%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($user->user_email)), $url)))
236
+ if(($url = preg_replace('/%%user_login%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($user->user_login)), $url)))
237
+ if(($url = preg_replace('/%%user_ip%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($user_reg_ip)), $url)))
238
+ if(($url = preg_replace('/%%user_id%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($user_id)), $url)))
239
+ {
240
+ if(is_array($fields) && !empty($fields))
241
+ foreach($fields as $var => $val /* Custom Registration/Profile Fields. */)
242
+ if(!($url = preg_replace('/%%'.preg_quote($var, '/').'%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode(maybe_serialize($val))), $url)))
243
+ break;
244
+
245
+ if(($url = trim(preg_replace('/%%(.+?)%%/i', '', $url))))
246
+ c_ws_plugin__s2member_utils_urls::remote($url);
247
+ }
248
+ $paypal['s2member_log'][] = 'Modification Notification URLs have been processed.';
249
+ }
250
+ if($processing && $GLOBALS['WS_PLUGIN__']['s2member']['o']['modification_notification_recipients'] && is_array($cv = preg_split('/\|/', $paypal['custom'])))
251
+ {
252
+ $msg = $sbj = '(s2Member / API Notification Email) - Modification';
253
+ $msg .= "\n\n"; // Spacing in the message body.
254
+
255
+ $msg .= 'subscr_id: %%subscr_id%%'."\n";
256
+ $msg .= 'subscr_baid: %%subscr_baid%%'."\n";
257
+ $msg .= 'subscr_cid: %%subscr_cid%%'."\n";
258
+ $msg .= 'currency: %%currency%%'."\n";
259
+ $msg .= 'currency_symbol: %%currency_symbol%%'."\n";
260
+ $msg .= 'initial: %%initial%%'."\n";
261
+ $msg .= 'regular: %%regular%%'."\n";
262
+ $msg .= 'recurring: %%recurring%%'."\n";
263
+ $msg .= 'initial_term: %%initial_term%%'."\n";
264
+ $msg .= 'regular_term: %%regular_term%%'."\n";
265
+ $msg .= 'item_number: %%item_number%%'."\n";
266
+ $msg .= 'item_name: %%item_name%%'."\n";
267
+ $msg .= 'first_name: %%first_name%%'."\n";
268
+ $msg .= 'last_name: %%last_name%%'."\n";
269
+ $msg .= 'full_name: %%full_name%%'."\n";
270
+ $msg .= 'payer_email: %%payer_email%%'."\n";
271
+
272
+ $msg .= 'user_first_name: %%user_first_name%%'."\n";
273
+ $msg .= 'user_last_name: %%user_last_name%%'."\n";
274
+ $msg .= 'user_full_name: %%user_full_name%%'."\n";
275
+ $msg .= 'user_email: %%user_email%%'."\n";
276
+ $msg .= 'user_login: %%user_login%%'."\n";
277
+ $msg .= 'user_ip: %%user_ip%%'."\n";
278
+ $msg .= 'user_id: %%user_id%%'."\n";
279
+
280
+ if(is_array($fields) && !empty($fields))
281
+ foreach($fields as $var => $val)
282
+ $msg .= $var.': %%'.$var.'%%'."\n";
283
+
284
+ $msg .= 'cv0: %%cv0%%'."\n";
285
+ $msg .= 'cv1: %%cv1%%'."\n";
286
+ $msg .= 'cv2: %%cv2%%'."\n";
287
+ $msg .= 'cv3: %%cv3%%'."\n";
288
+ $msg .= 'cv4: %%cv4%%'."\n";
289
+ $msg .= 'cv5: %%cv5%%'."\n";
290
+ $msg .= 'cv6: %%cv6%%'."\n";
291
+ $msg .= 'cv7: %%cv7%%'."\n";
292
+ $msg .= 'cv8: %%cv8%%'."\n";
293
+ $msg .= 'cv9: %%cv9%%';
294
+
295
+ if(($msg = preg_replace('/%%cv([0-9]+)%%/ei', 'trim(@$cv[$1])', $msg)) && ($msg = preg_replace('/%%subscr_id%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['subscr_id']), $msg)))
296
+ if(($msg = preg_replace('/%%subscr_baid%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['subscr_baid']), $msg)) && ($msg = preg_replace('/%%subscr_cid%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['subscr_cid']), $msg)))
297
+ if(($msg = preg_replace('/%%currency%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['currency']), $msg)) && ($msg = preg_replace('/%%currency_symbol%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['currency_symbol']), $msg)))
298
+ if(($msg = preg_replace('/%%initial%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['initial']), $msg)) && ($msg = preg_replace('/%%regular%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['regular']), $msg)) && ($msg = preg_replace('/%%recurring%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['recurring']), $msg)))
299
+ if(($msg = preg_replace('/%%initial_term%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['initial_term']), $msg)) && ($msg = preg_replace('/%%regular_term%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['regular_term']), $msg)))
300
+ if(($msg = preg_replace('/%%item_number%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['item_number']), $msg)) && ($msg = preg_replace('/%%item_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['item_name']), $msg)))
301
+ if(($msg = preg_replace('/%%first_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['first_name']), $msg)) && ($msg = preg_replace('/%%last_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['last_name']), $msg)))
302
+ if(($msg = preg_replace('/%%full_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(trim($paypal['first_name'].' '.$paypal['last_name'])), $msg)))
303
+ if(($msg = preg_replace('/%%payer_email%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['payer_email']), $msg)))
304
+
305
+ if(($msg = preg_replace('/%%user_first_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($user->first_name), $msg)) && ($msg = preg_replace('/%%user_last_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($user->last_name), $msg)))
306
+ if(($msg = preg_replace('/%%user_full_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(trim($user->first_name.' '.$user->last_name)), $msg)))
307
+ if(($msg = preg_replace('/%%user_email%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($user->user_email), $msg)))
308
+ if(($msg = preg_replace('/%%user_login%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($user->user_login), $msg)))
309
+ if(($msg = preg_replace('/%%user_ip%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($user_reg_ip), $msg)))
310
+ if(($msg = preg_replace('/%%user_id%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($user_id), $msg)))
311
+ {
312
+ if(is_array($fields) && !empty($fields))
313
+ foreach($fields as $var => $val /* Custom Registration/Profile Fields. */)
314
+ if(!($msg = preg_replace('/%%'.preg_quote($var, '/').'%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(maybe_serialize($val)), $msg)))
315
+ break;
316
+
317
+ if($sbj && ($msg = trim(preg_replace('/%%(.+?)%%/i', '', $msg)))) // Still have a ``$sbj`` and a ``$msg``?
318
+
319
+ foreach(c_ws_plugin__s2member_utils_strings::parse_emails($GLOBALS['WS_PLUGIN__']['s2member']['o']['modification_notification_recipients']) as $recipient)
320
+ wp_mail($recipient, apply_filters('ws_plugin__s2member_modification_notification_email_sbj', $sbj, get_defined_vars()), apply_filters('ws_plugin__s2member_modification_notification_email_msg', $msg, get_defined_vars()), 'Content-Type: text/plain; charset=UTF-8');
321
+ }
322
+ $paypal['s2member_log'][] = 'Modification Notification Emails have been processed.';
323
+ }
324
+ if($processing && ($code = $GLOBALS['WS_PLUGIN__']['s2member']['o']['modification_tracking_codes']) && is_array($cv = preg_split('/\|/', $paypal['custom'])))
325
  {
326
+ if(($code = preg_replace('/%%cv([0-9]+)%%/ei', 'trim(@$cv[$1])', $code)) && ($code = preg_replace('/%%subscr_id%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['subscr_id']), $code)))
327
+ if(($code = preg_replace('/%%subscr_baid%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['subscr_baid']), $code)) && ($code = preg_replace('/%%subscr_cid%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['subscr_cid']), $code)))
328
+ if(($code = preg_replace('/%%currency%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['currency']), $code)) && ($code = preg_replace('/%%currency_symbol%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['currency_symbol']), $code)))
329
+ if(($code = preg_replace('/%%initial%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['initial']), $code)) && ($code = preg_replace('/%%regular%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['regular']), $code)) && ($code = preg_replace('/%%recurring%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['recurring']), $code)))
330
+ if(($code = preg_replace('/%%initial_term%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['initial_term']), $code)) && ($code = preg_replace('/%%regular_term%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['regular_term']), $code)))
331
+ if(($code = preg_replace('/%%item_number%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['item_number']), $code)) && ($code = preg_replace('/%%item_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['item_name']), $code)))
332
+ if(($code = preg_replace('/%%first_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['first_name']), $code)) && ($code = preg_replace('/%%last_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['last_name']), $code)))
333
+ if(($code = preg_replace('/%%full_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(trim($paypal['first_name'].' '.$paypal['last_name'])), $code)))
334
+ if(($code = preg_replace('/%%payer_email%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['payer_email']), $code)))
335
+ {
336
+ if(($code = preg_replace('/%%user_first_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($user->first_name), $code)) && ($code = preg_replace('/%%user_last_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($user->last_name), $code)))
337
+ if(($code = preg_replace('/%%user_full_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(trim($user->first_name.' '.$user->last_name)), $code)))
338
+ if(($code = preg_replace('/%%user_email%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($user->user_email), $code)))
339
+ if(($code = preg_replace('/%%user_login%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($user->user_login), $code)))
340
+ if(($code = preg_replace('/%%user_ip%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($user_reg_ip), $code)))
341
+ if(($code = preg_replace('/%%user_id%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($user_id), $code)))
342
+ {
343
+ if(is_array($fields) && !empty($fields))
344
+ foreach($fields as $var => $val /* Custom Registration/Profile Fields. */)
345
+ if(!($code = preg_replace('/%%'.preg_quote($var, '/').'%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(maybe_serialize($val)), $code)))
346
+ break;
347
+
348
+ if(($code = trim(preg_replace('/%%(.+?)%%/i', '', $code)))) // This gets stored into a Transient Queue.
349
+ {
350
+ $paypal['s2member_log'][] = 'Storing Modification Tracking Codes into a Transient Queue. These will be processed on-site.';
351
+ set_transient('s2m_'.md5('s2member_transient_modification_tracking_codes_'.$paypal['subscr_id']), $code, 43200);
352
+ }
353
+ }
354
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
355
  }
356
+ foreach(array_keys(get_defined_vars()) as $__v) $__refs[$__v] =& $$__v;
357
+ do_action('ws_plugin__s2member_during_paypal_notify_during_subscr_modify', get_defined_vars());
358
+ unset($__refs, $__v);
359
+ }
360
+ else $paypal['s2member_log'][] = 'Unable to modify Subscription. The existing User ID is associated with an Administrator. Stopping here. Otherwise, an Administrator could lose access.';
361
  }
362
+ else $paypal['s2member_log'][] = 'Unable to modify Subscription. Could not get the existing User ID from the DB.';
363
+ }
364
+ else // Else, this is a duplicate IPN. Must stop here.
365
+ {
366
+ $paypal['s2member_log'][] = 'Not processing. Duplicate IPN.';
367
+ $paypal['s2member_log'][] = 's2Member `txn_type` identified as ( `subscr_modify` ).';
368
+ $paypal['s2member_log'][] = 'Duplicate IPN. Already processed. This IPN will be ignored.';
369
+ }
370
+ foreach(array_keys(get_defined_vars()) as $__v) $__refs[$__v] =& $$__v;
371
+ do_action('ws_plugin__s2member_during_paypal_notify_after_subscr_modify', get_defined_vars());
372
+ unset($__refs, $__v);
373
+
374
+ return apply_filters('c_ws_plugin__s2member_paypal_notify_in_subscr_modify_w_level', $paypal, get_defined_vars());
375
  }
376
+ else return apply_filters('c_ws_plugin__s2member_paypal_notify_in_subscr_modify_w_level', FALSE, get_defined_vars());
377
+ }
378
+ }
379
+ }
includes/classes/paypal-notify-in-subscr-or-rp-eots-w-level.inc.php CHANGED
@@ -1,436 +1,447 @@
1
  <?php
2
  /**
3
- * s2Member's PayPal IPN handler (inner processing routine).
4
- *
5
- * Copyright: © 2009-2011
6
- * {@link http://www.websharks-inc.com/ WebSharks, Inc.}
7
- * (coded in the USA)
8
- *
9
- * Released under the terms of the GNU General Public License.
10
- * You should have received a copy of the GNU General Public License,
11
- * along with this software. In the main directory, see: /licensing/
12
- * If not, see: {@link http://www.gnu.org/licenses/}.
13
- *
14
- * @package s2Member\PayPal
15
- * @since 110720
16
- */
17
- if(realpath(__FILE__) === realpath($_SERVER["SCRIPT_FILENAME"]))
18
- exit("Do not access this file directly.");
19
-
20
- if(!class_exists("c_ws_plugin__s2member_paypal_notify_in_subscr_or_rp_eots_w_level"))
 
 
 
 
 
 
 
 
21
  {
22
  /**
23
- * s2Member's PayPal IPN handler (inner processing routine).
24
- *
25
- * @package s2Member\PayPal
26
- * @since 110720
27
- */
28
- class c_ws_plugin__s2member_paypal_notify_in_subscr_or_rp_eots_w_level
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
29
  {
30
- /**
31
- * s2Member's PayPal IPN handler (inner processing routine).
32
- *
33
- * @package s2Member\PayPal
34
- * @since 110720
35
- *
36
- * @param array $vars Required. An array of defined variables passed by {@link s2Member\PayPal\c_ws_plugin__s2member_paypal_notify_in::paypal_notify()}.
37
- * @return array|bool The original ``$paypal`` array passed in (extracted) from ``$vars``, or false when conditions do NOT apply.
38
- */
39
- public static function cp($vars = array()) // Conditional phase for ``c_ws_plugin__s2member_paypal_notify_in::paypal_notify()``.
 
 
 
 
 
 
 
 
 
 
40
  {
41
- extract($vars, EXTR_OVERWRITE | EXTR_REFS); // Extract all vars passed in from: ``c_ws_plugin__s2member_paypal_notify_in::paypal_notify()``.
42
-
43
- if(((!empty($paypal["txn_type"]) && preg_match("/^(subscr_eot|recurring_payment_expired|recurring_payment_suspended_due_to_max_failed_payment)$/i", $paypal["txn_type"]) && ($recurring = true))
44
- || (!empty($paypal["txn_type"]) && preg_match("/^recurring_payment_profile_cancel$/i", $paypal["txn_type"]) && !empty($paypal["initial_payment_status"]) && preg_match("/^failed$/i", $paypal["initial_payment_status"]) && ($recurring = true))
45
- || (!empty($paypal["txn_type"]) && preg_match("/^new_case$/i", $paypal["txn_type"]) && !empty($paypal["case_type"]) && preg_match("/^chargeback$/i", $paypal["case_type"]) && !($recurring = false)) // Seeking this for future compatibility.
46
- || (!empty($paypal["payment_status"]) && preg_match("/^(refunded|reversed|reversal)$/i", $paypal["payment_status"]) && !($recurring = false))) // The `txn_type` is irrelevant in all of these payment statuses: `refunded|reversed|reversal`.
47
- && (!empty($paypal["subscr_id"]) || ($paypal["subscr_id"] = c_ws_plugin__s2member_paypal_utilities::paypal_pro_subscr_id($paypal)) || (!empty($paypal["parent_txn_id"]) && ($paypal["subscr_id"] = $paypal["parent_txn_id"]))) // Other MUST haves.
48
- && (!empty($paypal["period1"]) || ($paypal["period1"] = c_ws_plugin__s2member_paypal_utilities::paypal_pro_period1($paypal, false)) || empty($recurring) || ($paypal["period1"] = c_ws_plugin__s2member_utils_users::get_user_ipn_signup_var("period1", false, $paypal["subscr_id"])) || ($paypal["period1"] = "0 D"))
49
- && (!empty($paypal["period3"]) || ($paypal["period3"] = c_ws_plugin__s2member_paypal_utilities::paypal_pro_period3($paypal, false)) || empty($recurring) || ($paypal["period3"] = c_ws_plugin__s2member_utils_users::get_user_ipn_signup_var("period3", false, $paypal["subscr_id"])) || ($paypal["period3"] = "1 D"))
50
- && ((!empty($paypal["item_number"]) || ($paypal["item_number"] = c_ws_plugin__s2member_paypal_utilities::paypal_pro_item_number($paypal)) || ($paypal["item_number"] = c_ws_plugin__s2member_utils_users::get_user_ipn_signup_var("item_number", false, $paypal["subscr_id"])) || ($paypal["item_number"] = "1")) && preg_match($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["membership_item_number_w_level_regex"], $paypal["item_number"]))
51
- && (!empty($paypal["item_name"]) || ($paypal["item_name"] = c_ws_plugin__s2member_paypal_utilities::paypal_pro_item_name($paypal)) || ($paypal["item_name"] = c_ws_plugin__s2member_utils_users::get_user_ipn_signup_var("item_name", false, $paypal["subscr_id"])) || ($paypal["item_name"] = $_SERVER["HTTP_HOST"]))
52
- && (!empty($paypal["payer_email"]) || ($paypal["payer_email"] = c_ws_plugin__s2member_utils_users::get_user_ipn_signup_var("payer_email", false, $paypal["subscr_id"])) || ($paypal["payer_email"] = c_ws_plugin__s2member_utils_users::get_user_email_with($paypal["subscr_id"])))
53
- && (!empty($paypal["subscr_baid"]) || ($paypal["subscr_baid"] = $paypal["subscr_id"]))
54
- && (!empty($paypal["subscr_cid"]) || ($paypal["subscr_cid"] = $paypal["subscr_id"])))
55
- {
56
- foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;
57
- do_action("ws_plugin__s2member_during_paypal_notify_before_subscr_eot", get_defined_vars());
58
- unset($__refs, $__v);
59
 
60
- if(!get_transient($transient_ipn = "s2m_ipn_".md5("s2member_transient_".$_paypal_s)) && set_transient($transient_ipn, time(), 31556926 * 10))
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
61
  {
62
- $is_refund = (preg_match("/^refunded$/i", $paypal["payment_status"]) && !empty($paypal["parent_txn_id"]));
63
- $is_reversal = (preg_match("/^(reversed|reversal)$/i", $paypal["payment_status"]) && !empty($paypal["parent_txn_id"]));
64
- $is_reversal = (!$is_reversal) ? (preg_match("/^new_case$/i", $paypal["txn_type"]) && preg_match("/^chargeback$/i", $paypal["case_type"])) : $is_reversal;
65
- $is_refund_or_reversal = ($is_refund || $is_reversal); // If either of the previous tests above evaluated to true; then it's obviously a Refund and/or a Reversal.
66
- $is_partial_refund = // Partial refund detection. All refunds processed against Subscriptions are considered partials. Full refunds occur only against Buy Now transactions.
67
- (!$is_refund || (!empty($paypal["mc_gross"]) && ($original_txn_type = c_ws_plugin__s2member_utils_users::get_user_ipn_signup_var("txn_type", FALSE, $paypal["subscr_id"])) === "web_accept"
68
- && ($original_mc_gross = c_ws_plugin__s2member_utils_users::get_user_ipn_signup_var("mc_gross", FALSE, $paypal["subscr_id"])) <= abs($paypal["mc_gross"]))) ? FALSE : TRUE;
69
- $is_delayed_eot = (!$is_refund_or_reversal && preg_match("/^(subscr_eot|recurring_payment_expired)$/i", $paypal["txn_type"]) && preg_match("/^I-/i", $paypal["subscr_id"]));
70
-
71
- if($is_refund_or_reversal)
72
- $paypal["s2member_log"][] = "s2Member `txn_type` identified as ".($identified_as = "( `[empty or irrelevant]` ) w/ `payment_status` ( `refunded|reversed|reversal` ) - or - `new_case` w/ `case_type` ( `chargeback` )").".";
73
- else $paypal["s2member_log"][] = "s2Member `txn_type` identified as ".($identified_as = "( `subscr_eot|recurring_payment_expired|recurring_payment_suspended_due_to_max_failed_payment` ) - or - `recurring_payment_profile_cancel` w/ `initial_payment_status` ( `failed` )").".";
74
-
75
- if(empty($_REQUEST["s2member_paypal_proxy"])) // Only on true PayPal IPNs; e.g. we can bypass this on proxied IPNs.
76
- {
77
- $paypal["s2member_log"][] = "Sleeping for 10 seconds. Waiting for a possible ( `subscr_signup|subscr_modify|recurring_payment_profile_created` ).";
78
- sleep(10); // Sleep here for a moment. PayPal sometimes sends a subscr_eot before the subscr_signup, subscr_modify.
79
- $paypal["s2member_log"][] = "Awake. It's ".date("D M j, Y g:i:s a T").". s2Member `txn_type` identified as ".$identified_as.".";
80
- }
81
- $paypal["ip"] = (preg_match("/ip address/i", $paypal["option_name2"]) && $paypal["option_selection2"]) ? $paypal["option_selection2"] : "";
82
- $paypal["ip"] = (!$paypal["ip"] && preg_match("/^[a-z0-9]+~[0-9\.]+$/i", $paypal["invoice"])) ? preg_replace("/^[a-z0-9]+~/i", "", $paypal["invoice"]) : $paypal["ip"];
83
-
84
- if(($user_id = c_ws_plugin__s2member_utils_users::get_user_id_with($paypal["subscr_id"])) && is_object($user = new WP_User($user_id)) && !empty($user->ID))
85
- {
86
- $fields = get_user_option("s2member_custom_fields", $user_id); // These will be needed below.
87
- $user_reg_ip = get_user_option("s2member_registration_ip", $user_id); // Needed below.
88
- $user_reg_ip = $paypal["ip"] = ($user_reg_ip) ? $user_reg_ip : $paypal["ip"];
89
-
90
- if((!$is_refund_or_reversal && !$is_delayed_eot && !get_user_option("s2member_auto_eot_time", $user_id))
91
- || ($is_refund_or_reversal && $is_partial_refund && $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["triggers_immediate_eot"] === "refunds,partial_refunds,reversals")
92
- || ($is_refund_or_reversal && !$is_partial_refund && $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["triggers_immediate_eot"] === "refunds,reversals")
93
- || ($is_refund && !$is_partial_refund && $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["triggers_immediate_eot"] === "refunds")
94
- || ($is_reversal && $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["triggers_immediate_eot"] === "reversals"))
95
- {
96
- if(!$user->has_cap("administrator")) // Do NOT process this routine on Administrators.
97
- {
98
- if($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["auto_eot_system_enabled"]) // EOT enabled?
99
- {
100
- if($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["membership_eot_behavior"] === "demote")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
101
  {
102
- $processing = $during = true; // Yes, we ARE processing this.
103
-
104
- $eot_del_type = ($is_refund_or_reversal) ? // Set EOT/Del type.
105
- "ipn-refund-reversal-demotion" : "ipn-cancellation-expiration-demotion";
106
-
107
- $demotion_role = c_ws_plugin__s2member_option_forces::force_demotion_role("subscriber");
108
- $existing_role = c_ws_plugin__s2member_user_access::user_access_role($user);
109
-
110
- foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;
111
- do_action("ws_plugin__s2member_during_paypal_notify_during_subscr_eot_before_demote", get_defined_vars());
112
- do_action("ws_plugin__s2member_during_collective_mods", $user_id, get_defined_vars(), $eot_del_type, "modification", $demotion_role);
113
- do_action("ws_plugin__s2member_during_collective_eots", $user_id, get_defined_vars(), $eot_del_type, "modification");
114
- unset($__refs, $__v);
115
-
116
- if($existing_role !== $demotion_role) // Only if NOT the existing Role.
117
- $user->set_role($demotion_role); // Give User the demotion Role.
118
-
119
- if(apply_filters("ws_plugin__s2member_remove_ccaps_during_eot_events",
120
- ((bool)$GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["eots_remove_ccaps"] || $is_refund_or_reversal), get_defined_vars()))
121
- foreach($user->allcaps as $cap => $cap_enabled)
122
- if(preg_match("/^access_s2member_ccap_/", $cap))
123
- $user->remove_cap($ccap = $cap);
124
-
125
- delete_user_option($user_id, "s2member_custom");
126
- delete_user_option($user_id, "s2member_subscr_id");
127
- delete_user_option($user_id, "s2member_subscr_baid");
128
- delete_user_option($user_id, "s2member_subscr_cid");
129
- delete_user_option($user_id, "s2member_subscr_gateway");
130
-
131
- delete_user_option($user_id, "s2member_ipn_signup_vars");
132
- if(!apply_filters("ws_plugin__s2member_preserve_paid_registration_times", true, get_defined_vars()))
133
- delete_user_option($user_id, "s2member_paid_registration_times");
134
-
135
- delete_user_option($user_id, "s2member_last_status_scan");
136
- delete_user_option($user_id, "s2member_first_payment_txn_id");
137
- delete_user_option($user_id, "s2member_last_payment_time");
138
- delete_user_option($user_id, "s2member_auto_eot_time");
139
-
140
- delete_user_option($user_id, "s2member_file_download_access_log");
141
-
142
- c_ws_plugin__s2member_user_notes::append_user_notes($user_id, "Demoted by s2Member: ".date("D M j, Y g:i a T"));
143
- c_ws_plugin__s2member_user_notes::append_user_notes ($user_id, "Paid Subscr. ID @ time of demotion: ".$paypal["subscr_gateway"]." -› ".$paypal["subscr_id"]);
144
-
145
- $paypal["s2member_log"][] = "Member Level/Capabilities demoted to: ".ucwords(preg_replace("/_/", " ", $demotion_role)).".";
146
-
147
- if($processing && $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["eot_del_notification_urls"] && is_array($cv = preg_split("/\|/", $paypal["custom"])))
148
- {
149
- foreach(preg_split("/[\r\n\t]+/", $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["eot_del_notification_urls"]) as $url) // Handle EOT Notifications.
150
-
151
- if(($url = preg_replace("/%%cv([0-9]+)%%/ei", 'urlencode(trim(@$cv[$1]))', $url)) && ($url = preg_replace("/%%eot_del_type%%/i", c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($eot_del_type)), $url)) && ($url = preg_replace("/%%subscr_id%%/i", c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($paypal["subscr_id"])), $url)))
152
- if(($url = preg_replace("/%%subscr_baid%%/i", c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($paypal["subscr_baid"])), $url)) && ($url = preg_replace("/%%subscr_cid%%/i", c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($paypal["subscr_cid"])), $url)))
153
- if(($url = preg_replace("/%%user_first_name%%/i", c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($user->first_name)), $url)) && ($url = preg_replace("/%%user_last_name%%/i", c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($user->last_name)), $url)))
154
- if(($url = preg_replace("/%%user_full_name%%/i", c_ws_plugin__s2member_utils_strings::esc_refs(urlencode(trim($user->first_name." ".$user->last_name))), $url)))
155
- if(($url = preg_replace("/%%user_email%%/i", c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($user->user_email)), $url)))
156
- if(($url = preg_replace("/%%user_login%%/i", c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($user->user_login)), $url)))
157
- if(($url = preg_replace("/%%user_ip%%/i", c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($user_reg_ip)), $url)))
158
- if(($url = preg_replace("/%%user_id%%/i", c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($user_id)), $url)))
159
- {
160
- if(is_array($fields) && !empty($fields))
161
- foreach($fields as $var => $val) // Custom Registration/Profile Fields.
162
- if(!($url = preg_replace("/%%".preg_quote($var, "/")."%%/i", c_ws_plugin__s2member_utils_strings::esc_refs(urlencode(maybe_serialize($val))), $url)))
163
- break;
164
-
165
- if(($url = trim(preg_replace("/%%(.+?)%%/i", "", $url))))
166
- c_ws_plugin__s2member_utils_urls::remote($url);
167
- }
168
- $paypal["s2member_log"][] = "EOT/Deletion Notification URLs have been processed.";
169
- }
170
- if($processing && $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["eot_del_notification_recipients"] && is_array($cv = preg_split("/\|/", $paypal["custom"])))
171
- {
172
- $msg = $sbj = "(s2Member / API Notification Email) - EOT/Deletion";
173
- $msg .= "\n\n"; // Spacing in the message body.
174
-
175
- $msg .= "eot_del_type: %%eot_del_type%%\n";
176
- $msg .= "subscr_id: %%subscr_id%%\n";
177
- $msg .= "subscr_baid: %%subscr_baid%%\n";
178
- $msg .= "subscr_cid: %%subscr_cid%%\n";
179
- $msg .= "user_first_name: %%user_first_name%%\n";
180
- $msg .= "user_last_name: %%user_last_name%%\n";
181
- $msg .= "user_full_name: %%user_full_name%%\n";
182
- $msg .= "user_email: %%user_email%%\n";
183
- $msg .= "user_login: %%user_login%%\n";
184
- $msg .= "user_ip: %%user_ip%%\n";
185
- $msg .= "user_id: %%user_id%%\n";
186
-
187
- if(is_array($fields) && !empty($fields))
188
- foreach($fields as $var => $val)
189
- $msg .= $var.": %%".$var."%%\n";
190
-
191
- $msg .= "cv0: %%cv0%%\n";
192
- $msg .= "cv1: %%cv1%%\n";
193
- $msg .= "cv2: %%cv2%%\n";
194
- $msg .= "cv3: %%cv3%%\n";
195
- $msg .= "cv4: %%cv4%%\n";
196
- $msg .= "cv5: %%cv5%%\n";
197
- $msg .= "cv6: %%cv6%%\n";
198
- $msg .= "cv7: %%cv7%%\n";
199
- $msg .= "cv8: %%cv8%%\n";
200
- $msg .= "cv9: %%cv9%%";
201
-
202
- if(($msg = preg_replace("/%%cv([0-9]+)%%/ei", 'trim(@$cv[$1])', $msg)) && ($msg = preg_replace("/%%eot_del_type%%/i", c_ws_plugin__s2member_utils_strings::esc_refs($eot_del_type), $msg)) && ($msg = preg_replace("/%%subscr_id%%/i", c_ws_plugin__s2member_utils_strings::esc_refs($paypal["subscr_id"]), $msg)))
203
- if(($msg = preg_replace("/%%subscr_baid%%/i", c_ws_plugin__s2member_utils_strings::esc_refs($paypal["subscr_baid"]), $msg)) && ($msg = preg_replace("/%%subscr_cid%%/i", c_ws_plugin__s2member_utils_strings::esc_refs($paypal["subscr_cid"]), $msg)))
204
- if(($msg = preg_replace("/%%user_first_name%%/i", c_ws_plugin__s2member_utils_strings::esc_refs($user->first_name), $msg)) && ($msg = preg_replace("/%%user_last_name%%/i", c_ws_plugin__s2member_utils_strings::esc_refs($user->last_name), $msg)))
205
- if(($msg = preg_replace("/%%user_full_name%%/i", c_ws_plugin__s2member_utils_strings::esc_refs(trim($user->first_name." ".$user->last_name)), $msg)))
206
- if(($msg = preg_replace("/%%user_email%%/i", c_ws_plugin__s2member_utils_strings::esc_refs($user->user_email), $msg)))
207
- if(($msg = preg_replace("/%%user_login%%/i", c_ws_plugin__s2member_utils_strings::esc_refs($user->user_login), $msg)))
208
- if(($msg = preg_replace("/%%user_ip%%/i", c_ws_plugin__s2member_utils_strings::esc_refs($user_reg_ip), $msg)))
209
- if(($msg = preg_replace("/%%user_id%%/i", c_ws_plugin__s2member_utils_strings::esc_refs($user_id), $msg)))
210
- {
211
- if(is_array($fields) && !empty($fields))
212
- foreach($fields as $var => $val) // Custom Registration/Profile Fields.
213
- if(!($msg = preg_replace("/%%".preg_quote($var, "/")."%%/i", c_ws_plugin__s2member_utils_strings::esc_refs(maybe_serialize($val)), $msg)))
214
- break;
215
-
216
- if($sbj && ($msg = trim(preg_replace("/%%(.+?)%%/i", "", $msg)))) // Still have a ``$sbj`` and a ``$msg``?
217
-
218
- foreach(c_ws_plugin__s2member_utils_strings::parse_emails($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["eot_del_notification_recipients"]) as $recipient)
219
- wp_mail($recipient, apply_filters("ws_plugin__s2member_eot_del_notification_email_sbj", $sbj, get_defined_vars()), apply_filters("ws_plugin__s2member_eot_del_notification_email_msg", $msg, get_defined_vars()), "Content-Type: text/plain; charset=UTF-8");
220
- }
221
- $paypal["s2member_log"][] = "EOT/Deletion Notification Emails have been processed.";
222
- }
223
- foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;
224
- do_action("ws_plugin__s2member_during_paypal_notify_during_subscr_eot_demote", get_defined_vars());
225
- unset($__refs, $__v);
226
  }
227
- else if($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["membership_eot_behavior"] === "delete")
228
- {
229
- $processing = $during = true; // Yes, we ARE processing this.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
230
 
231
- $eot_del_type = $GLOBALS["ws_plugin__s2member_eot_del_type"] = // Configure EOT/Del type.
232
- ($is_refund_or_reversal) ? "ipn-refund-reversal-deletion" : "ipn-cancellation-expiration-deletion";
233
 
234
- foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;
235
- do_action("ws_plugin__s2member_during_paypal_notify_during_subscr_eot_before_delete", get_defined_vars());
236
- do_action("ws_plugin__s2member_during_collective_eots", $user_id, get_defined_vars(), $eot_del_type, "removal-deletion");
237
- unset($__refs, $__v);
238
 
239
- if(is_multisite()) // Multisite does NOT actually delete; ONLY removes.
240
- {
241
- remove_user_from_blog($user_id, $current_blog->blog_id);
242
- // This will automatically trigger `eot_del_notification_urls` as well.
243
- c_ws_plugin__s2member_user_deletions::handle_ms_user_deletions($user_id, $current_blog->blog_id, "s2says");
244
- }
245
- else // Otherwise, we can actually delete them.
246
- // This will automatically trigger `eot_del_notification_urls` as well.
247
- wp_delete_user($user_id); // `c_ws_plugin__s2member_user_deletions::handle_user_deletions()`
248
 
249
- $paypal["s2member_log"][] = "This Member's account has been ".((is_multisite()) ? "removed" : "deleted").".";
250
 
251
- $paypal["s2member_log"][] = "EOT/Deletion Notification URLs have been processed.";
252
 
253
- foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;
254
- do_action("ws_plugin__s2member_during_paypal_notify_during_subscr_eot_delete", get_defined_vars());
255
- unset($__refs, $__v);
256
- }
257
- foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;
258
- do_action("ws_plugin__s2member_during_paypal_notify_during_subscr_eot", get_defined_vars());
259
- unset($__refs, $__v);
260
- }
261
- else // Otherwise, treat this as if it were a cancellation. EOTs are currently disabled.
262
- {
263
- $processing = $during = true; // Yes, we ARE processing this.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
264
 
265
- update_user_option($user_id, "s2member_auto_eot_time", ($auto_eot_time = strtotime("now")));
 
 
 
266
 
267
- $paypal["s2member_log"][] = "Auto-EOT is currently disabled. Skipping EOT (demote|delete), for now.";
268
- $paypal["s2member_log"][] = "Recording the Auto-EOT Time for this Member's account: ".date("D M j, Y g:i a T", $auto_eot_time);
269
 
270
- foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;
271
- do_action("ws_plugin__s2member_during_paypal_notify_during_subscr_eot_disabled", get_defined_vars());
272
- unset($__refs, $__v);
273
- }
274
- }
275
- else $paypal["s2member_log"][] = "Unable to (demote|delete) Member. The existing User ID is associated with an Administrator. Stopping here. Otherwise, an Administrator could lose access.";
276
- }
277
- else if($is_delayed_eot && !get_user_option("s2member_auto_eot_time", $user_id))
278
- {
279
- if(!$user->has_cap("administrator")) // Do NOT process this routine on Administrators.
280
- {
281
- $processing = $during = true; // Yes, we ARE processing this.
282
-
283
- $auto_eot_time = c_ws_plugin__s2member_utils_time::auto_eot_time($user_id, $paypal["period1"], $paypal["period3"], "", time());
284
- /* We assume the last payment was today, because this is how newer PayPal accounts function with respect to EOT handling.
285
- Newer PayPal accounts ( i.e. Subscription IDs starting with `I-`, will have their EOT triggered upon the last payment. */
286
- update_user_option($user_id, "s2member_auto_eot_time", $auto_eot_time); // s2Member will follow-up on this later.
287
-
288
- $paypal["s2member_log"][] = "Auto-EOT Time for this account (delayed), set to: ".date("D M j, Y g:i a T", $auto_eot_time);
289
-
290
- foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;
291
- do_action("ws_plugin__s2member_during_paypal_notify_during_subscr_eot_delayed", get_defined_vars());
292
- unset($__refs, $__v);
293
- }
294
- else $paypal["s2member_log"][] = "Ignoring Delayed EOT. The existing User ID is associated with an Administrator. Stopping here. Otherwise, an Administrator could lose access.";
295
- }
296
- else if(!$is_refund_or_reversal || $is_delayed_eot)
297
- $paypal["s2member_log"][] = "Skipping (demote|delete) Member, for now. An Auto-EOT Time is already set for this account. When an Auto-EOT Time has been recorded, s2Member will handle EOT (demote|delete) events using it's own Auto-EOT System - internally.";
298
-
299
- else if($is_refund && $is_partial_refund)
300
- $paypal["s2member_log"][] = "Skipping (demote|delete) Member. Your configuration dictates that s2Member should NOT take any immediate action on an EOT associated with a Partial Refund. An s2Member API Notification will still be processed however.";
301
-
302
- else if($is_refund && !$is_partial_refund)
303
- $paypal["s2member_log"][] = "Skipping (demote|delete) Member. Your configuration dictates that s2Member should NOT take any immediate action on an EOT associated with a Full Refund. An s2Member API Notification will still be processed however.";
304
-
305
- else if($is_reversal)
306
- $paypal["s2member_log"][] = "Skipping (demote|delete) Member. Your configuration dictates that s2Member should NOT take any immediate action on an EOT associated with a Chargeback Reversal. An s2Member API Notification will still be processed however.";
307
- }
308
- else if($is_delayed_eot) // Otherwise, we need to re-generate/store this IPN into a Transient Queue. Then re-process it on registration.
309
- {
310
- $paypal["s2member_log"][] = "Skipping this IPN response, for now. The Subscr. ID is not associated with a registered Member.";
311
-
312
- $ipn = array("txn_type" => "subscr_eot"); // Create a simulated IPN response for txn_type=subscr_eot.
313
-
314
- foreach($paypal as $var => $val)
315
- if(in_array($var, array("subscr_gateway", "subscr_id", "subscr_baid", "subscr_cid", "custom", "invoice", "payer_email", "first_name", "last_name", "item_name", "item_number", /* Exclude; might be defaults. "period1", "period3", */ "option_name1", "option_selection1", "option_name2", "option_selection2")))
316
- $ipn[$var] = $val;
317
-
318
- $paypal["s2member_log"][] = "Re-generating. This IPN will go into a Transient Queue; and be re-processed during registration.";
319
-
320
- set_transient("s2m_".md5("s2member_transient_ipn_subscr_eot_".$paypal["subscr_id"]), $ipn, 43200);
321
- }
322
- else $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 processed through another IPN, removed manually by a Site Administrator, or by s2Member's Auto-EOT Sys.";
323
- /*
324
- Refunds and chargeback reversals. This is excluded from the processing check, because a Member *could* have already been (demoted|deleted).
325
- In other words, s2Member sends `Refund/Reversal` Notifications ANYTIME a Refund/Reversal occurs; even if s2Member did not process it otherwise.
326
- Since this routine ignores the processing check, it is *possible* that Refund/Reversal Notification URLs will be contacted more than once.
327
- If you're writing scripts that depend on Refund/Reversal Notifications, please keep this in mind.
328
- */
329
- if($is_refund_or_reversal) // Previously assigned as a quick method of Refund/Reversal detection.
330
- {
331
- $fields = ($user_id) ? get_user_option("s2member_custom_fields", $user_id) : array(); // These will be needed below.
332
- $user_reg_ip = ($user_id) ? get_user_option("s2member_registration_ip", $user_id) : ""; // Needed below.
333
- $user_reg_ip = $paypal["ip"] = ($user_reg_ip) ? $user_reg_ip : $paypal["ip"]; // Now merge conditionally.
334
-
335
- if($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["ref_rev_notification_urls"] && is_array($cv = preg_split("/\|/", $paypal["custom"])))
336
- {
337
- foreach(preg_split("/[\r\n\t]+/", $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["ref_rev_notification_urls"]) as $url)
338
-
339
- if(($url = preg_replace("/%%cv([0-9]+)%%/ei", 'urlencode(trim(@$cv[$1]))', $url)) && ($url = preg_replace("/%%subscr_id%%/i", c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($paypal["subscr_id"])), $url)) && ($url = preg_replace("/%%parent_txn_id%%/i", c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($paypal["parent_txn_id"])), $url)))
340
- if(($url = preg_replace("/%%subscr_baid%%/i", c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($paypal["subscr_baid"])), $url)) && ($url = preg_replace("/%%subscr_cid%%/i", c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($paypal["subscr_cid"])), $url)))
341
- if(($url = preg_replace("/%%item_number%%/i", c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($paypal["item_number"])), $url)) && ($url = preg_replace("/%%item_name%%/i", c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($paypal["item_name"])), $url)))
342
- if(($url = preg_replace("/%%-amount%%/i", c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($paypal["mc_gross"])), $url)) && ($url = preg_replace("/%%-fee%%/i", c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($paypal["mc_fee"])), $url)))
343
- if(($url = preg_replace("/%%first_name%%/i", c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($paypal["first_name"])), $url)) && ($url = preg_replace("/%%last_name%%/i", c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($paypal["last_name"])), $url)))
344
- if(($url = preg_replace("/%%full_name%%/i", c_ws_plugin__s2member_utils_strings::esc_refs(urlencode(trim($paypal["first_name"]." ".$paypal["last_name"]))), $url)))
345
- if(($url = preg_replace("/%%payer_email%%/i", c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($paypal["payer_email"])), $url)))
346
- if(($url = preg_replace("/%%user_ip%%/i", c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($user_reg_ip)), $url)))
347
- if(($url = preg_replace("/%%user_id%%/i", c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($user_id)), $url)))
348
- {
349
- if(is_array($fields) && !empty($fields))
350
- foreach($fields as $var => $val) // Custom Registration/Profile Fields.
351
- if(!($url = preg_replace("/%%".preg_quote($var, "/")."%%/i", c_ws_plugin__s2member_utils_strings::esc_refs(urlencode(maybe_serialize($val))), $url)))
352
- break;
353
-
354
- if(($url = trim(preg_replace("/%%(.+?)%%/i", "", $url))))
355
- c_ws_plugin__s2member_utils_urls::remote($url);
356
- }
357
- $paypal["s2member_log"][] = "Refund/Reversal Notification URLs have been processed.";
358
- }
359
- if($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["ref_rev_notification_recipients"] && is_array($cv = preg_split("/\|/", $paypal["custom"])))
360
- {
361
- $msg = $sbj = "(s2Member / API Notification Email) - Refund/Reversal";
362
- $msg .= "\n\n"; // Spacing in the message body.
363
-
364
- $msg .= "subscr_id: %%subscr_id%%\n";
365
- $msg .= "subscr_baid: %%subscr_baid%%\n";
366
- $msg .= "subscr_cid: %%subscr_cid%%\n";
367
- $msg .= "parent_txn_id: %%parent_txn_id%%\n";
368
- $msg .= "item_number: %%item_number%%\n";
369
- $msg .= "item_name: %%item_name%%\n";
370
- $msg .= "-amount: %%-amount%%\n";
371
- $msg .= "-fee: %%-fee%%\n";
372
- $msg .= "first_name: %%first_name%%\n";
373
- $msg .= "last_name: %%last_name%%\n";
374
- $msg .= "full_name: %%full_name%%\n";
375
- $msg .= "payer_email: %%payer_email%%\n";
376
- $msg .= "user_ip: %%user_ip%%\n";
377
- $msg .= "user_id: %%user_id%%\n";
378
-
379
- if(is_array($fields) && !empty($fields))
380
- foreach($fields as $var => $val)
381
- $msg .= $var.": %%".$var."%%\n";
382
-
383
- $msg .= "cv0: %%cv0%%\n";
384
- $msg .= "cv1: %%cv1%%\n";
385
- $msg .= "cv2: %%cv2%%\n";
386
- $msg .= "cv3: %%cv3%%\n";
387
- $msg .= "cv4: %%cv4%%\n";
388
- $msg .= "cv5: %%cv5%%\n";
389
- $msg .= "cv6: %%cv6%%\n";
390
- $msg .= "cv7: %%cv7%%\n";
391
- $msg .= "cv8: %%cv8%%\n";
392
- $msg .= "cv9: %%cv9%%";
393
-
394
- if(($msg = preg_replace("/%%cv([0-9]+)%%/ei", 'trim(@$cv[$1])', $msg)) && ($msg = preg_replace("/%%subscr_id%%/i", c_ws_plugin__s2member_utils_strings::esc_refs($paypal["subscr_id"]), $msg)) && ($msg = preg_replace("/%%parent_txn_id%%/i", c_ws_plugin__s2member_utils_strings::esc_refs($paypal["parent_txn_id"]), $msg)))
395
- if(($msg = preg_replace("/%%subscr_baid%%/i", c_ws_plugin__s2member_utils_strings::esc_refs($paypal["subscr_baid"]), $msg)) && ($msg = preg_replace("/%%subscr_cid%%/i", c_ws_plugin__s2member_utils_strings::esc_refs($paypal["subscr_cid"]), $msg)))
396
- if(($msg = preg_replace("/%%item_number%%/i", c_ws_plugin__s2member_utils_strings::esc_refs($paypal["item_number"]), $msg)) && ($msg = preg_replace("/%%item_name%%/i", c_ws_plugin__s2member_utils_strings::esc_refs($paypal["item_name"]), $msg)))
397
- if(($msg = preg_replace("/%%-amount%%/i", c_ws_plugin__s2member_utils_strings::esc_refs($paypal["mc_gross"]), $msg)) && ($msg = preg_replace("/%%-fee%%/i", c_ws_plugin__s2member_utils_strings::esc_refs($paypal["mc_fee"]), $msg)))
398
- if(($msg = preg_replace("/%%first_name%%/i", c_ws_plugin__s2member_utils_strings::esc_refs($paypal["first_name"]), $msg)) && ($msg = preg_replace("/%%last_name%%/i", c_ws_plugin__s2member_utils_strings::esc_refs($paypal["last_name"]), $msg)))
399
- if(($msg = preg_replace("/%%full_name%%/i", c_ws_plugin__s2member_utils_strings::esc_refs(trim($paypal["first_name"]." ".$paypal["last_name"])), $msg)))
400
- if(($msg = preg_replace("/%%payer_email%%/i", c_ws_plugin__s2member_utils_strings::esc_refs($paypal["payer_email"]), $msg)))
401
- if(($msg = preg_replace("/%%user_ip%%/i", c_ws_plugin__s2member_utils_strings::esc_refs($user_reg_ip), $msg)))
402
- if(($msg = preg_replace("/%%user_id%%/i", c_ws_plugin__s2member_utils_strings::esc_refs($user_id), $msg)))
403
- {
404
- if(is_array($fields) && !empty($fields))
405
- foreach($fields as $var => $val) // Custom Registration/Profile Fields.
406
- if(!($msg = preg_replace("/%%".preg_quote($var, "/")."%%/i", c_ws_plugin__s2member_utils_strings::esc_refs(maybe_serialize($val)), $msg)))
407
- break;
408
-
409
- if($sbj && ($msg = trim(preg_replace("/%%(.+?)%%/i", "", $msg)))) // Still have a ``$sbj`` and a ``$msg``?
410
-
411
- foreach(c_ws_plugin__s2member_utils_strings::parse_emails($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["ref_rev_notification_recipients"]) as $recipient)
412
- wp_mail($recipient, apply_filters("ws_plugin__s2member_ref_rev_notification_email_sbj", $sbj, get_defined_vars()), apply_filters("ws_plugin__s2member_ref_rev_notification_email_msg", $msg, get_defined_vars()), "Content-Type: text/plain; charset=UTF-8");
413
- }
414
- $paypal["s2member_log"][] = "Refund/Reversal Notification Emails have been processed.";
415
- }
416
- foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;
417
- do_action("ws_plugin__s2member_during_paypal_notify_during_subscr_eot_refund_reversal", get_defined_vars());
418
- unset($__refs, $__v);
419
- }
420
- }
421
- else // Else, this is a duplicate IPN. Must stop here.
422
- {
423
- $paypal["s2member_log"][] = "Not processing. Duplicate IPN.";
424
- $paypal["s2member_log"][] = "s2Member `txn_type` identified as a type of EOT.";
425
- $paypal["s2member_log"][] = "Duplicate IPN. Already processed. This IPN will be ignored.";
426
- }
427
- foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;
428
- do_action("ws_plugin__s2member_during_paypal_notify_after_subscr_eot", get_defined_vars());
429
  unset($__refs, $__v);
430
-
431
- return apply_filters("c_ws_plugin__s2member_paypal_notify_in_subscr_or_rp_eots_w_level", $paypal, get_defined_vars());
432
  }
433
- else return apply_filters("c_ws_plugin__s2member_paypal_notify_in_subscr_or_rp_eots_w_level", false, get_defined_vars());
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
434
  }
 
 
 
 
 
 
 
 
 
 
 
 
435
  }
436
- }
 
 
 
1
  <?php
2
  /**
3
+ * s2Member's PayPal IPN handler (inner processing routine).
4
+ *
5
+ * Copyright: © 2009-2011
6
+ * {@link http://www.websharks-inc.com/ WebSharks, Inc.}
7
+ * (coded in the USA)
8
+ *
9
+ * Released under the terms of the GNU General Public License.
10
+ * You should have received a copy of the GNU General Public License,
11
+ * along with this software. In the main directory, see: /licensing/
12
+ * If not, see: {@link http://www.gnu.org/licenses/}.
13
+ *
14
+ * @package s2Member\PayPal
15
+ * @since 110720
16
+ */
17
+ if(realpath(__FILE__) === realpath($_SERVER['SCRIPT_FILENAME']))
18
+ exit('Do not access this file directly.');
19
+
20
+ if(!class_exists('c_ws_plugin__s2member_paypal_notify_in_subscr_or_rp_eots_w_level'))
21
+ {
22
+ /**
23
+ * s2Member's PayPal IPN handler (inner processing routine).
24
+ *
25
+ * @package s2Member\PayPal
26
+ * @since 110720
27
+ */
28
+ class c_ws_plugin__s2member_paypal_notify_in_subscr_or_rp_eots_w_level
29
  {
30
  /**
31
+ * s2Member's PayPal IPN handler (inner processing routine).
32
+ *
33
+ * @package s2Member\PayPal
34
+ * @since 110720
35
+ *
36
+ * @param array $vars Required. An array of defined variables passed by {@link s2Member\PayPal\c_ws_plugin__s2member_paypal_notify_in::paypal_notify()}.
37
+ *
38
+ * @return array|bool The original ``$paypal`` array passed in (extracted) from ``$vars``, or false when conditions do NOT apply.
39
+ */
40
+ public static function cp($vars = array()) // Conditional phase for ``c_ws_plugin__s2member_paypal_notify_in::paypal_notify()``.
41
+ {
42
+ extract($vars, EXTR_OVERWRITE | EXTR_REFS); // Extract all vars passed in from: ``c_ws_plugin__s2member_paypal_notify_in::paypal_notify()``.
43
+
44
+ if(((!empty($paypal['txn_type']) && preg_match('/^(subscr_eot|recurring_payment_expired|recurring_payment_suspended_due_to_max_failed_payment)$/i', $paypal['txn_type']) && ($recurring = TRUE))
45
+ || (!empty($paypal['txn_type']) && preg_match('/^recurring_payment_profile_cancel$/i', $paypal['txn_type']) && !empty($paypal['initial_payment_status']) && preg_match('/^failed$/i', $paypal['initial_payment_status']) && ($recurring = TRUE))
46
+ || (!empty($paypal['txn_type']) && preg_match('/^new_case$/i', $paypal['txn_type']) && !empty($paypal['case_type']) && preg_match('/^chargeback$/i', $paypal['case_type']) && !($recurring = FALSE)) // Seeking this for future compatibility.
47
+ || (!empty($paypal['payment_status']) && preg_match('/^(refunded|reversed|reversal)$/i', $paypal['payment_status']) && !($recurring = FALSE))) // The `txn_type` is irrelevant in all of these payment statuses: `refunded|reversed|reversal`.
48
+ && (!empty($paypal['subscr_id']) || ($paypal['subscr_id'] = c_ws_plugin__s2member_paypal_utilities::paypal_pro_subscr_id($paypal)) || (!empty($paypal['parent_txn_id']) && ($paypal['subscr_id'] = $paypal['parent_txn_id']))) // Other MUST haves.
49
+ && (!empty($paypal['period1']) || ($paypal['period1'] = c_ws_plugin__s2member_paypal_utilities::paypal_pro_period1($paypal, FALSE)) || empty($recurring) || ($paypal['period1'] = c_ws_plugin__s2member_utils_users::get_user_ipn_signup_var('period1', FALSE, $paypal['subscr_id'])) || ($paypal['period1'] = '0 D'))
50
+ && (!empty($paypal['period3']) || ($paypal['period3'] = c_ws_plugin__s2member_paypal_utilities::paypal_pro_period3($paypal, FALSE)) || empty($recurring) || ($paypal['period3'] = c_ws_plugin__s2member_utils_users::get_user_ipn_signup_var('period3', FALSE, $paypal['subscr_id'])) || ($paypal['period3'] = '1 D'))
51
+ && ((!empty($paypal['item_number']) || ($paypal['item_number'] = c_ws_plugin__s2member_paypal_utilities::paypal_pro_item_number($paypal)) || ($paypal['item_number'] = c_ws_plugin__s2member_utils_users::get_user_ipn_signup_var('item_number', FALSE, $paypal['subscr_id'])) || ($paypal['item_number'] = '1')) && preg_match($GLOBALS['WS_PLUGIN__']['s2member']['c']['membership_item_number_w_level_regex'], $paypal['item_number']))
52
+ && (!empty($paypal['item_name']) || ($paypal['item_name'] = c_ws_plugin__s2member_paypal_utilities::paypal_pro_item_name($paypal)) || ($paypal['item_name'] = c_ws_plugin__s2member_utils_users::get_user_ipn_signup_var('item_name', FALSE, $paypal['subscr_id'])) || ($paypal['item_name'] = $_SERVER['HTTP_HOST']))
53
+ && (!empty($paypal['payer_email']) || ($paypal['payer_email'] = c_ws_plugin__s2member_utils_users::get_user_ipn_signup_var('payer_email', FALSE, $paypal['subscr_id'])) || ($paypal['payer_email'] = c_ws_plugin__s2member_utils_users::get_user_email_with($paypal['subscr_id'])))
54
+ && (!empty($paypal['subscr_baid']) || ($paypal['subscr_baid'] = $paypal['subscr_id']))
55
+ && (!empty($paypal['subscr_cid']) || ($paypal['subscr_cid'] = $paypal['subscr_id']))
56
+ )
57
  {
58
+ foreach(array_keys(get_defined_vars()) as $__v) $__refs[$__v] =& $$__v;
59
+ do_action('ws_plugin__s2member_during_paypal_notify_before_subscr_eot', get_defined_vars());
60
+ unset($__refs, $__v);
61
+
62
+ if(!get_transient($transient_ipn = 's2m_ipn_'.md5('s2member_transient_'.$_paypal_s)) && set_transient($transient_ipn, time(), 31556926 * 10))
63
+ {
64
+ $is_refund = (preg_match('/^refunded$/i', $paypal['payment_status']) && !empty($paypal['parent_txn_id']));
65
+ $is_reversal = (preg_match('/^(reversed|reversal)$/i', $paypal['payment_status']) && !empty($paypal['parent_txn_id']));
66
+ $is_reversal = (!$is_reversal) ? (preg_match('/^new_case$/i', $paypal['txn_type']) && preg_match('/^chargeback$/i', $paypal['case_type'])) : $is_reversal;
67
+ $is_refund_or_reversal = ($is_refund || $is_reversal); // If either of the previous tests above evaluated to true; then it's obviously a Refund and/or a Reversal.
68
+ $is_partial_refund = // Partial refund detection. All refunds processed against Subscriptions are considered partials. Full refunds occur only against Buy Now transactions.
69
+ (!$is_refund || (!empty($paypal['mc_gross']) && ($original_txn_type = c_ws_plugin__s2member_utils_users::get_user_ipn_signup_var('txn_type', FALSE, $paypal['subscr_id'])) === 'web_accept'
70
+ && ($original_mc_gross = c_ws_plugin__s2member_utils_users::get_user_ipn_signup_var('mc_gross', FALSE, $paypal['subscr_id'])) <= abs($paypal['mc_gross']))) ? FALSE : TRUE;
71
+ $is_delayed_eot = (!$is_refund_or_reversal && preg_match('/^(subscr_eot|recurring_payment_expired)$/i', $paypal['txn_type']) && preg_match('/^I-/i', $paypal['subscr_id']));
72
+
73
+ if($is_refund_or_reversal)
74
+ $paypal['s2member_log'][] = 's2Member `txn_type` identified as '.($identified_as = '( `[empty or irrelevant]` ) w/ `payment_status` ( `refunded|reversed|reversal` ) - or - `new_case` w/ `case_type` ( `chargeback` )').'.';
75
+ else $paypal['s2member_log'][] = 's2Member `txn_type` identified as '.($identified_as = '( `subscr_eot|recurring_payment_expired|recurring_payment_suspended_due_to_max_failed_payment` ) - or - `recurring_payment_profile_cancel` w/ `initial_payment_status` ( `failed` )').'.';
76
+
77
+ if(empty($_REQUEST['s2member_paypal_proxy'])) // Only on true PayPal IPNs; e.g. we can bypass this on proxied IPNs.
78
  {
79
+ $paypal['s2member_log'][] = 'Sleeping for 10 seconds. Waiting for a possible ( `subscr_signup|subscr_modify|recurring_payment_profile_created` ).';
80
+ sleep(10); // Sleep here for a moment. PayPal sometimes sends a subscr_eot before the subscr_signup, subscr_modify.
81
+ $paypal['s2member_log'][] = 'Awake. It\'s '.date('D M j, Y g:i:s a T').'. s2Member `txn_type` identified as '.$identified_as.'.';
82
+ }
83
+ $paypal['ip'] = (preg_match('/ip address/i', $paypal['option_name2']) && $paypal['option_selection2']) ? $paypal['option_selection2'] : '';
84
+ $paypal['ip'] = (!$paypal['ip'] && preg_match('/^[a-z0-9]+~[0-9\.]+$/i', $paypal['invoice'])) ? preg_replace('/^[a-z0-9]+~/i', '', $paypal['invoice']) : $paypal['ip'];
 
 
 
 
 
 
 
 
 
 
 
 
85
 
86
+ $paypal['currency'] = strtoupper($paypal['mc_currency']); // Normalize input currency.
87
+ $paypal['currency_symbol'] = c_ws_plugin__s2member_utils_cur::symbol($paypal['currency']);
88
+
89
+ if(($user_id = c_ws_plugin__s2member_utils_users::get_user_id_with($paypal['subscr_id'])) && is_object($user = new WP_User($user_id)) && !empty($user->ID))
90
+ {
91
+ $fields = get_user_option('s2member_custom_fields', $user_id); // These will be needed below.
92
+ $user_reg_ip = get_user_option('s2member_registration_ip', $user_id); // Needed below.
93
+ $user_reg_ip = $paypal['ip'] = ($user_reg_ip) ? $user_reg_ip : $paypal['ip'];
94
+
95
+ if((!$is_refund_or_reversal && !$is_delayed_eot && !get_user_option('s2member_auto_eot_time', $user_id))
96
+ || ($is_refund_or_reversal && $is_partial_refund && $GLOBALS['WS_PLUGIN__']['s2member']['o']['triggers_immediate_eot'] === 'refunds,partial_refunds,reversals')
97
+ || ($is_refund_or_reversal && !$is_partial_refund && $GLOBALS['WS_PLUGIN__']['s2member']['o']['triggers_immediate_eot'] === 'refunds,reversals')
98
+ || ($is_refund && !$is_partial_refund && $GLOBALS['WS_PLUGIN__']['s2member']['o']['triggers_immediate_eot'] === 'refunds')
99
+ || ($is_reversal && $GLOBALS['WS_PLUGIN__']['s2member']['o']['triggers_immediate_eot'] === 'reversals')
100
+ )
101
+ {
102
+ if(!$user->has_cap('administrator')) // Do NOT process this routine on Administrators.
103
+ {
104
+ if($GLOBALS['WS_PLUGIN__']['s2member']['o']['auto_eot_system_enabled']) // EOT enabled?
105
+ {
106
+ if($GLOBALS['WS_PLUGIN__']['s2member']['o']['membership_eot_behavior'] === 'demote')
107
  {
108
+ $processing = $during = TRUE; // Yes, we ARE processing this.
109
+
110
+ $eot_del_type = ($is_refund_or_reversal) ? // Set EOT/Del type.
111
+ 'ipn-refund-reversal-demotion' : 'ipn-cancellation-expiration-demotion';
112
+
113
+ $demotion_role = c_ws_plugin__s2member_option_forces::force_demotion_role('subscriber');
114
+ $existing_role = c_ws_plugin__s2member_user_access::user_access_role($user);
115
+
116
+ foreach(array_keys(get_defined_vars()) as $__v) $__refs[$__v] =& $$__v;
117
+ do_action('ws_plugin__s2member_during_paypal_notify_during_subscr_eot_before_demote', get_defined_vars());
118
+ do_action('ws_plugin__s2member_during_collective_mods', $user_id, get_defined_vars(), $eot_del_type, 'modification', $demotion_role);
119
+ do_action('ws_plugin__s2member_during_collective_eots', $user_id, get_defined_vars(), $eot_del_type, 'modification');
120
+ unset($__refs, $__v);
121
+
122
+ if($existing_role !== $demotion_role) // Only if NOT the existing Role.
123
+ $user->set_role($demotion_role); // Give User the demotion Role.
124
+
125
+ if(apply_filters('ws_plugin__s2member_remove_ccaps_during_eot_events',
126
+ ((bool)$GLOBALS['WS_PLUGIN__']['s2member']['o']['eots_remove_ccaps'] || $is_refund_or_reversal), get_defined_vars()))
127
+ foreach($user->allcaps as $cap => $cap_enabled)
128
+ if(preg_match('/^access_s2member_ccap_/', $cap))
129
+ $user->remove_cap($ccap = $cap);
130
+
131
+ delete_user_option($user_id, 's2member_custom');
132
+ delete_user_option($user_id, 's2member_subscr_id');
133
+ delete_user_option($user_id, 's2member_subscr_baid');
134
+ delete_user_option($user_id, 's2member_subscr_cid');
135
+ delete_user_option($user_id, 's2member_subscr_gateway');
136
+
137
+ delete_user_option($user_id, 's2member_ipn_signup_vars');
138
+ if(!apply_filters('ws_plugin__s2member_preserve_paid_registration_times', TRUE, get_defined_vars()))
139
+ delete_user_option($user_id, 's2member_paid_registration_times');
140
+
141
+ delete_user_option($user_id, 's2member_last_status_scan');
142
+ delete_user_option($user_id, 's2member_first_payment_txn_id');
143
+ delete_user_option($user_id, 's2member_last_payment_time');
144
+ delete_user_option($user_id, 's2member_auto_eot_time');
145
+
146
+ delete_user_option($user_id, 's2member_file_download_access_log');
147
+
148
+ c_ws_plugin__s2member_user_notes::append_user_notes($user_id, 'Demoted by s2Member: '.date('D M j, Y g:i a T'));
149
+ c_ws_plugin__s2member_user_notes::append_user_notes($user_id, 'Paid Subscr. ID @ time of demotion: '.$paypal['subscr_gateway'].' -› '.$paypal['subscr_id']);
150
+
151
+ $paypal['s2member_log'][] = 'Member Level/Capabilities demoted to: '.ucwords(preg_replace('/_/', ' ', $demotion_role)).'.';
152
+
153
+ if($processing && $GLOBALS['WS_PLUGIN__']['s2member']['o']['eot_del_notification_urls'] && is_array($cv = preg_split('/\|/', $paypal['custom'])))
154
+ {
155
+ foreach(preg_split('/['."\r\n\t".']+/', $GLOBALS['WS_PLUGIN__']['s2member']['o']['eot_del_notification_urls']) as $url) // Handle EOT Notifications.
156
+
157
+ if(($url = preg_replace('/%%cv([0-9]+)%%/ei', 'urlencode(trim(@$cv[$1]))', $url)) && ($url = preg_replace('/%%eot_del_type%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($eot_del_type)), $url)) && ($url = preg_replace('/%%subscr_id%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($paypal['subscr_id'])), $url)))
158
+ if(($url = preg_replace('/%%subscr_baid%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($paypal['subscr_baid'])), $url)) && ($url = preg_replace('/%%subscr_cid%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($paypal['subscr_cid'])), $url)))
159
+ if(($url = preg_replace('/%%user_first_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($user->first_name)), $url)) && ($url = preg_replace('/%%user_last_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($user->last_name)), $url)))
160
+ if(($url = preg_replace('/%%user_full_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode(trim($user->first_name.' '.$user->last_name))), $url)))
161
+ if(($url = preg_replace('/%%user_email%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($user->user_email)), $url)))
162
+ if(($url = preg_replace('/%%user_login%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($user->user_login)), $url)))
163
+ if(($url = preg_replace('/%%user_ip%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($user_reg_ip)), $url)))
164
+ if(($url = preg_replace('/%%user_id%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($user_id)), $url)))
165
  {
166
+ if(is_array($fields) && !empty($fields))
167
+ foreach($fields as $var => $val) // Custom Registration/Profile Fields.
168
+ if(!($url = preg_replace('/%%'.preg_quote($var, '/').'%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode(maybe_serialize($val))), $url)))
169
+ break;
170
+
171
+ if(($url = trim(preg_replace('/%%(.+?)%%/i', '', $url))))
172
+ c_ws_plugin__s2member_utils_urls::remote($url);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
173
  }
174
+ $paypal['s2member_log'][] = 'EOT/Deletion Notification URLs have been processed.';
175
+ }
176
+ if($processing && $GLOBALS['WS_PLUGIN__']['s2member']['o']['eot_del_notification_recipients'] && is_array($cv = preg_split('/\|/', $paypal['custom'])))
177
+ {
178
+ $msg = $sbj = '(s2Member / API Notification Email) - EOT/Deletion';
179
+ $msg .= "\n\n"; // Spacing in the message body.
180
+
181
+ $msg .= 'eot_del_type: %%eot_del_type%%'."\n";
182
+ $msg .= 'subscr_id: %%subscr_id%%'."\n";
183
+ $msg .= 'subscr_baid: %%subscr_baid%%'."\n";
184
+ $msg .= 'subscr_cid: %%subscr_cid%%'."\n";
185
+ $msg .= 'user_first_name: %%user_first_name%%'."\n";
186
+ $msg .= 'user_last_name: %%user_last_name%%'."\n";
187
+ $msg .= 'user_full_name: %%user_full_name%%'."\n";
188
+ $msg .= 'user_email: %%user_email%%'."\n";
189
+ $msg .= 'user_login: %%user_login%%'."\n";
190
+ $msg .= 'user_ip: %%user_ip%%'."\n";
191
+ $msg .= 'user_id: %%user_id%%'."\n";
192
+
193
+ if(is_array($fields) && !empty($fields))
194
+ foreach($fields as $var => $val)
195
+ $msg .= $var.': %%'.$var.'%%'."\n";
196
+
197
+ $msg .= 'cv0: %%cv0%%'."\n";
198
+ $msg .= 'cv1: %%cv1%%'."\n";
199
+ $msg .= 'cv2: %%cv2%%'."\n";
200
+ $msg .= 'cv3: %%cv3%%'."\n";
201
+ $msg .= 'cv4: %%cv4%%'."\n";
202
+ $msg .= 'cv5: %%cv5%%'."\n";
203
+ $msg .= 'cv6: %%cv6%%'."\n";
204
+ $msg .= 'cv7: %%cv7%%'."\n";
205
+ $msg .= 'cv8: %%cv8%%'."\n";
206
+ $msg .= 'cv9: %%cv9%%';
207
+
208
+ if(($msg = preg_replace('/%%cv([0-9]+)%%/ei', 'trim(@$cv[$1])', $msg)) && ($msg = preg_replace('/%%eot_del_type%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($eot_del_type), $msg)) && ($msg = preg_replace('/%%subscr_id%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['subscr_id']), $msg)))
209
+ if(($msg = preg_replace('/%%subscr_baid%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['subscr_baid']), $msg)) && ($msg = preg_replace('/%%subscr_cid%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['subscr_cid']), $msg)))
210
+ if(($msg = preg_replace('/%%user_first_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($user->first_name), $msg)) && ($msg = preg_replace('/%%user_last_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($user->last_name), $msg)))
211
+ if(($msg = preg_replace('/%%user_full_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(trim($user->first_name.' '.$user->last_name)), $msg)))
212
+ if(($msg = preg_replace('/%%user_email%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($user->user_email), $msg)))
213
+ if(($msg = preg_replace('/%%user_login%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($user->user_login), $msg)))
214
+ if(($msg = preg_replace('/%%user_ip%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($user_reg_ip), $msg)))
215
+ if(($msg = preg_replace('/%%user_id%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($user_id), $msg)))
216
+ {
217
+ if(is_array($fields) && !empty($fields))
218
+ foreach($fields as $var => $val) // Custom Registration/Profile Fields.
219
+ if(!($msg = preg_replace('/%%'.preg_quote($var, '/').'%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(maybe_serialize($val)), $msg)))
220
+ break;
221
+
222
+ if($sbj && ($msg = trim(preg_replace('/%%(.+?)%%/i', '', $msg)))) // Still have a ``$sbj`` and a ``$msg``?
223
+
224
+ foreach(c_ws_plugin__s2member_utils_strings::parse_emails($GLOBALS['WS_PLUGIN__']['s2member']['o']['eot_del_notification_recipients']) as $recipient)
225
+ wp_mail($recipient, apply_filters('ws_plugin__s2member_eot_del_notification_email_sbj', $sbj, get_defined_vars()), apply_filters('ws_plugin__s2member_eot_del_notification_email_msg', $msg, get_defined_vars()), 'Content-Type: text/plain; charset=UTF-8');
226
+ }
227
+ $paypal['s2member_log'][] = 'EOT/Deletion Notification Emails have been processed.';
228
+ }
229
+ foreach(array_keys(get_defined_vars()) as $__v) $__refs[$__v] =& $$__v;
230
+ do_action('ws_plugin__s2member_during_paypal_notify_during_subscr_eot_demote', get_defined_vars());
231
+ unset($__refs, $__v);
232
+ }
233
+ else if($GLOBALS['WS_PLUGIN__']['s2member']['o']['membership_eot_behavior'] === 'delete')
234
+ {
235
+ $processing = $during = TRUE; // Yes, we ARE processing this.
236
 
237
+ $eot_del_type = $GLOBALS['ws_plugin__s2member_eot_del_type'] = // Configure EOT/Del type.
238
+ ($is_refund_or_reversal) ? 'ipn-refund-reversal-deletion' : 'ipn-cancellation-expiration-deletion';
239
 
240
+ foreach(array_keys(get_defined_vars()) as $__v) $__refs[$__v] =& $$__v;
241
+ do_action('ws_plugin__s2member_during_paypal_notify_during_subscr_eot_before_delete', get_defined_vars());
242
+ do_action('ws_plugin__s2member_during_collective_eots', $user_id, get_defined_vars(), $eot_del_type, 'removal-deletion');
243
+ unset($__refs, $__v);
244
 
245
+ if(is_multisite()) // Multisite does NOT actually delete; ONLY removes.
246
+ {
247
+ remove_user_from_blog($user_id, $current_blog->blog_id);
248
+ // This will automatically trigger `eot_del_notification_urls` as well.
249
+ c_ws_plugin__s2member_user_deletions::handle_ms_user_deletions($user_id, $current_blog->blog_id, 's2says');
250
+ }
251
+ else // Otherwise, we can actually delete them.
252
+ // This will automatically trigger `eot_del_notification_urls` as well.
253
+ wp_delete_user($user_id); // `c_ws_plugin__s2member_user_deletions::handle_user_deletions()`
254
 
255
+ $paypal['s2member_log'][] = 'This Member\'s account has been '.((is_multisite()) ? 'removed' : 'deleted').'.';
256
 
257
+ $paypal['s2member_log'][] = 'EOT/Deletion Notification URLs have been processed.';
258
 
259
+ foreach(array_keys(get_defined_vars()) as $__v) $__refs[$__v] =& $$__v;
260
+ do_action('ws_plugin__s2member_during_paypal_notify_during_subscr_eot_delete', get_defined_vars());
261
+ unset($__refs, $__v);
262
+ }
263
+ foreach(array_keys(get_defined_vars()) as $__v) $__refs[$__v] =& $$__v;
264
+ do_action('ws_plugin__s2member_during_paypal_notify_during_subscr_eot', get_defined_vars());
265
+ unset($__refs, $__v);
266
+ }
267
+ else // Otherwise, treat this as if it were a cancellation. EOTs are currently disabled.
268
+ {
269
+ $processing = $during = TRUE; // Yes, we ARE processing this.
270
+
271
+ update_user_option($user_id, 's2member_auto_eot_time', ($auto_eot_time = strtotime('now')));
272
+
273
+ $paypal['s2member_log'][] = 'Auto-EOT is currently disabled. Skipping EOT (demote|delete), for now.';
274
+ $paypal['s2member_log'][] = 'Recording the Auto-EOT Time for this Member\'s account: '.date('D M j, Y g:i a T', $auto_eot_time);
275
+
276
+ foreach(array_keys(get_defined_vars()) as $__v) $__refs[$__v] =& $$__v;
277
+ do_action('ws_plugin__s2member_during_paypal_notify_during_subscr_eot_disabled', get_defined_vars());
278
+ unset($__refs, $__v);
279
+ }
280
+ }
281
+ else $paypal['s2member_log'][] = 'Unable to (demote|delete) Member. The existing User ID is associated with an Administrator. Stopping here. Otherwise, an Administrator could lose access.';
282
+ }
283
+ else if($is_delayed_eot && !get_user_option('s2member_auto_eot_time', $user_id))
284
+ {
285
+ if(!$user->has_cap('administrator')) // Do NOT process this routine on Administrators.
286
+ {
287
+ $processing = $during = TRUE; // Yes, we ARE processing this.
288
 
289
+ $auto_eot_time = c_ws_plugin__s2member_utils_time::auto_eot_time($user_id, $paypal['period1'], $paypal['period3'], '', time());
290
+ /* We assume the last payment was today, because this is how newer PayPal accounts function with respect to EOT handling.
291
+ Newer PayPal accounts ( i.e. Subscription IDs starting with `I-`, will have their EOT triggered upon the last payment. */
292
+ update_user_option($user_id, 's2member_auto_eot_time', $auto_eot_time); // s2Member will follow-up on this later.
293
 
294
+ $paypal['s2member_log'][] = 'Auto-EOT Time for this account (delayed), set to: '.date('D M j, Y g:i a T', $auto_eot_time);
 
295
 
296
+ foreach(array_keys(get_defined_vars()) as $__v) $__refs[$__v] =& $$__v;
297
+ do_action('ws_plugin__s2member_during_paypal_notify_during_subscr_eot_delayed', get_defined_vars());
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
298
  unset($__refs, $__v);
 
 
299
  }
300
+ else $paypal['s2member_log'][] = 'Ignoring Delayed EOT. The existing User ID is associated with an Administrator. Stopping here. Otherwise, an Administrator could lose access.';
301
+ }
302
+ else if(!$is_refund_or_reversal || $is_delayed_eot)
303
+ $paypal['s2member_log'][] = 'Skipping (demote|delete) Member, for now. An Auto-EOT Time is already set for this account. When an Auto-EOT Time has been recorded, s2Member will handle EOT (demote|delete) events using it\'s own Auto-EOT System - internally.';
304
+
305
+ else if($is_refund && $is_partial_refund)
306
+ $paypal['s2member_log'][] = 'Skipping (demote|delete) Member. Your configuration dictates that s2Member should NOT take any immediate action on an EOT associated with a Partial Refund. An s2Member API Notification will still be processed however.';
307
+
308
+ else if($is_refund && !$is_partial_refund)
309
+ $paypal['s2member_log'][] = 'Skipping (demote|delete) Member. Your configuration dictates that s2Member should NOT take any immediate action on an EOT associated with a Full Refund. An s2Member API Notification will still be processed however.';
310
+
311
+ else if($is_reversal)
312
+ $paypal['s2member_log'][] = 'Skipping (demote|delete) Member. Your configuration dictates that s2Member should NOT take any immediate action on an EOT associated with a Chargeback Reversal. An s2Member API Notification will still be processed however.';
313
+ }
314
+ else if($is_delayed_eot) // Otherwise, we need to re-generate/store this IPN into a Transient Queue. Then re-process it on registration.
315
+ {
316
+ $paypal['s2member_log'][] = 'Skipping this IPN response, for now. The Subscr. ID is not associated with a registered Member.';
317
+
318
+ $ipn = array('txn_type' => 'subscr_eot'); // Create a simulated IPN response for txn_type=subscr_eot.
319
+
320
+ foreach($paypal as $var => $val)
321
+ if(in_array($var, array('subscr_gateway', 'subscr_id', 'subscr_baid', 'subscr_cid', 'custom', 'invoice', 'payer_email', 'first_name', 'last_name', 'item_name', 'item_number', /* Exclude; might be defaults. 'period1', 'period3', */
322
+ 'option_name1', 'option_selection1', 'option_name2', 'option_selection2')))
323
+ $ipn[$var] = $val;
324
+
325
+ $paypal['s2member_log'][] = 'Re-generating. This IPN will go into a Transient Queue; and be re-processed during registration.';
326
+
327
+ set_transient('s2m_'.md5('s2member_transient_ipn_subscr_eot_'.$paypal['subscr_id']), $ipn, 43200);
328
+ }
329
+ else $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 processed through another IPN, removed manually by a Site Administrator, or by s2Member\'s Auto-EOT Sys.';
330
+ /*
331
+ Refunds and chargeback reversals. This is excluded from the processing check, because a Member *could* have already been (demoted|deleted).
332
+ In other words, s2Member sends `Refund/Reversal` Notifications ANYTIME a Refund/Reversal occurs; even if s2Member did not process it otherwise.
333
+ Since this routine ignores the processing check, it is *possible* that Refund/Reversal Notification URLs will be contacted more than once.
334
+ If you're writing scripts that depend on Refund/Reversal Notifications, please keep this in mind.
335
+ */
336
+ if($is_refund_or_reversal) // Previously assigned as a quick method of Refund/Reversal detection.
337
+ {
338
+ $fields = ($user_id) ? get_user_option('s2member_custom_fields', $user_id) : array(); // These will be needed below.
339
+ $user_reg_ip = ($user_id) ? get_user_option('s2member_registration_ip', $user_id) : ''; // Needed below.
340
+ $user_reg_ip = $paypal['ip'] = ($user_reg_ip) ? $user_reg_ip : $paypal['ip']; // Now merge conditionally.
341
+
342
+ if($GLOBALS['WS_PLUGIN__']['s2member']['o']['ref_rev_notification_urls'] && is_array($cv = preg_split('/\|/', $paypal['custom'])))
343
+ {
344
+ foreach(preg_split('/['."\r\n\t".']+/', $GLOBALS['WS_PLUGIN__']['s2member']['o']['ref_rev_notification_urls']) as $url)
345
+
346
+ if(($url = preg_replace('/%%cv([0-9]+)%%/ei', 'urlencode(trim(@$cv[$1]))', $url)) && ($url = preg_replace('/%%subscr_id%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($paypal['subscr_id'])), $url)) && ($url = preg_replace('/%%parent_txn_id%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($paypal['parent_txn_id'])), $url)))
347
+ if(($url = preg_replace('/%%subscr_baid%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($paypal['subscr_baid'])), $url)) && ($url = preg_replace('/%%subscr_cid%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($paypal['subscr_cid'])), $url)))
348
+ if(($url = preg_replace('/%%item_number%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($paypal['item_number'])), $url)) && ($url = preg_replace('/%%item_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($paypal['item_name'])), $url)))
349
+ if(($url = preg_replace('/%%currency%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($paypal['currency'])), $url)) && ($url = preg_replace('/%%currency_symbol%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($paypal['currency_symbol'])), $url)))
350
+ if(($url = preg_replace('/%%-amount%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($paypal['mc_gross'])), $url)) && ($url = preg_replace('/%%-fee%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($paypal['mc_fee'])), $url)))
351
+ if(($url = preg_replace('/%%first_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($paypal['first_name'])), $url)) && ($url = preg_replace('/%%last_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($paypal['last_name'])), $url)))
352
+ if(($url = preg_replace('/%%full_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode(trim($paypal['first_name'].' '.$paypal['last_name']))), $url)))
353
+ if(($url = preg_replace('/%%payer_email%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($paypal['payer_email'])), $url)))
354
+ if(($url = preg_replace('/%%user_ip%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($user_reg_ip)), $url)))
355
+ if(($url = preg_replace('/%%user_id%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($user_id)), $url)))
356
+ {
357
+ if(is_array($fields) && !empty($fields))
358
+ foreach($fields as $var => $val) // Custom Registration/Profile Fields.
359
+ if(!($url = preg_replace('/%%'.preg_quote($var, '/').'%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode(maybe_serialize($val))), $url)))
360
+ break;
361
+
362
+ if(($url = trim(preg_replace('/%%(.+?)%%/i', '', $url))))
363
+ c_ws_plugin__s2member_utils_urls::remote($url);
364
+ }
365
+ $paypal['s2member_log'][] = 'Refund/Reversal Notification URLs have been processed.';
366
+ }
367
+ if($GLOBALS['WS_PLUGIN__']['s2member']['o']['ref_rev_notification_recipients'] && is_array($cv = preg_split('/\|/', $paypal['custom'])))
368
+ {
369
+ $msg = $sbj = '(s2Member / API Notification Email) - Refund/Reversal';
370
+ $msg .= "\n\n"; // Spacing in the message body.
371
+
372
+ $msg .= 'subscr_id: %%subscr_id%%'."\n";
373
+ $msg .= 'subscr_baid: %%subscr_baid%%'."\n";
374
+ $msg .= 'subscr_cid: %%subscr_cid%%'."\n";
375
+ $msg .= 'parent_txn_id: %%parent_txn_id%%'."\n";
376
+ $msg .= 'item_number: %%item_number%%'."\n";
377
+ $msg .= 'item_name: %%item_name%%'."\n";
378
+ $msg .= 'currency: %%currency%%'."\n";
379
+ $msg .= 'currency_symbol: %%currency_symbol%%'."\n";
380
+ $msg .= '-amount: %%-amount%%'."\n";
381
+ $msg .= '-fee: %%-fee%%'."\n";
382
+ $msg .= 'first_name: %%first_name%%'."\n";
383
+ $msg .= 'last_name: %%last_name%%'."\n";
384
+ $msg .= 'full_name: %%full_name%%'."\n";
385
+ $msg .= 'payer_email: %%payer_email%%'."\n";
386
+ $msg .= 'user_ip: %%user_ip%%'."\n";
387
+ $msg .= 'user_id: %%user_id%%'."\n";
388
+
389
+ if(is_array($fields) && !empty($fields))
390
+ foreach($fields as $var => $val)
391
+ $msg .= $var.': %%'.$var.'%%'."\n";
392
+
393
+ $msg .= 'cv0: %%cv0%%'."\n";
394
+ $msg .= 'cv1: %%cv1%%'."\n";
395
+ $msg .= 'cv2: %%cv2%%'."\n";
396
+ $msg .= 'cv3: %%cv3%%'."\n";
397
+ $msg .= 'cv4: %%cv4%%'."\n";
398
+ $msg .= 'cv5: %%cv5%%'."\n";
399
+ $msg .= 'cv6: %%cv6%%'."\n";
400
+ $msg .= 'cv7: %%cv7%%'."\n";
401
+ $msg .= 'cv8: %%cv8%%'."\n";
402
+ $msg .= 'cv9: %%cv9%%';
403
+
404
+ if(($msg = preg_replace('/%%cv([0-9]+)%%/ei', 'trim(@$cv[$1])', $msg)) && ($msg = preg_replace('/%%subscr_id%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['subscr_id']), $msg)) && ($msg = preg_replace('/%%parent_txn_id%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['parent_txn_id']), $msg)))
405
+ if(($msg = preg_replace('/%%subscr_baid%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['subscr_baid']), $msg)) && ($msg = preg_replace('/%%subscr_cid%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['subscr_cid']), $msg)))
406
+ if(($msg = preg_replace('/%%item_number%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['item_number']), $msg)) && ($msg = preg_replace('/%%item_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['item_name']), $msg)))
407
+ if(($msg = preg_replace('/%%currency%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['currency']), $msg)) && ($msg = preg_replace('/%%currency_symbol%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['currency_symbol']), $msg)))
408
+ if(($msg = preg_replace('/%%-amount%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['mc_gross']), $msg)) && ($msg = preg_replace('/%%-fee%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['mc_fee']), $msg)))
409
+ if(($msg = preg_replace('/%%first_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['first_name']), $msg)) && ($msg = preg_replace('/%%last_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['last_name']), $msg)))
410
+ if(($msg = preg_replace('/%%full_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(trim($paypal['first_name'].' '.$paypal['last_name'])), $msg)))
411
+ if(($msg = preg_replace('/%%payer_email%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['payer_email']), $msg)))
412
+ if(($msg = preg_replace('/%%user_ip%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($user_reg_ip), $msg)))
413
+ if(($msg = preg_replace('/%%user_id%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($user_id), $msg)))
414
+ {
415
+ if(is_array($fields) && !empty($fields))
416
+ foreach($fields as $var => $val) // Custom Registration/Profile Fields.
417
+ if(!($msg = preg_replace('/%%'.preg_quote($var, '/').'%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(maybe_serialize($val)), $msg)))
418
+ break;
419
+
420
+ if($sbj && ($msg = trim(preg_replace('/%%(.+?)%%/i', '', $msg)))) // Still have a ``$sbj`` and a ``$msg``?
421
+
422
+ foreach(c_ws_plugin__s2member_utils_strings::parse_emails($GLOBALS['WS_PLUGIN__']['s2member']['o']['ref_rev_notification_recipients']) as $recipient)
423
+ wp_mail($recipient, apply_filters('ws_plugin__s2member_ref_rev_notification_email_sbj', $sbj, get_defined_vars()), apply_filters('ws_plugin__s2member_ref_rev_notification_email_msg', $msg, get_defined_vars()), 'Content-Type: text/plain; charset=UTF-8');
424
+ }
425
+ $paypal['s2member_log'][] = 'Refund/Reversal Notification Emails have been processed.';
426
+ }
427
+ foreach(array_keys(get_defined_vars()) as $__v) $__refs[$__v] =& $$__v;
428
+ do_action('ws_plugin__s2member_during_paypal_notify_during_subscr_eot_refund_reversal', get_defined_vars());
429
+ unset($__refs, $__v);
430
  }
431
+ }
432
+ else // Else, this is a duplicate IPN. Must stop here.
433
+ {
434
+ $paypal['s2member_log'][] = 'Not processing. Duplicate IPN.';
435
+ $paypal['s2member_log'][] = 's2Member `txn_type` identified as a type of EOT.';
436
+ $paypal['s2member_log'][] = 'Duplicate IPN. Already processed. This IPN will be ignored.';
437
+ }
438
+ foreach(array_keys(get_defined_vars()) as $__v) $__refs[$__v] =& $$__v;
439
+ do_action('ws_plugin__s2member_during_paypal_notify_after_subscr_eot', get_defined_vars());
440
+ unset($__refs, $__v);
441
+
442
+ return apply_filters('c_ws_plugin__s2member_paypal_notify_in_subscr_or_rp_eots_w_level', $paypal, get_defined_vars());
443
  }
444
+ else return apply_filters('c_ws_plugin__s2member_paypal_notify_in_subscr_or_rp_eots_w_level', FALSE, get_defined_vars());
445
+ }
446
+ }
447
+ }
includes/classes/paypal-notify-in-subscr-or-rp-payment-w-level.inc.php CHANGED
@@ -1,224 +1,233 @@
1
  <?php
2
  /**
3
- * s2Member's PayPal IPN handler (inner processing routine).
4
- *
5
- * Copyright: © 2009-2011
6
- * {@link http://www.websharks-inc.com/ WebSharks, Inc.}
7
- * (coded in the USA)
8
- *
9
- * Released under the terms of the GNU General Public License.
10
- * You should have received a copy of the GNU General Public License,
11
- * along with this software. In the main directory, see: /licensing/
12
- * If not, see: {@link http://www.gnu.org/licenses/}.
13
- *
14
- * @package s2Member\PayPal
15
- * @since 110720
16
- */
17
- if (realpath (__FILE__) === realpath ($_SERVER["SCRIPT_FILENAME"]))
18
- exit ("Do not access this file directly.");
19
-
20
- if (!class_exists ("c_ws_plugin__s2member_paypal_notify_in_subscr_or_rp_payment_w_level"))
 
 
 
 
 
 
 
 
21
  {
22
  /**
23
- * s2Member's PayPal IPN handler (inner processing routine).
24
- *
25
- * @package s2Member\PayPal
26
- * @since 110720
27
- */
28
- class c_ws_plugin__s2member_paypal_notify_in_subscr_or_rp_payment_w_level
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
29
  {
30
- /**
31
- * s2Member's PayPal IPN handler (inner processing routine).
32
- *
33
- * @package s2Member\PayPal
34
- * @since 110720
35
- *
36
- * @param array $vars Required. An array of defined variables passed by {@link s2Member\PayPal\c_ws_plugin__s2member_paypal_notify_in::paypal_notify()}.
37
- * @return array|bool The original ``$paypal`` array passed in (extracted) from ``$vars``, or false when conditions do NOT apply.
38
- */
39
- public static function cp ($vars = array()) // Conditional phase for ``c_ws_plugin__s2member_paypal_notify_in::paypal_notify()``.
 
 
 
 
 
 
 
 
 
 
 
 
 
40
  {
41
- extract ($vars, EXTR_OVERWRITE | EXTR_REFS); // Extract all vars passed in from: ``c_ws_plugin__s2member_paypal_notify_in::paypal_notify()``.
42
-
43
- if ((!empty($paypal["txn_type"]) && preg_match ("/^(subscr_payment|recurring_payment)$/i", $paypal["txn_type"]))
44
- && ((!empty($paypal["item_number"]) || ($paypal["item_number"] = c_ws_plugin__s2member_paypal_utilities::paypal_pro_item_number ($paypal))) && preg_match ($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["membership_item_number_w_level_regex"], $paypal["item_number"]))
45
- && (!empty($paypal["subscr_id"]) || ($paypal["subscr_id"] = c_ws_plugin__s2member_paypal_utilities::paypal_pro_subscr_id ($paypal)))
46
- && (empty($paypal["payment_status"]) || empty($payment_status_issues) || !preg_match ($payment_status_issues, $paypal["payment_status"]))
47
- && (!empty($paypal["item_name"]) || ($paypal["item_name"] = c_ws_plugin__s2member_paypal_utilities::paypal_pro_item_name ($paypal)))
48
- && (!empty($paypal["payer_email"]) || ($paypal["payer_email"] = c_ws_plugin__s2member_utils_users::get_user_email_with ($paypal["subscr_id"])))
49
- && (!empty($paypal["subscr_baid"]) || ($paypal["subscr_baid"] = $paypal["subscr_id"]))
50
- && (!empty($paypal["subscr_cid"]) || ($paypal["subscr_cid"] = $paypal["subscr_id"]))
51
- && (!empty($paypal["txn_id"])) && (!empty($paypal["mc_gross"])))
52
- {
53
- foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;
54
- do_action("ws_plugin__s2member_during_paypal_notify_before_subscr_payment", get_defined_vars ());
55
- unset($__refs, $__v);
56
-
57
- if (!get_transient ($transient_ipn = "s2m_ipn_" . md5 ("s2member_transient_" . $_paypal_s)) && set_transient ($transient_ipn, time (), 31556926 * 10))
58
- {
59
- $paypal["s2member_log"][] = "s2Member `txn_type` identified as " . ($identified_as = "( `subscr_payment|recurring_payment` )") . ".";
60
-
61
- if(empty($_REQUEST["s2member_paypal_proxy"])) // Only on true PayPal IPNs; e.g. we can bypass this on proxied IPNs.
62
- {
63
- $paypal["s2member_log"][] = "Sleeping for 5 seconds. Waiting for a possible ( `subscr_signup|subscr_modify|recurring_payment_profile_created` ).";
64
- sleep (5); // Sleep here for a moment. PayPal sometimes sends a subscr_payment before the subscr_signup, subscr_modify.
65
- $paypal["s2member_log"][] = "Awake. It's " . date ("D M j, Y g:i:s a T") . ". s2Member `txn_type` identified as " . $identified_as . ".";
66
- }
67
- list($paypal["level"], $paypal["ccaps"]) = preg_split ("/\:/", $paypal["item_number"], 3);
68
-
69
- $paypal["ip"] = (preg_match ("/ip address/i", $paypal["option_name2"]) && $paypal["option_selection2"]) ? $paypal["option_selection2"] : "";
70
- $paypal["ip"] = (!$paypal["ip"] && preg_match ("/^[a-z0-9]+~[0-9\.]+$/i", $paypal["invoice"])) ? preg_replace ("/^[a-z0-9]+~/i", "", $paypal["invoice"]) : $paypal["ip"];
71
-
72
- if (($user_id = c_ws_plugin__s2member_utils_users::get_user_id_with ($paypal["subscr_id"])) && is_object ($user = new WP_User ($user_id)) && $user->ID)
73
- {
74
- $processing = $during = true; // Yes, we ARE processing this.
75
-
76
- $pr_times = get_user_option ("s2member_paid_registration_times", $user_id);
77
- $pr_times["level"] = (!$pr_times["level"]) ? time () : $pr_times["level"]; // Preserves existing.
78
- $pr_times["level" . $paypal["level"]] = (!$pr_times["level" . $paypal["level"]]) ? time () : $pr_times["level" . $paypal["level"]];
79
- update_user_option ($user_id, "s2member_paid_registration_times", $pr_times); // Update now.
80
-
81
- if (!get_user_option ("s2member_first_payment_txn_id", $user_id)) // 1st payment?
82
- update_user_option ($user_id, "s2member_first_payment_txn_id", $paypal["txn_id"]);
83
-
84
- update_user_option ($user_id, "s2member_last_payment_time", time ()); // Also update last payment time.
85
-
86
- $paypal["s2member_log"][] = "Updated Payment Times for this Member."; // Flag this action in the log.
87
-
88
- $fields = get_user_option ("s2member_custom_fields", $user_id); // These will be needed in the routines below.
89
- $user_reg_ip = get_user_option ("s2member_registration_ip", $user_id); // Original IP during Registration.
90
- $user_reg_ip = $paypal["ip"] = ($user_reg_ip) ? $user_reg_ip : $paypal["ip"]; // Now merge conditionally.
91
-
92
- if ($processing && $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["payment_notification_urls"] && is_array($cv = preg_split ("/\|/", $paypal["custom"])))
93
- {
94
- foreach (preg_split ("/[\r\n\t]+/", $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["payment_notification_urls"]) as $url)
95
-
96
- if (($url = preg_replace ("/%%cv([0-9]+)%%/ei", 'urlencode(trim(@$cv[$1]))', $url)) && ($url = preg_replace ("/%%subscr_id%%/i", c_ws_plugin__s2member_utils_strings::esc_refs (urlencode ($paypal["subscr_id"])), $url)))
97
- if (($url = preg_replace ("/%%subscr_baid%%/i", c_ws_plugin__s2member_utils_strings::esc_refs (urlencode ($paypal["subscr_baid"])), $url)) && ($url = preg_replace ("/%%subscr_cid%%/i", c_ws_plugin__s2member_utils_strings::esc_refs (urlencode ($paypal["subscr_cid"])), $url)))
98
- if (($url = preg_replace ("/%%amount%%/i", c_ws_plugin__s2member_utils_strings::esc_refs (urlencode ($paypal["mc_gross"])), $url)) && ($url = preg_replace ("/%%txn_id%%/i", c_ws_plugin__s2member_utils_strings::esc_refs (urlencode ($paypal["txn_id"])), $url)))
99
- if (($url = preg_replace ("/%%item_number%%/i", c_ws_plugin__s2member_utils_strings::esc_refs (urlencode ($paypal["item_number"])), $url)) && ($url = preg_replace ("/%%item_name%%/i", c_ws_plugin__s2member_utils_strings::esc_refs (urlencode ($paypal["item_name"])), $url)))
100
- if (($url = preg_replace ("/%%first_name%%/i", c_ws_plugin__s2member_utils_strings::esc_refs (urlencode ($paypal["first_name"])), $url)) && ($url = preg_replace ("/%%last_name%%/i", c_ws_plugin__s2member_utils_strings::esc_refs (urlencode ($paypal["last_name"])), $url)))
101
- if (($url = preg_replace ("/%%full_name%%/i", c_ws_plugin__s2member_utils_strings::esc_refs (urlencode (trim ($paypal["first_name"] . " " . $paypal["last_name"]))), $url)))
102
- if (($url = preg_replace ("/%%payer_email%%/i", c_ws_plugin__s2member_utils_strings::esc_refs (urlencode ($paypal["payer_email"])), $url)))
103
- {
104
- if (($url = preg_replace ("/%%user_first_name%%/i", c_ws_plugin__s2member_utils_strings::esc_refs (urlencode ($user->first_name)), $url)) && ($url = preg_replace ("/%%user_last_name%%/i", c_ws_plugin__s2member_utils_strings::esc_refs (urlencode ($user->last_name)), $url)))
105
- if (($url = preg_replace ("/%%user_full_name%%/i", c_ws_plugin__s2member_utils_strings::esc_refs (urlencode (trim ($user->first_name . " " . $user->last_name))), $url)))
106
- if (($url = preg_replace ("/%%user_email%%/i", c_ws_plugin__s2member_utils_strings::esc_refs (urlencode ($user->user_email)), $url)))
107
- if (($url = preg_replace ("/%%user_login%%/i", c_ws_plugin__s2member_utils_strings::esc_refs (urlencode ($user->user_login)), $url)))
108
- if (($url = preg_replace ("/%%user_ip%%/i", c_ws_plugin__s2member_utils_strings::esc_refs (urlencode ($user_reg_ip)), $url)))
109
- if (($url = preg_replace ("/%%user_id%%/i", c_ws_plugin__s2member_utils_strings::esc_refs (urlencode ($user_id)), $url)))
110
- {
111
- if (is_array($fields) && !empty($fields))
112
- foreach /* Custom Registration/Profile Fields. */ ($fields as $var => $val)
113
- if (!($url = preg_replace ("/%%" . preg_quote ($var, "/") . "%%/i", c_ws_plugin__s2member_utils_strings::esc_refs (urlencode (maybe_serialize ($val))), $url)))
114
- break;
115
-
116
- if (($url = trim (preg_replace ("/%%(.+?)%%/i", "", $url))))
117
- c_ws_plugin__s2member_utils_urls::remote ($url);
118
- }
119
- }
120
- $paypal["s2member_log"][] = "Payment Notification URLs have been processed.";
121
- }
122
- if ($processing && $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["payment_notification_recipients"] && is_array($cv = preg_split ("/\|/", $paypal["custom"])))
123
- {
124
- $msg = $sbj = "(s2Member / API Notification Email) - Payment";
125
- $msg .= "\n\n"; // Spacing in the message body.
126
-
127
- $msg .= "subscr_id: %%subscr_id%%\n";
128
- $msg .= "subscr_baid: %%subscr_baid%%\n";
129
- $msg .= "subscr_cid: %%subscr_cid%%\n";
130
- $msg .= "amount: %%amount%%\n";
131
- $msg .= "txn_id: %%txn_id%%\n";
132
- $msg .= "item_number: %%item_number%%\n";
133
- $msg .= "item_name: %%item_name%%\n";
134
- $msg .= "first_name: %%first_name%%\n";
135
- $msg .= "last_name: %%last_name%%\n";
136
- $msg .= "full_name: %%full_name%%\n";
137
- $msg .= "payer_email: %%payer_email%%\n";
138
-
139
- $msg .= "user_first_name: %%user_first_name%%\n";
140
- $msg .= "user_last_name: %%user_last_name%%\n";
141
- $msg .= "user_full_name: %%user_full_name%%\n";
142
- $msg .= "user_email: %%user_email%%\n";
143
- $msg .= "user_login: %%user_login%%\n";
144
- $msg .= "user_ip: %%user_ip%%\n";
145
- $msg .= "user_id: %%user_id%%\n";
146
-
147
- if (is_array($fields) && !empty($fields))
148
- foreach ($fields as $var => $val)
149
- $msg .= $var . ": %%" . $var . "%%\n";
150
-
151
- $msg .= "cv0: %%cv0%%\n";
152
- $msg .= "cv1: %%cv1%%\n";
153
- $msg .= "cv2: %%cv2%%\n";
154
- $msg .= "cv3: %%cv3%%\n";
155
- $msg .= "cv4: %%cv4%%\n";
156
- $msg .= "cv5: %%cv5%%\n";
157
- $msg .= "cv6: %%cv6%%\n";
158
- $msg .= "cv7: %%cv7%%\n";
159
- $msg .= "cv8: %%cv8%%\n";
160
- $msg .= "cv9: %%cv9%%";
161
-
162
- if (($msg = preg_replace ("/%%cv([0-9]+)%%/ei", 'trim(@$cv[$1])', $msg)) && ($msg = preg_replace ("/%%subscr_id%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($paypal["subscr_id"]), $msg)))
163
- if (($msg = preg_replace ("/%%subscr_baid%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($paypal["subscr_baid"]), $msg)) && ($msg = preg_replace ("/%%subscr_cid%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($paypal["subscr_cid"]), $msg)))
164
- if (($msg = preg_replace ("/%%amount%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($paypal["mc_gross"]), $msg)) && ($msg = preg_replace ("/%%txn_id%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($paypal["txn_id"]), $msg)))
165
- if (($msg = preg_replace ("/%%item_number%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($paypal["item_number"]), $msg)) && ($msg = preg_replace ("/%%item_name%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($paypal["item_name"]), $msg)))
166
- if (($msg = preg_replace ("/%%first_name%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($paypal["first_name"]), $msg)) && ($msg = preg_replace ("/%%last_name%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($paypal["last_name"]), $msg)))
167
- if (($msg = preg_replace ("/%%full_name%%/i", c_ws_plugin__s2member_utils_strings::esc_refs (trim ($paypal["first_name"] . " " . $paypal["last_name"])), $msg)))
168
- if (($msg = preg_replace ("/%%payer_email%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($paypal["payer_email"]), $msg)))
169
  {
170
- if (($msg = preg_replace ("/%%user_first_name%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($user->first_name), $msg)) && ($msg = preg_replace ("/%%user_last_name%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($user->last_name), $msg)))
171
- if (($msg = preg_replace ("/%%user_full_name%%/i", c_ws_plugin__s2member_utils_strings::esc_refs (trim ($user->first_name . " " . $user->last_name)), $msg)))
172
- if (($msg = preg_replace ("/%%user_email%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($user->user_email), $msg)))
173
- if (($msg = preg_replace ("/%%user_login%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($user->user_login), $msg)))
174
- if (($msg = preg_replace ("/%%user_ip%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($user_reg_ip), $msg)))
175
- if (($msg = preg_replace ("/%%user_id%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($user_id), $msg)))
176
- {
177
- if (is_array($fields) && !empty($fields))
178
- foreach /* Custom Registration/Profile Fields. */ ($fields as $var => $val)
179
- if (!($msg = preg_replace ("/%%" . preg_quote ($var, "/") . "%%/i", c_ws_plugin__s2member_utils_strings::esc_refs (maybe_serialize ($val)), $msg)))
180
- break;
181
-
182
- if ($sbj && ($msg = trim (preg_replace ("/%%(.+?)%%/i", "", $msg)))) // Still have a ``$sbj`` and a ``$msg``?
183
-
184
- foreach (c_ws_plugin__s2member_utils_strings::parse_emails ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["payment_notification_recipients"]) as $recipient)
185
- wp_mail ($recipient, apply_filters("ws_plugin__s2member_payment_notification_email_sbj", $sbj, get_defined_vars ()), apply_filters("ws_plugin__s2member_payment_notification_email_msg", $msg, get_defined_vars ()), "Content-Type: text/plain; charset=UTF-8");
186
- }
187
  }
188
- $paypal["s2member_log"][] = "Payment Notification Emails have been processed.";
189
- }
190
- foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;
191
- do_action("ws_plugin__s2member_during_paypal_notify_during_subscr_payment", get_defined_vars ());
192
- unset($__refs, $__v);
193
- }
194
- else // Otherwise, we need to re-generate/store this IPN into a Transient Queue. Then re-process it on registration.
195
- {
196
- $paypal["s2member_log"][] = "Skipping this IPN response, for now. The Subscr. ID is not associated with a registered Member.";
197
-
198
- $ipn = array("txn_type" => "subscr_payment"); // Create a simulated IPN response for txn_type=subscr_payment.
199
-
200
- foreach ($paypal as $var => $val)
201
- if (in_array($var, array("subscr_gateway", "subscr_id", "subscr_baid", "subscr_cid", "txn_id", "custom", "invoice", "mc_gross", "mc_currency", "tax", "payer_email", "first_name", "last_name", "item_name", "item_number", "option_name1", "option_selection1", "option_name2", "option_selection2")))
202
- $ipn[$var] = $val;
203
-
204
- $paypal["s2member_log"][] = "Re-generating. This IPN will go into a Transient Queue; and be re-processed during registration.";
205
-
206
- set_transient ("s2m_" . md5 ("s2member_transient_ipn_subscr_payment_" . $paypal["subscr_id"]), $ipn, 43200);
207
- }
208
- }
209
- else // Else, this is a duplicate IPN. Must stop here.
210
- {
211
- $paypal["s2member_log"][] = "Not processing. Duplicate IPN.";
212
- $paypal["s2member_log"][] = "s2Member `txn_type` identified as ( `subscr_payment|recurring_payment` ).";
213
- $paypal["s2member_log"][] = "Duplicate IPN. Already processed. This IPN will be ignored.";
214
- }
215
- foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;
216
- do_action("ws_plugin__s2member_during_paypal_notify_after_subscr_payment", get_defined_vars ());
217
- unset($__refs, $__v);
218
-
219
- return apply_filters("c_ws_plugin__s2member_paypal_notify_in_subscr_or_rp_payment_w_level", $paypal, get_defined_vars ());
220
- }
221
- else return apply_filters("c_ws_plugin__s2member_paypal_notify_in_subscr_or_rp_payment_w_level", false, get_defined_vars ());
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
222
  }
 
 
 
 
 
 
 
 
 
 
 
 
223
  }
224
- }
 
 
 
1
  <?php
2
  /**
3
+ * s2Member's PayPal IPN handler (inner processing routine).
4
+ *
5
+ * Copyright: © 2009-2011
6
+ * {@link http://www.websharks-inc.com/ WebSharks, Inc.}
7
+ * (coded in the USA)
8
+ *
9
+ * Released under the terms of the GNU General Public License.
10
+ * You should have received a copy of the GNU General Public License,
11
+ * along with this software. In the main directory, see: /licensing/
12
+ * If not, see: {@link http://www.gnu.org/licenses/}.
13
+ *
14
+ * @package s2Member\PayPal
15
+ * @since 110720
16
+ */
17
+ if(realpath(__FILE__) === realpath($_SERVER['SCRIPT_FILENAME']))
18
+ exit ('Do not access this file directly.');
19
+
20
+ if(!class_exists('c_ws_plugin__s2member_paypal_notify_in_subscr_or_rp_payment_w_level'))
21
+ {
22
+ /**
23
+ * s2Member's PayPal IPN handler (inner processing routine).
24
+ *
25
+ * @package s2Member\PayPal
26
+ * @since 110720
27
+ */
28
+ class c_ws_plugin__s2member_paypal_notify_in_subscr_or_rp_payment_w_level
29
  {
30
  /**
31
+ * s2Member's PayPal IPN handler (inner processing routine).
32
+ *
33
+ * @package s2Member\PayPal
34
+ * @since 110720
35
+ *
36
+ * @param array $vars Required. An array of defined variables passed by {@link s2Member\PayPal\c_ws_plugin__s2member_paypal_notify_in::paypal_notify()}.
37
+ *
38
+ * @return array|bool The original ``$paypal`` array passed in (extracted) from ``$vars``, or false when conditions do NOT apply.
39
+ */
40
+ public static function cp($vars = array()) // Conditional phase for ``c_ws_plugin__s2member_paypal_notify_in::paypal_notify()``.
41
+ {
42
+ extract($vars, EXTR_OVERWRITE | EXTR_REFS); // Extract all vars passed in from: ``c_ws_plugin__s2member_paypal_notify_in::paypal_notify()``.
43
+
44
+ if((!empty($paypal['txn_type']) && preg_match('/^(subscr_payment|recurring_payment|merch_pmt)$/i', $paypal['txn_type']))
45
+ && ((!empty($paypal['item_number']) || ($paypal['item_number'] = c_ws_plugin__s2member_paypal_utilities::paypal_pro_item_number($paypal))) && preg_match($GLOBALS['WS_PLUGIN__']['s2member']['c']['membership_item_number_w_level_regex'], $paypal['item_number']))
46
+ && (!empty($paypal['subscr_id']) || ($paypal['subscr_id'] = c_ws_plugin__s2member_paypal_utilities::paypal_pro_subscr_id($paypal)))
47
+ && (empty($paypal['payment_status']) || empty($payment_status_issues) || !preg_match($payment_status_issues, $paypal['payment_status']))
48
+ && (!empty($paypal['item_name']) || ($paypal['item_name'] = c_ws_plugin__s2member_paypal_utilities::paypal_pro_item_name($paypal)))
49
+ && (!empty($paypal['payer_email']) || ($paypal['payer_email'] = c_ws_plugin__s2member_utils_users::get_user_email_with($paypal['subscr_id'])))
50
+ && (!empty($paypal['subscr_baid']) || ($paypal['subscr_baid'] = $paypal['subscr_id']))
51
+ && (!empty($paypal['subscr_cid']) || ($paypal['subscr_cid'] = $paypal['subscr_id']))
52
+ && (!empty($paypal['txn_id'])) && (!empty($paypal['mc_gross']))
53
+ )
54
  {
55
+ foreach(array_keys(get_defined_vars()) as $__v) $__refs[$__v] =& $$__v;
56
+ do_action('ws_plugin__s2member_during_paypal_notify_before_subscr_payment', get_defined_vars());
57
+ unset($__refs, $__v);
58
+
59
+ if(!get_transient($transient_ipn = 's2m_ipn_'.md5('s2member_transient_'.$_paypal_s)) && set_transient($transient_ipn, time(), 31556926 * 10))
60
+ {
61
+ $paypal['s2member_log'][] = 's2Member `txn_type` identified as '.($identified_as = '( `subscr_payment|recurring_payment` )').'.';
62
+
63
+ if(empty($_REQUEST['s2member_paypal_proxy'])) // Only on true PayPal IPNs; e.g. we can bypass this on proxied IPNs.
64
+ {
65
+ $paypal['s2member_log'][] = 'Sleeping for 5 seconds. Waiting for a possible ( `subscr_signup|subscr_modify|recurring_payment_profile_created` ).';
66
+ sleep(5); // Sleep here for a moment. PayPal sometimes sends a subscr_payment before the subscr_signup, subscr_modify.
67
+ $paypal['s2member_log'][] = 'Awake. It\'s '.date('D M j, Y g:i:s a T').'. s2Member `txn_type` identified as '.$identified_as.'.';
68
+ }
69
+ list($paypal['level'], $paypal['ccaps']) = preg_split('/\:/', $paypal['item_number'], 3);
70
+
71
+ $paypal['ip'] = (preg_match('/ip address/i', $paypal['option_name2']) && $paypal['option_selection2']) ? $paypal['option_selection2'] : '';
72
+ $paypal['ip'] = (!$paypal['ip'] && preg_match('/^[a-z0-9]+~[0-9\.]+$/i', $paypal['invoice'])) ? preg_replace('/^[a-z0-9]+~/i', '', $paypal['invoice']) : $paypal['ip'];
73
+
74
+ $paypal['currency'] = strtoupper($paypal['mc_currency']); // Normalize input currency.
75
+ $paypal['currency_symbol'] = c_ws_plugin__s2member_utils_cur::symbol($paypal['currency']);
76
+
77
+ if(($user_id = c_ws_plugin__s2member_utils_users::get_user_id_with($paypal['subscr_id'])) && is_object($user = new WP_User ($user_id)) && $user->ID)
78
  {
79
+ $processing = $during = TRUE; // Yes, we ARE processing this.
80
+
81
+ $pr_times = get_user_option('s2member_paid_registration_times', $user_id);
82
+ $pr_times['level'] = (!$pr_times['level']) ? time() : $pr_times['level']; // Preserves existing.
83
+ $pr_times['level'.$paypal['level']] = (!$pr_times['level'.$paypal['level']]) ? time() : $pr_times['level'.$paypal['level']];
84
+ update_user_option($user_id, 's2member_paid_registration_times', $pr_times); // Update now.
85
+
86
+ if(!get_user_option('s2member_first_payment_txn_id', $user_id)) // 1st payment?
87
+ update_user_option($user_id, 's2member_first_payment_txn_id', $paypal['txn_id']);
88
+
89
+ update_user_option($user_id, 's2member_last_payment_time', time()); // Also update last payment time.
90
+
91
+ $paypal['s2member_log'][] = 'Updated Payment Times for this Member.'; // Flag this action in the log.
92
+
93
+ $fields = get_user_option('s2member_custom_fields', $user_id); // These will be needed in the routines below.
94
+ $user_reg_ip = get_user_option('s2member_registration_ip', $user_id); // Original IP during Registration.
95
+ $user_reg_ip = $paypal['ip'] = ($user_reg_ip) ? $user_reg_ip : $paypal['ip']; // Now merge conditionally.
96
+
97
+ if($processing && $GLOBALS['WS_PLUGIN__']['s2member']['o']['payment_notification_urls'] && is_array($cv = preg_split('/\|/', $paypal['custom'])))
98
+ {
99
+ foreach(preg_split('/['."\r\n\t".']+/', $GLOBALS['WS_PLUGIN__']['s2member']['o']['payment_notification_urls']) as $url)
100
+
101
+ if(($url = preg_replace('/%%cv([0-9]+)%%/ei', 'urlencode(trim(@$cv[$1]))', $url)) && ($url = preg_replace('/%%subscr_id%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($paypal['subscr_id'])), $url)))
102
+ if(($url = preg_replace('/%%subscr_baid%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($paypal['subscr_baid'])), $url)) && ($url = preg_replace('/%%subscr_cid%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($paypal['subscr_cid'])), $url)))
103
+ if(($url = preg_replace('/%%currency%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($paypal['currency'])), $url)) && ($url = preg_replace('/%%currency_symbol%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($paypal['currency_symbol'])), $url)))
104
+ if(($url = preg_replace('/%%amount%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($paypal['mc_gross'])), $url)) && ($url = preg_replace('/%%txn_id%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($paypal['txn_id'])), $url)))
105
+ if(($url = preg_replace('/%%item_number%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($paypal['item_number'])), $url)) && ($url = preg_replace('/%%item_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($paypal['item_name'])), $url)))
106
+ if(($url = preg_replace('/%%first_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($paypal['first_name'])), $url)) && ($url = preg_replace('/%%last_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($paypal['last_name'])), $url)))
107
+ if(($url = preg_replace('/%%full_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode(trim($paypal['first_name'].' '.$paypal['last_name']))), $url)))
108
+ if(($url = preg_replace('/%%payer_email%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($paypal['payer_email'])), $url)))
109
+ {
110
+ if(($url = preg_replace('/%%user_first_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($user->first_name)), $url)) && ($url = preg_replace('/%%user_last_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($user->last_name)), $url)))
111
+ if(($url = preg_replace('/%%user_full_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode(trim($user->first_name.' '.$user->last_name))), $url)))
112
+ if(($url = preg_replace('/%%user_email%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($user->user_email)), $url)))
113
+ if(($url = preg_replace('/%%user_login%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($user->user_login)), $url)))
114
+ if(($url = preg_replace('/%%user_ip%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($user_reg_ip)), $url)))
115
+ if(($url = preg_replace('/%%user_id%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($user_id)), $url)))
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
116
  {
117
+ if(is_array($fields) && !empty($fields))
118
+ foreach($fields as $var => $val /* Custom Registration/Profile Fields. */)
119
+ if(!($url = preg_replace('/%%'.preg_quote($var, '/').'%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode(maybe_serialize($val))), $url)))
120
+ break;
121
+
122
+ if(($url = trim(preg_replace('/%%(.+?)%%/i', '', $url))))
123
+ c_ws_plugin__s2member_utils_urls::remote($url);
 
 
 
 
 
 
 
 
 
 
124
  }
125
+ }
126
+ $paypal['s2member_log'][] = 'Payment Notification URLs have been processed.';
127
+ }
128
+ if($processing && $GLOBALS['WS_PLUGIN__']['s2member']['o']['payment_notification_recipients'] && is_array($cv = preg_split('/\|/', $paypal['custom'])))
129
+ {
130
+ $msg = $sbj = '(s2Member / API Notification Email) - Payment';
131
+ $msg .= "\n\n"; // Spacing in the message body.
132
+
133
+ $msg .= 'subscr_id: %%subscr_id%%'."\n";
134
+ $msg .= 'subscr_baid: %%subscr_baid%%'."\n";
135
+ $msg .= 'subscr_cid: %%subscr_cid%%'."\n";
136
+ $msg .= 'currency: %%currency%%'."\n";
137
+ $msg .= 'currency_symbol: %%currency_symbol%%'."\n";
138
+ $msg .= 'amount: %%amount%%'."\n";
139
+ $msg .= 'txn_id: %%txn_id%%'."\n";
140
+ $msg .= 'item_number: %%item_number%%'."\n";
141
+ $msg .= 'item_name: %%item_name%%'."\n";
142
+ $msg .= 'first_name: %%first_name%%'."\n";
143
+ $msg .= 'last_name: %%last_name%%'."\n";
144
+ $msg .= 'full_name: %%full_name%%'."\n";
145
+ $msg .= 'payer_email: %%payer_email%%'."\n";
146
+
147
+ $msg .= 'user_first_name: %%user_first_name%%'."\n";
148
+ $msg .= 'user_last_name: %%user_last_name%%'."\n";
149
+ $msg .= 'user_full_name: %%user_full_name%%'."\n";
150
+ $msg .= 'user_email: %%user_email%%'."\n";
151
+ $msg .= 'user_login: %%user_login%%'."\n";
152
+ $msg .= 'user_ip: %%user_ip%%'."\n";
153
+ $msg .= 'user_id: %%user_id%%'."\n";
154
+
155
+ if(is_array($fields) && !empty($fields))
156
+ foreach($fields as $var => $val)
157
+ $msg .= $var.': %%'.$var.'%%'."\n";
158
+
159
+ $msg .= 'cv0: %%cv0%%'."\n";
160
+ $msg .= 'cv1: %%cv1%%'."\n";
161
+ $msg .= 'cv2: %%cv2%%'."\n";
162
+ $msg .= 'cv3: %%cv3%%'."\n";
163
+ $msg .= 'cv4: %%cv4%%'."\n";
164
+ $msg .= 'cv5: %%cv5%%'."\n";
165
+ $msg .= 'cv6: %%cv6%%'."\n";
166
+ $msg .= 'cv7: %%cv7%%'."\n";
167
+ $msg .= 'cv8: %%cv8%%'."\n";
168
+ $msg .= 'cv9: %%cv9%%';
169
+
170
+ if(($msg = preg_replace('/%%cv([0-9]+)%%/ei', 'trim(@$cv[$1])', $msg)) && ($msg = preg_replace('/%%subscr_id%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['subscr_id']), $msg)))
171
+ if(($msg = preg_replace('/%%subscr_baid%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['subscr_baid']), $msg)) && ($msg = preg_replace('/%%subscr_cid%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['subscr_cid']), $msg)))
172
+ if(($msg = preg_replace('/%%currency%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['currency']), $msg)) && ($msg = preg_replace('/%%currency_symbol%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['currency_symbol']), $msg)))
173
+ if(($msg = preg_replace('/%%amount%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['mc_gross']), $msg)) && ($msg = preg_replace('/%%txn_id%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['txn_id']), $msg)))
174
+ if(($msg = preg_replace('/%%item_number%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['item_number']), $msg)) && ($msg = preg_replace('/%%item_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['item_name']), $msg)))
175
+ if(($msg = preg_replace('/%%first_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['first_name']), $msg)) && ($msg = preg_replace('/%%last_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['last_name']), $msg)))
176
+ if(($msg = preg_replace('/%%full_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(trim($paypal['first_name'].' '.$paypal['last_name'])), $msg)))
177
+ if(($msg = preg_replace('/%%payer_email%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['payer_email']), $msg)))
178
+ {
179
+ if(($msg = preg_replace('/%%user_first_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($user->first_name), $msg)) && ($msg = preg_replace('/%%user_last_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($user->last_name), $msg)))
180
+ if(($msg = preg_replace('/%%user_full_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(trim($user->first_name.' '.$user->last_name)), $msg)))
181
+ if(($msg = preg_replace('/%%user_email%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($user->user_email), $msg)))
182
+ if(($msg = preg_replace('/%%user_login%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($user->user_login), $msg)))
183
+ if(($msg = preg_replace('/%%user_ip%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($user_reg_ip), $msg)))
184
+ if(($msg = preg_replace('/%%user_id%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($user_id), $msg)))
185
+ {
186
+ if(is_array($fields) && !empty($fields))
187
+ foreach($fields as $var => $val /* Custom Registration/Profile Fields. */)
188
+ if(!($msg = preg_replace('/%%'.preg_quote($var, '/').'%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(maybe_serialize($val)), $msg)))
189
+ break;
190
+
191
+ if($sbj && ($msg = trim(preg_replace('/%%(.+?)%%/i', '', $msg)))) // Still have a ``$sbj`` and a ``$msg``?
192
+
193
+ foreach(c_ws_plugin__s2member_utils_strings::parse_emails($GLOBALS['WS_PLUGIN__']['s2member']['o']['payment_notification_recipients']) as $recipient)
194
+ wp_mail($recipient, apply_filters('ws_plugin__s2member_payment_notification_email_sbj', $sbj, get_defined_vars()), apply_filters('ws_plugin__s2member_payment_notification_email_msg', $msg, get_defined_vars()), 'Content-Type: text/plain; charset=UTF-8');
195
+ }
196
+ }
197
+ $paypal['s2member_log'][] = 'Payment Notification Emails have been processed.';
198
+ }
199
+ foreach(array_keys(get_defined_vars()) as $__v) $__refs[$__v] =& $$__v;
200
+ do_action('ws_plugin__s2member_during_paypal_notify_during_subscr_payment', get_defined_vars());
201
+ unset($__refs, $__v);
202
+ }
203
+ else // Otherwise, we need to re-generate/store this IPN into a Transient Queue. Then re-process it on registration.
204
+ {
205
+ $paypal['s2member_log'][] = 'Skipping this IPN response, for now. The Subscr. ID is not associated with a registered Member.';
206
+
207
+ $ipn = array('txn_type' => 'subscr_payment'); // Create a simulated IPN response for txn_type=subscr_payment.
208
+
209
+ foreach($paypal as $var => $val)
210
+ if(in_array($var, array('subscr_gateway', 'subscr_id', 'subscr_baid', 'subscr_cid', 'txn_id', 'custom', 'invoice', 'mc_gross', 'mc_currency', 'tax', 'payer_email', 'first_name', 'last_name', 'item_name', 'item_number', 'option_name1', 'option_selection1', 'option_name2', 'option_selection2')))
211
+ $ipn[$var] = $val;
212
+
213
+ $paypal['s2member_log'][] = 'Re-generating. This IPN will go into a Transient Queue; and be re-processed during registration.';
214
+
215
+ set_transient('s2m_'.md5('s2member_transient_ipn_subscr_payment_'.$paypal['subscr_id']), $ipn, 43200);
216
  }
217
+ }
218
+ else // Else, this is a duplicate IPN. Must stop here.
219
+ {
220
+ $paypal['s2member_log'][] = 'Not processing. Duplicate IPN.';
221
+ $paypal['s2member_log'][] = 's2Member `txn_type` identified as ( `subscr_payment|recurring_payment` ).';
222
+ $paypal['s2member_log'][] = 'Duplicate IPN. Already processed. This IPN will be ignored.';
223
+ }
224
+ foreach(array_keys(get_defined_vars()) as $__v) $__refs[$__v] =& $$__v;
225
+ do_action('ws_plugin__s2member_during_paypal_notify_after_subscr_payment', get_defined_vars());
226
+ unset($__refs, $__v);
227
+
228
+ return apply_filters('c_ws_plugin__s2member_paypal_notify_in_subscr_or_rp_payment_w_level', $paypal, get_defined_vars());
229
  }
230
+ else return apply_filters('c_ws_plugin__s2member_paypal_notify_in_subscr_or_rp_payment_w_level', FALSE, get_defined_vars());
231
+ }
232
+ }
233
+ }
includes/classes/paypal-notify-in-subscr-or-wa-w-level.inc.php CHANGED
@@ -73,11 +73,13 @@ if(!class_exists('c_ws_plugin__s2member_paypal_notify_in_subscr_or_wa_w_level'))
73
  $paypal['period3'] = ($paypal['eotper']) ? $paypal['eotper'] : '1 L'; // 1 lifetime.
74
  $paypal['mc_amount3'] = $paypal['mc_gross']; // The 'Buy Now' amount is the full gross.
75
  }
76
- $paypal['initial_term'] = (preg_match('/^[1-9]/', $paypal['period1'])) ? $paypal['period1'] : '0 D';
77
- $paypal['initial'] = isset($paypal['mc_amount1'][0]) && preg_match('/^[1-9]/', $paypal['period1']) ? $paypal['mc_amount1'] : $paypal['mc_amount3'];
78
- $paypal['regular'] = $paypal['mc_amount3']; // This is the regular payment amount that is charged to the customer. always required by PayPal.
79
- $paypal['regular_term'] = $paypal['period3']; // This is just set to keep a standard; this way both initial_term & regular_term are available.
80
- $paypal['recurring'] = !empty($paypal['recurring']) ? $paypal['mc_amount3'] : '0'; // If non-recurring, this should be zero, otherwise regular.
 
 
81
 
82
  $ipn_signup_vars = $paypal; // Create array of IPN signup vars w/o s2member_log.
83
  unset($ipn_signup_vars['s2member_log']);
@@ -165,113 +167,117 @@ if(!class_exists('c_ws_plugin__s2member_paypal_notify_in_subscr_or_wa_w_level'))
165
 
166
  if(($rec = preg_replace('/%%cv([0-9]+)%%/ei', 'trim(@$cv[$1])', $rec)) && ($rec = preg_replace('/%%subscr_id%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['subscr_id']), $rec)))
167
  if(($rec = preg_replace('/%%subscr_baid%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['subscr_baid']), $rec)) && ($rec = preg_replace('/%%subscr_cid%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['subscr_cid']), $rec)))
168
- if(($rec = preg_replace('/%%initial%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['initial']), $rec)) && ($rec = preg_replace('/%%regular%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['regular']), $rec)))
169
- if(($rec = preg_replace('/%%initial_term%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['initial_term']), $rec)) && ($rec = preg_replace('/%%regular_term%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['regular_term']), $rec)))
170
- if(($rec = preg_replace('/%%initial_cycle%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(c_ws_plugin__s2member_utils_time::period_term($paypal['initial_term'])), $rec)) && ($rec = preg_replace('/%%regular_cycle%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(c_ws_plugin__s2member_utils_time::period_term($paypal['regular_term'], $paypal['recurring'])), $rec)))
171
- if(($rec = preg_replace('/%%recurring%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['recurring']), $rec)) && ($rec = preg_replace('/%%recurring\/regular_cycle%%/i', c_ws_plugin__s2member_utils_strings::esc_refs((($paypal['recurring']) ? $paypal['recurring'].' / '.c_ws_plugin__s2member_utils_time::period_term($paypal['regular_term'], TRUE) : '0 / non-recurring')), $rec)))
172
- if(($rec = preg_replace('/%%item_number%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['item_number']), $rec)) && ($rec = preg_replace('/%%item_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['item_name']), $rec)))
173
- if(($rec = preg_replace('/%%first_name%%/i', c_ws_plugin__s2member_utils_strings::esc_dq(c_ws_plugin__s2member_utils_strings::esc_refs($paypal['first_name'])), $rec)) && ($rec = preg_replace('/%%last_name%%/i', c_ws_plugin__s2member_utils_strings::esc_dq(c_ws_plugin__s2member_utils_strings::esc_refs($paypal['last_name'])), $rec)))
174
- if(($rec = preg_replace('/%%full_name%%/i', c_ws_plugin__s2member_utils_strings::esc_dq(c_ws_plugin__s2member_utils_strings::esc_refs(trim($paypal['first_name'].' '.$paypal['last_name']))), $rec))) // **NOTE** c_ws_plugin__s2member_utils_strings::esc_dq() is applied here. (ex. 'N\'ame' <email>).
175
- if(($rec = preg_replace('/%%payer_email%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['payer_email']), $rec)))
176
-
177
- if(($rec = preg_replace('/%%full_coupon_code%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($coupon['full_coupon_code']), $rec)) && ($rec = preg_replace('/%%coupon_code%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($coupon['coupon_code']), $rec)) && ($rec = preg_replace('/%%coupon_affiliate_id%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($coupon['affiliate_id']), $rec)))
178
-
179
- if(($rec = preg_replace('/%%user_first_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($user->first_name), $rec)) && ($rec = preg_replace('/%%user_last_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($user->last_name), $rec)))
180
- if(($rec = preg_replace('/%%user_full_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(trim($user->first_name.' '.$user->last_name)), $rec)))
181
- if(($rec = preg_replace('/%%user_email%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($user->user_email), $rec)))
182
- if(($rec = preg_replace('/%%user_login%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($user->user_login), $rec)))
183
- if(($rec = preg_replace('/%%user_ip%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($user_reg_ip), $rec)))
184
- if(($rec = preg_replace('/%%user_id%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($user_id), $rec)))
185
-
186
- if(($sbj = preg_replace('/%%cv([0-9]+)%%/ei', 'trim(@$cv[$1])', $sbj)) && ($sbj = preg_replace('/%%subscr_id%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['subscr_id']), $sbj)))
187
- if(($sbj = preg_replace('/%%subscr_baid%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['subscr_baid']), $sbj)) && ($sbj = preg_replace('/%%subscr_cid%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['subscr_cid']), $sbj)))
188
- if(($sbj = preg_replace('/%%initial%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['initial']), $sbj)) && ($sbj = preg_replace('/%%regular%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['regular']), $sbj)))
189
- if(($sbj = preg_replace('/%%initial_term%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['initial_term']), $sbj)) && ($sbj = preg_replace('/%%regular_term%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['regular_term']), $sbj)))
190
- if(($sbj = preg_replace('/%%initial_cycle%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(c_ws_plugin__s2member_utils_time::period_term($paypal['initial_term'])), $sbj)) && ($sbj = preg_replace('/%%regular_cycle%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(c_ws_plugin__s2member_utils_time::period_term($paypal['regular_term'], $paypal['recurring'])), $sbj)))
191
- if(($sbj = preg_replace('/%%recurring%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['recurring']), $sbj)) && ($sbj = preg_replace('/%%recurring\/regular_cycle%%/i', c_ws_plugin__s2member_utils_strings::esc_refs((($paypal['recurring']) ? $paypal['recurring'].' / '.c_ws_plugin__s2member_utils_time::period_term($paypal['regular_term'], TRUE) : '0 / non-recurring')), $sbj)))
192
- if(($sbj = preg_replace('/%%item_number%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['item_number']), $sbj)) && ($sbj = preg_replace('/%%item_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['item_name']), $sbj)))
193
- if(($sbj = preg_replace('/%%first_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['first_name']), $sbj)) && ($sbj = preg_replace('/%%last_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['last_name']), $sbj)))
194
- if(($sbj = preg_replace('/%%full_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(trim($paypal['first_name'].' '.$paypal['last_name'])), $sbj)))
195
- if(($sbj = preg_replace('/%%payer_email%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['payer_email']), $sbj)))
196
-
197
- if(($sbj = preg_replace('/%%full_coupon_code%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($coupon['full_coupon_code']), $sbj)) && ($sbj = preg_replace('/%%coupon_code%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($coupon['coupon_code']), $sbj)) && ($sbj = preg_replace('/%%coupon_affiliate_id%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($coupon['affiliate_id']), $sbj)))
198
-
199
- if(($sbj = preg_replace('/%%user_first_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($user->first_name), $sbj)) && ($sbj = preg_replace('/%%user_last_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($user->last_name), $sbj)))
200
- if(($sbj = preg_replace('/%%user_full_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(trim($user->first_name.' '.$user->last_name)), $sbj)))
201
- if(($sbj = preg_replace('/%%user_email%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($user->user_email), $sbj)))
202
- if(($sbj = preg_replace('/%%user_login%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($user->user_login), $sbj)))
203
- if(($sbj = preg_replace('/%%user_ip%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($user_reg_ip), $sbj)))
204
- if(($sbj = preg_replace('/%%user_id%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($user_id), $sbj)))
205
-
206
- if(($msg = preg_replace('/%%cv([0-9]+)%%/ei', 'trim(@$cv[$1])', $msg)) && ($msg = preg_replace('/%%subscr_id%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['subscr_id']), $msg)))
207
- if(($msg = preg_replace('/%%subscr_baid%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['subscr_baid']), $msg)) && ($msg = preg_replace('/%%subscr_cid%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['subscr_cid']), $msg)))
208
- if(($msg = preg_replace('/%%initial%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['initial']), $msg)) && ($msg = preg_replace('/%%regular%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['regular']), $msg)))
209
- if(($msg = preg_replace('/%%initial_term%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['initial_term']), $msg)) && ($msg = preg_replace('/%%regular_term%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['regular_term']), $msg)))
210
- if(($msg = preg_replace('/%%initial_cycle%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(c_ws_plugin__s2member_utils_time::period_term($paypal['initial_term'])), $msg)) && ($msg = preg_replace('/%%regular_cycle%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(c_ws_plugin__s2member_utils_time::period_term($paypal['regular_term'], $paypal['recurring'])), $msg)))
211
- if(($msg = preg_replace('/%%recurring%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['recurring']), $msg)) && ($msg = preg_replace('/%%recurring\/regular_cycle%%/i', c_ws_plugin__s2member_utils_strings::esc_refs((($paypal['recurring']) ? $paypal['recurring'].' / '.c_ws_plugin__s2member_utils_time::period_term($paypal['regular_term'], TRUE) : '0 / non-recurring')), $msg)))
212
- if(($msg = preg_replace('/%%item_number%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['item_number']), $msg)) && ($msg = preg_replace('/%%item_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['item_name']), $msg)))
213
- if(($msg = preg_replace('/%%first_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['first_name']), $msg)) && ($msg = preg_replace('/%%last_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['last_name']), $msg)))
214
- if(($msg = preg_replace('/%%full_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(trim($paypal['first_name'].' '.$paypal['last_name'])), $msg)))
215
- if(($msg = preg_replace('/%%payer_email%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['payer_email']), $msg)))
216
-
217
- if(($msg = preg_replace('/%%full_coupon_code%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($coupon['full_coupon_code']), $msg)) && ($msg = preg_replace('/%%coupon_code%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($coupon['coupon_code']), $msg)) && ($msg = preg_replace('/%%coupon_affiliate_id%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($coupon['affiliate_id']), $msg)))
218
-
219
- if(($msg = preg_replace('/%%user_first_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($user->first_name), $msg)) && ($msg = preg_replace('/%%user_last_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($user->last_name), $msg)))
220
- if(($msg = preg_replace('/%%user_full_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(trim($user->first_name.' '.$user->last_name)), $msg)))
221
- if(($msg = preg_replace('/%%user_email%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($user->user_email), $msg)))
222
- if(($msg = preg_replace('/%%user_login%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($user->user_login), $msg)))
223
- if(($msg = preg_replace('/%%user_ip%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($user_reg_ip), $msg)))
224
- if(($msg = preg_replace('/%%user_id%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($user_id), $msg)))
225
- {
226
- if(is_array($fields) && !empty($fields)) foreach($fields as $var => $val /* Custom Registration/Profile Fields. */)
227
- {
228
- $rec = preg_replace('/%%'.preg_quote($var, '/').'%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(maybe_serialize($val)), $rec);
229
- $sbj = preg_replace('/%%'.preg_quote($var, '/').'%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(maybe_serialize($val)), $sbj);
230
- $msg = preg_replace('/%%'.preg_quote($var, '/').'%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(maybe_serialize($val)), $msg);
231
- }
232
- if(($rec = trim(preg_replace('/%%(.+?)%%/i', '', $rec))) && ($sbj = trim(preg_replace('/%%(.+?)%%/i', '', $sbj))) && ($msg = trim(preg_replace('/%%(.+?)%%/i', '', $msg))))
233
- {
234
- if(!is_multisite() || !c_ws_plugin__s2member_utils_conds::is_multisite_farm() || is_main_site())
235
- {
236
- $sbj = c_ws_plugin__s2member_utilities::evl($sbj, get_defined_vars());
237
- $msg = c_ws_plugin__s2member_utilities::evl($msg, get_defined_vars());
238
- }
239
- foreach(c_ws_plugin__s2member_utils_strings::parse_emails($rec) as $recipient /* Go through a possible list of recipients. */)
240
- c_ws_plugin__s2member_email_configs::email_config().wp_mail($recipient, apply_filters('ws_plugin__s2member_modification_email_sbj', $sbj, get_defined_vars()), apply_filters('ws_plugin__s2member_modification_email_msg', $msg, get_defined_vars()), 'From: "'.preg_replace('/"/', "'", $GLOBALS['WS_PLUGIN__']['s2member']['o']['reg_email_from_name']).'" <'.$GLOBALS['WS_PLUGIN__']['s2member']['o']['reg_email_from_email'].'>'."\r\n".'Content-Type: text/plain; charset=UTF-8').c_ws_plugin__s2member_email_configs::email_config_release();
241
-
242
- $paypal['s2member_log'][] = 'Modification Confirmation Email sent to: '.$rec.'.';
243
- }
244
- }
 
 
 
245
  if($processing && $GLOBALS['WS_PLUGIN__']['s2member']['o']['modification_notification_urls'] && is_array($cv = preg_split('/\|/', $paypal['custom'])))
246
  {
247
  foreach(preg_split('/['."\r\n\t".']+/', $GLOBALS['WS_PLUGIN__']['s2member']['o']['modification_notification_urls']) as $url)
248
 
249
  if(($url = preg_replace('/%%cv([0-9]+)%%/ei', 'urlencode(trim(@$cv[$1]))', $url)) && ($url = preg_replace('/%%subscr_id%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($paypal['subscr_id'])), $url)))
250
  if(($url = preg_replace('/%%subscr_baid%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($paypal['subscr_baid'])), $url)) && ($url = preg_replace('/%%subscr_cid%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($paypal['subscr_cid'])), $url)))
251
- if(($url = preg_replace('/%%initial%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($paypal['initial'])), $url)) && ($url = preg_replace('/%%regular%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($paypal['regular'])), $url)) && ($url = preg_replace('/%%recurring%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($paypal['recurring'])), $url)))
252
- if(($url = preg_replace('/%%initial_term%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($paypal['initial_term'])), $url)) && ($url = preg_replace('/%%regular_term%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($paypal['regular_term'])), $url)))
253
- if(($url = preg_replace('/%%item_number%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($paypal['item_number'])), $url)) && ($url = preg_replace('/%%item_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($paypal['item_name'])), $url)))
254
- if(($url = preg_replace('/%%first_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($paypal['first_name'])), $url)) && ($url = preg_replace('/%%last_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($paypal['last_name'])), $url)))
255
- if(($url = preg_replace('/%%full_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode(trim($paypal['first_name'].' '.$paypal['last_name']))), $url)))
256
- if(($url = preg_replace('/%%payer_email%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($paypal['payer_email'])), $url)))
257
-
258
- if(($url = preg_replace('/%%full_coupon_code%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($coupon['full_coupon_code'])), $url)) && ($url = preg_replace('/%%coupon_code%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($coupon['coupon_code'])), $url)) && ($url = preg_replace('/%%coupon_affiliate_id%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($coupon['affiliate_id'])), $url)))
259
-
260
- if(($url = preg_replace('/%%user_first_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($user->first_name)), $url)) && ($url = preg_replace('/%%user_last_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($user->last_name)), $url)))
261
- if(($url = preg_replace('/%%user_full_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode(trim($user->first_name.' '.$user->last_name))), $url)))
262
- if(($url = preg_replace('/%%user_email%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($user->user_email)), $url)))
263
- if(($url = preg_replace('/%%user_login%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($user->user_login)), $url)))
264
- if(($url = preg_replace('/%%user_ip%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($user_reg_ip)), $url)))
265
- if(($url = preg_replace('/%%user_id%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($user_id)), $url)))
266
- {
267
- if(is_array($fields) && !empty($fields))
268
- foreach($fields as $var => $val /* Custom Registration/Profile Fields. */)
269
- if(!($url = preg_replace('/%%'.preg_quote($var, '/').'%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode(maybe_serialize($val))), $url)))
270
- break;
271
-
272
- if(($url = trim(preg_replace('/%%(.+?)%%/i', '', $url))))
273
- c_ws_plugin__s2member_utils_urls::remote($url);
274
- }
 
275
  $paypal['s2member_log'][] = 'Modification Notification URLs have been processed.';
276
  }
277
  if($processing && $GLOBALS['WS_PLUGIN__']['s2member']['o']['modification_notification_recipients'] && is_array($cv = preg_split('/\|/', $paypal['custom'])))
@@ -282,6 +288,8 @@ if(!class_exists('c_ws_plugin__s2member_paypal_notify_in_subscr_or_wa_w_level'))
282
  $msg .= 'subscr_id: %%subscr_id%%'."\n";
283
  $msg .= 'subscr_baid: %%subscr_baid%%'."\n";
284
  $msg .= 'subscr_cid: %%subscr_cid%%'."\n";
 
 
285
  $msg .= 'initial: %%initial%%'."\n";
286
  $msg .= 'regular: %%regular%%'."\n";
287
  $msg .= 'recurring: %%recurring%%'."\n";
@@ -323,65 +331,67 @@ if(!class_exists('c_ws_plugin__s2member_paypal_notify_in_subscr_or_wa_w_level'))
323
 
324
  if(($msg = preg_replace('/%%cv([0-9]+)%%/ei', 'trim(@$cv[$1])', $msg)) && ($msg = preg_replace('/%%subscr_id%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['subscr_id']), $msg)))
325
  if(($msg = preg_replace('/%%subscr_baid%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['subscr_baid']), $msg)) && ($msg = preg_replace('/%%subscr_cid%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['subscr_cid']), $msg)))
326
- if(($msg = preg_replace('/%%initial%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['initial']), $msg)) && ($msg = preg_replace('/%%regular%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['regular']), $msg)) && ($msg = preg_replace('/%%recurring%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['recurring']), $msg)))
327
- if(($msg = preg_replace('/%%initial_term%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['initial_term']), $msg)) && ($msg = preg_replace('/%%regular_term%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['regular_term']), $msg)))
328
- if(($msg = preg_replace('/%%item_number%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['item_number']), $msg)) && ($msg = preg_replace('/%%item_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['item_name']), $msg)))
329
- if(($msg = preg_replace('/%%first_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['first_name']), $msg)) && ($msg = preg_replace('/%%last_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['last_name']), $msg)))
330
- if(($msg = preg_replace('/%%full_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(trim($paypal['first_name'].' '.$paypal['last_name'])), $msg)))
331
- if(($msg = preg_replace('/%%payer_email%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['payer_email']), $msg)))
332
-
333
- if(($msg = preg_replace('/%%full_coupon_code%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($coupon['full_coupon_code']), $msg)) && ($msg = preg_replace('/%%coupon_code%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($coupon['coupon_code']), $msg)) && ($msg = preg_replace('/%%coupon_affiliate_id%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($coupon['affiliate_id']), $msg)))
334
-
335
- if(($msg = preg_replace('/%%user_first_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($user->first_name), $msg)) && ($msg = preg_replace('/%%user_last_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($user->last_name), $msg)))
336
- if(($msg = preg_replace('/%%user_full_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(trim($user->first_name.' '.$user->last_name)), $msg)))
337
- if(($msg = preg_replace('/%%user_email%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($user->user_email), $msg)))
338
- if(($msg = preg_replace('/%%user_login%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($user->user_login), $msg)))
339
- if(($msg = preg_replace('/%%user_ip%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($user_reg_ip), $msg)))
340
- if(($msg = preg_replace('/%%user_id%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($user_id), $msg)))
341
- {
342
- if(is_array($fields) && !empty($fields))
343
- foreach($fields as $var => $val /* Custom Registration/Profile Fields. */)
344
- if(!($msg = preg_replace('/%%'.preg_quote($var, '/').'%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(maybe_serialize($val)), $msg)))
345
- break;
 
346
 
347
- if($sbj && ($msg = trim(preg_replace('/%%(.+?)%%/i', '', $msg)))) // Still have a ``$sbj`` and a ``$msg``?
348
 
349
- foreach(c_ws_plugin__s2member_utils_strings::parse_emails($GLOBALS['WS_PLUGIN__']['s2member']['o']['modification_notification_recipients']) as $recipient)
350
- wp_mail($recipient, apply_filters('ws_plugin__s2member_modification_notification_email_sbj', $sbj, get_defined_vars()), apply_filters('ws_plugin__s2member_modification_notification_email_msg', $msg, get_defined_vars()), 'Content-Type: text/plain; charset=UTF-8');
351
- }
352
  $paypal['s2member_log'][] = 'Modification Notification Emails have been processed.';
353
  }
354
  if($processing && ($code = $GLOBALS['WS_PLUGIN__']['s2member']['o']['modification_tracking_codes']) && is_array($cv = preg_split('/\|/', $paypal['custom'])))
355
  {
356
  if(($code = preg_replace('/%%cv([0-9]+)%%/ei', 'trim(@$cv[$1])', $code)) && ($code = preg_replace('/%%subscr_id%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['subscr_id']), $code)))
357
  if(($code = preg_replace('/%%subscr_baid%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['subscr_baid']), $code)) && ($code = preg_replace('/%%subscr_cid%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['subscr_cid']), $code)))
358
- if(($code = preg_replace('/%%initial%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['initial']), $code)) && ($code = preg_replace('/%%regular%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['regular']), $code)) && ($code = preg_replace('/%%recurring%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['recurring']), $code)))
359
- if(($code = preg_replace('/%%initial_term%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['initial_term']), $code)) && ($code = preg_replace('/%%regular_term%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['regular_term']), $code)))
360
- if(($code = preg_replace('/%%item_number%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['item_number']), $code)) && ($code = preg_replace('/%%item_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['item_name']), $code)))
361
- if(($code = preg_replace('/%%first_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['first_name']), $code)) && ($code = preg_replace('/%%last_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['last_name']), $code)))
362
- if(($code = preg_replace('/%%full_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(trim($paypal['first_name'].' '.$paypal['last_name'])), $code)))
363
- if(($code = preg_replace('/%%payer_email%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['payer_email']), $code)))
364
-
365
- if(($code = preg_replace('/%%full_coupon_code%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($coupon['full_coupon_code']), $code)) && ($code = preg_replace('/%%coupon_code%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($coupon['coupon_code']), $code)) && ($code = preg_replace('/%%coupon_affiliate_id%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($coupon['affiliate_id']), $code)))
366
-
367
- if(($code = preg_replace('/%%user_first_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($user->first_name), $code)) && ($code = preg_replace('/%%user_last_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($user->last_name), $code)))
368
- if(($code = preg_replace('/%%user_full_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(trim($user->first_name.' '.$user->last_name)), $code)))
369
- if(($code = preg_replace('/%%user_email%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($user->user_email), $code)))
370
- if(($code = preg_replace('/%%user_login%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($user->user_login), $code)))
371
- if(($code = preg_replace('/%%user_ip%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($user_reg_ip), $code)))
372
- if(($code = preg_replace('/%%user_id%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($user_id), $code)))
373
- {
374
- if(is_array($fields) && !empty($fields))
375
- foreach($fields as $var => $val /* Custom Registration/Profile Fields. */)
376
- if(!($code = preg_replace('/%%'.preg_quote($var, '/').'%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(maybe_serialize($val)), $code)))
377
- break;
378
-
379
- if(($code = trim(preg_replace('/%%(.+?)%%/i', '', $code))) /* This gets stored into a transient queue. */)
380
  {
381
- $paypal['s2member_log'][] = 'Storing Modification Tracking Codes into a Transient Queue. These will be processed on-site.';
382
- set_transient('s2m_'.md5('s2member_transient_modification_tracking_codes_'.$paypal['subscr_id']), $code, 43200);
 
 
 
 
 
 
 
 
383
  }
384
- }
385
  }
386
  foreach(array_keys(get_defined_vars()) as $__v) $__refs[$__v] =& $$__v;
387
  do_action('ws_plugin__s2member_during_paypal_notify_during_subscr_signup_w_update_vars', get_defined_vars());
@@ -416,72 +426,76 @@ if(!class_exists('c_ws_plugin__s2member_paypal_notify_in_subscr_or_wa_w_level'))
416
 
417
  if(($rec = preg_replace('/%%cv([0-9]+)%%/ei', 'trim(@$cv[$1])', $rec)) && ($rec = preg_replace('/%%subscr_id%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['subscr_id']), $rec)))
418
  if(($rec = preg_replace('/%%subscr_baid%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['subscr_baid']), $rec)) && ($rec = preg_replace('/%%subscr_cid%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['subscr_cid']), $rec)))
419
- if(($rec = preg_replace('/%%initial%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['initial']), $rec)) && ($rec = preg_replace('/%%regular%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['regular']), $rec)))
420
- if(($rec = preg_replace('/%%initial_term%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['initial_term']), $rec)) && ($rec = preg_replace('/%%regular_term%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['regular_term']), $rec)))
421
- if(($rec = preg_replace('/%%initial_cycle%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(c_ws_plugin__s2member_utils_time::period_term($paypal['initial_term'])), $rec)) && ($rec = preg_replace('/%%regular_cycle%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(c_ws_plugin__s2member_utils_time::period_term($paypal['regular_term'], $paypal['recurring'])), $rec)))
422
- if(($rec = preg_replace('/%%recurring%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['recurring']), $rec)) && ($rec = preg_replace('/%%recurring\/regular_cycle%%/i', c_ws_plugin__s2member_utils_strings::esc_refs((($paypal['recurring']) ? $paypal['recurring'].' / '.c_ws_plugin__s2member_utils_time::period_term($paypal['regular_term'], TRUE) : '0 / non-recurring')), $rec)))
423
- if(($rec = preg_replace('/%%item_number%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['item_number']), $rec)) && ($rec = preg_replace('/%%item_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['item_name']), $rec)))
424
- if(($rec = preg_replace('/%%first_name%%/i', c_ws_plugin__s2member_utils_strings::esc_dq(c_ws_plugin__s2member_utils_strings::esc_refs($paypal['first_name'])), $rec)) && ($rec = preg_replace('/%%last_name%%/i', c_ws_plugin__s2member_utils_strings::esc_dq(c_ws_plugin__s2member_utils_strings::esc_refs($paypal['last_name'])), $rec)))
425
- if(($rec = preg_replace('/%%full_name%%/i', c_ws_plugin__s2member_utils_strings::esc_dq(c_ws_plugin__s2member_utils_strings::esc_refs(trim($paypal['first_name'].' '.$paypal['last_name']))), $rec))) // **NOTE** c_ws_plugin__s2member_utils_strings::esc_dq() is applied here. (ex. "N\"ame" <email>).
426
- if(($rec = preg_replace('/%%payer_email%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['payer_email']), $rec)))
427
- if(($rec = preg_replace('/%%user_ip%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['ip']), $rec)))
428
- if(($rec = preg_replace('/%%full_coupon_code%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($coupon['full_coupon_code']), $rec)) && ($rec = preg_replace('/%%coupon_code%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($coupon['coupon_code']), $rec)) && ($rec = preg_replace('/%%coupon_affiliate_id%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($coupon['affiliate_id']), $rec)))
429
-
430
- if(($sbj = preg_replace('/%%cv([0-9]+)%%/ei', 'trim(@$cv[$1])', $sbj)) && ($sbj = preg_replace('/%%subscr_id%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['subscr_id']), $sbj)))
431
- if(($sbj = preg_replace('/%%subscr_baid%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['subscr_baid']), $sbj)) && ($sbj = preg_replace('/%%subscr_cid%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['subscr_cid']), $sbj)))
432
- if(($sbj = preg_replace('/%%initial%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['initial']), $sbj)) && ($sbj = preg_replace('/%%regular%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['regular']), $sbj)))
433
- if(($sbj = preg_replace('/%%initial_term%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['initial_term']), $sbj)) && ($sbj = preg_replace('/%%regular_term%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['regular_term']), $sbj)))
434
- if(($sbj = preg_replace('/%%initial_cycle%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(c_ws_plugin__s2member_utils_time::period_term($paypal['initial_term'])), $sbj)) && ($sbj = preg_replace('/%%regular_cycle%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(c_ws_plugin__s2member_utils_time::period_term($paypal['regular_term'], $paypal['recurring'])), $sbj)))
435
- if(($sbj = preg_replace('/%%recurring%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['recurring']), $sbj)) && ($sbj = preg_replace('/%%recurring\/regular_cycle%%/i', c_ws_plugin__s2member_utils_strings::esc_refs((($paypal['recurring']) ? $paypal['recurring'].' / '.c_ws_plugin__s2member_utils_time::period_term($paypal['regular_term'], TRUE) : '0 / non-recurring')), $sbj)))
436
- if(($sbj = preg_replace('/%%item_number%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['item_number']), $sbj)) && ($sbj = preg_replace('/%%item_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['item_name']), $sbj)))
437
- if(($sbj = preg_replace('/%%first_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['first_name']), $sbj)) && ($sbj = preg_replace('/%%last_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['last_name']), $sbj)))
438
- if(($sbj = preg_replace('/%%full_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(trim($paypal['first_name'].' '.$paypal['last_name'])), $sbj)))
439
- if(($sbj = preg_replace('/%%payer_email%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['payer_email']), $sbj)))
440
- if(($sbj = preg_replace('/%%user_ip%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['ip']), $sbj)))
441
- if(($sbj = preg_replace('/%%full_coupon_code%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($coupon['full_coupon_code']), $sbj)) && ($sbj = preg_replace('/%%coupon_code%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($coupon['coupon_code']), $sbj)) && ($sbj = preg_replace('/%%coupon_affiliate_id%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($coupon['affiliate_id']), $sbj)))
442
-
443
- if(($msg = preg_replace('/%%cv([0-9]+)%%/ei', 'trim(@$cv[$1])', $msg)) && ($msg = preg_replace('/%%subscr_id%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['subscr_id']), $msg)))
444
- if(($msg = preg_replace('/%%subscr_baid%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['subscr_baid']), $msg)) && ($msg = preg_replace('/%%subscr_cid%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['subscr_cid']), $msg)))
445
- if(($msg = preg_replace('/%%initial%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['initial']), $msg)) && ($msg = preg_replace('/%%regular%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['regular']), $msg)))
446
- if(($msg = preg_replace('/%%initial_term%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['initial_term']), $msg)) && ($msg = preg_replace('/%%regular_term%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['regular_term']), $msg)))
447
- if(($msg = preg_replace('/%%initial_cycle%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(c_ws_plugin__s2member_utils_time::period_term($paypal['initial_term'])), $msg)) && ($msg = preg_replace('/%%regular_cycle%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(c_ws_plugin__s2member_utils_time::period_term($paypal['regular_term'], $paypal['recurring'])), $msg)))
448
- if(($msg = preg_replace('/%%recurring%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['recurring']), $msg)) && ($msg = preg_replace('/%%recurring\/regular_cycle%%/i', c_ws_plugin__s2member_utils_strings::esc_refs((($paypal['recurring']) ? $paypal['recurring'].' / '.c_ws_plugin__s2member_utils_time::period_term($paypal['regular_term'], TRUE) : '0 / non-recurring')), $msg)))
449
- if(($msg = preg_replace('/%%item_number%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['item_number']), $msg)) && ($msg = preg_replace('/%%item_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['item_name']), $msg)))
450
- if(($msg = preg_replace('/%%first_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['first_name']), $msg)) && ($msg = preg_replace('/%%last_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['last_name']), $msg)))
451
- if(($msg = preg_replace('/%%full_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(trim($paypal['first_name'].' '.$paypal['last_name'])), $msg)))
452
- if(($msg = preg_replace('/%%payer_email%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['payer_email']), $msg)))
453
- if(($msg = preg_replace('/%%user_ip%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['ip']), $msg)))
454
- if(($msg = preg_replace('/%%full_coupon_code%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($coupon['full_coupon_code']), $msg)) && ($msg = preg_replace('/%%coupon_code%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($coupon['coupon_code']), $msg)) && ($msg = preg_replace('/%%coupon_affiliate_id%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($coupon['affiliate_id']), $msg)))
455
-
456
- if(($rec = trim(preg_replace('/%%(.+?)%%/i', '', $rec))) && ($sbj = trim(preg_replace('/%%(.+?)%%/i', '', $sbj))) && ($msg = trim(preg_replace('/%%(.+?)%%/i', '', $msg))))
457
- {
458
- if(!is_multisite() || !c_ws_plugin__s2member_utils_conds::is_multisite_farm() || is_main_site())
459
- {
460
- $sbj = c_ws_plugin__s2member_utilities::evl($sbj, get_defined_vars());
461
- $msg = c_ws_plugin__s2member_utilities::evl($msg, get_defined_vars());
462
- }
463
- foreach(c_ws_plugin__s2member_utils_strings::parse_emails($rec) as $recipient) // Go through a possible list of recipients.
464
- c_ws_plugin__s2member_email_configs::email_config().wp_mail($recipient, apply_filters('ws_plugin__s2member_signup_email_sbj', $sbj, get_defined_vars()), apply_filters('ws_plugin__s2member_signup_email_msg', $msg, get_defined_vars()), 'From: "'.preg_replace('/"/', "'", $GLOBALS['WS_PLUGIN__']['s2member']['o']['reg_email_from_name']).'" <'.$GLOBALS['WS_PLUGIN__']['s2member']['o']['reg_email_from_email'].'>'."\r\n".'Content-Type: text/plain; charset=UTF-8').c_ws_plugin__s2member_email_configs::email_config_release();
465
-
466
- $paypal['s2member_log'][] = 'Signup Confirmation Email sent to: '.$rec.'.';
467
- }
 
 
 
468
  if($processing && $GLOBALS['WS_PLUGIN__']['s2member']['o']['signup_notification_urls'] && is_array($cv = preg_split('/\|/', $paypal['custom'])))
469
  {
470
  foreach(preg_split('/['."\r\n\t".']+/', $GLOBALS['WS_PLUGIN__']['s2member']['o']['signup_notification_urls']) as $url)
471
 
472
  if(($url = preg_replace('/%%cv([0-9]+)%%/ei', 'urlencode(trim(@$cv[$1]))', $url)) && ($url = preg_replace('/%%subscr_id%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($paypal['subscr_id'])), $url)))
473
  if(($url = preg_replace('/%%subscr_baid%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($paypal['subscr_baid'])), $url)) && ($url = preg_replace('/%%subscr_cid%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($paypal['subscr_cid'])), $url)))
474
- if(($url = preg_replace('/%%initial%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($paypal['initial'])), $url)) && ($url = preg_replace('/%%regular%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($paypal['regular'])), $url)) && ($url = preg_replace('/%%recurring%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($paypal['recurring'])), $url)))
475
- if(($url = preg_replace('/%%initial_term%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($paypal['initial_term'])), $url)) && ($url = preg_replace('/%%regular_term%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($paypal['regular_term'])), $url)))
476
- if(($url = preg_replace('/%%item_number%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($paypal['item_number'])), $url)) && ($url = preg_replace('/%%item_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($paypal['item_name'])), $url)))
477
- if(($url = preg_replace('/%%first_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($paypal['first_name'])), $url)) && ($url = preg_replace('/%%last_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($paypal['last_name'])), $url)))
478
- if(($url = preg_replace('/%%full_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode(trim($paypal['first_name'].' '.$paypal['last_name']))), $url)))
479
- if(($url = preg_replace('/%%payer_email%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($paypal['payer_email'])), $url)))
480
- if(($url = preg_replace('/%%user_ip%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($paypal['ip'])), $url)))
481
- if(($url = preg_replace('/%%full_coupon_code%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($coupon['full_coupon_code'])), $url)) && ($url = preg_replace('/%%coupon_code%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($coupon['coupon_code'])), $url)) && ($url = preg_replace('/%%coupon_affiliate_id%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($coupon['affiliate_id'])), $url)))
482
-
483
- if(($url = trim(preg_replace('/%%(.+?)%%/i', '', $url))))
484
- c_ws_plugin__s2member_utils_urls::remote($url);
 
485
 
486
  $paypal['s2member_log'][] = 'Signup Notification URLs have been processed.';
487
  }
@@ -493,6 +507,8 @@ if(!class_exists('c_ws_plugin__s2member_paypal_notify_in_subscr_or_wa_w_level'))
493
  $msg .= 'subscr_id: %%subscr_id%%'."\n";
494
  $msg .= 'subscr_baid: %%subscr_baid%%'."\n";
495
  $msg .= 'subscr_cid: %%subscr_cid%%'."\n";
 
 
496
  $msg .= 'initial: %%initial%%'."\n";
497
  $msg .= 'regular: %%regular%%'."\n";
498
  $msg .= 'recurring: %%recurring%%'."\n";
@@ -523,19 +539,20 @@ if(!class_exists('c_ws_plugin__s2member_paypal_notify_in_subscr_or_wa_w_level'))
523
 
524
  if(($msg = preg_replace('/%%cv([0-9]+)%%/ei', 'trim(@$cv[$1])', $msg)) && ($msg = preg_replace('/%%subscr_id%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['subscr_id']), $msg)))
525
  if(($msg = preg_replace('/%%subscr_baid%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['subscr_baid']), $msg)) && ($msg = preg_replace('/%%subscr_cid%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['subscr_cid']), $msg)))
526
- if(($msg = preg_replace('/%%initial%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['initial']), $msg)) && ($msg = preg_replace('/%%regular%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['regular']), $msg)) && ($msg = preg_replace('/%%recurring%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['recurring']), $msg)))
527
- if(($msg = preg_replace('/%%initial_term%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['initial_term']), $msg)) && ($msg = preg_replace('/%%regular_term%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['regular_term']), $msg)))
528
- if(($msg = preg_replace('/%%item_number%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['item_number']), $msg)) && ($msg = preg_replace('/%%item_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['item_name']), $msg)))
529
- if(($msg = preg_replace('/%%first_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['first_name']), $msg)) && ($msg = preg_replace('/%%last_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['last_name']), $msg)))
530
- if(($msg = preg_replace('/%%full_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(trim($paypal['first_name'].' '.$paypal['last_name'])), $msg)))
531
- if(($msg = preg_replace('/%%payer_email%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['payer_email']), $msg)))
532
- if(($msg = preg_replace('/%%user_ip%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['ip']), $msg)))
533
- if(($msg = preg_replace('/%%full_coupon_code%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($coupon['full_coupon_code']), $msg)) && ($msg = preg_replace('/%%coupon_code%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($coupon['coupon_code']), $msg)) && ($msg = preg_replace('/%%coupon_affiliate_id%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($coupon['affiliate_id']), $msg)))
 
534
 
535
- if($sbj && ($msg = trim(preg_replace('/%%(.+?)%%/i', '', $msg)))) // Still have a ``$sbj`` and a ``$msg``?
536
 
537
- foreach(c_ws_plugin__s2member_utils_strings::parse_emails($GLOBALS['WS_PLUGIN__']['s2member']['o']['signup_notification_recipients']) as $recipient)
538
- wp_mail($recipient, apply_filters('ws_plugin__s2member_signup_notification_email_sbj', $sbj, get_defined_vars()), apply_filters('ws_plugin__s2member_signup_notification_email_msg', $msg, get_defined_vars()), 'Content-Type: text/plain; charset=UTF-8');
539
 
540
  $paypal['s2member_log'][] = 'Signup Notification Emails have been processed.';
541
  }
@@ -543,20 +560,21 @@ if(!class_exists('c_ws_plugin__s2member_paypal_notify_in_subscr_or_wa_w_level'))
543
  {
544
  if(($code = preg_replace('/%%cv([0-9]+)%%/ei', 'trim(@$cv[$1])', $code)) && ($code = preg_replace('/%%subscr_id%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['subscr_id']), $code)))
545
  if(($code = preg_replace('/%%subscr_baid%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['subscr_baid']), $code)) && ($code = preg_replace('/%%subscr_cid%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['subscr_cid']), $code)))
546
- if(($code = preg_replace('/%%initial%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['initial']), $code)) && ($code = preg_replace('/%%regular%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['regular']), $code)) && ($code = preg_replace('/%%recurring%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['recurring']), $code)))
547
- if(($code = preg_replace('/%%initial_term%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['initial_term']), $code)) && ($code = preg_replace('/%%regular_term%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['regular_term']), $code)))
548
- if(($code = preg_replace('/%%item_number%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['item_number']), $code)) && ($code = preg_replace('/%%item_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['item_name']), $code)))
549
- if(($code = preg_replace('/%%first_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['first_name']), $code)) && ($code = preg_replace('/%%last_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['last_name']), $code)))
550
- if(($code = preg_replace('/%%full_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(trim($paypal['first_name'].' '.$paypal['last_name'])), $code)))
551
- if(($code = preg_replace('/%%payer_email%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['payer_email']), $code)))
552
- if(($code = preg_replace('/%%user_ip%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['ip']), $code)))
553
- if(($code = preg_replace('/%%full_coupon_code%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($coupon['full_coupon_code']), $code)) && ($code = preg_replace('/%%coupon_code%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($coupon['coupon_code']), $code)) && ($code = preg_replace('/%%coupon_affiliate_id%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($coupon['affiliate_id']), $code)))
554
-
555
- if(($code = trim(preg_replace('/%%(.+?)%%/i', '', $code))) /* This gets stored into a Transient Queue. */)
556
- {
557
- $paypal['s2member_log'][] = 'Storing Signup Tracking Codes into a Transient Queue. These will be processed on-site.';
558
- set_transient('s2m_'.md5('s2member_transient_signup_tracking_codes_'.$paypal['subscr_id']), $code, 43200);
559
- }
 
560
  }
561
  foreach(array_keys(get_defined_vars()) as $__v) $__refs[$__v] =& $$__v;
562
  do_action('ws_plugin__s2member_during_paypal_notify_during_subscr_signup_wo_update_vars', get_defined_vars());
@@ -577,31 +595,32 @@ if(!class_exists('c_ws_plugin__s2member_paypal_notify_in_subscr_or_wa_w_level'))
577
 
578
  if(($url = preg_replace('/%%cv([0-9]+)%%/ei', 'urlencode(trim(@$cv[$1]))', $url)) && ($url = preg_replace('/%%subscr_id%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($paypal['subscr_id'])), $url)))
579
  if(($url = preg_replace('/%%subscr_baid%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($paypal['subscr_baid'])), $url)) && ($url = preg_replace('/%%subscr_cid%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($paypal['subscr_cid'])), $url)))
580
- if(($url = preg_replace('/%%initial%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($paypal['initial'])), $url)) && ($url = preg_replace('/%%regular%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($paypal['regular'])), $url)) && ($url = preg_replace('/%%recurring%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($paypal['recurring'])), $url)))
581
- if(($url = preg_replace('/%%initial_term%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($paypal['initial_term'])), $url)) && ($url = preg_replace('/%%regular_term%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($paypal['regular_term'])), $url)))
582
- if(($url = preg_replace('/%%item_number%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($paypal['item_number'])), $url)) && ($url = preg_replace('/%%item_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($paypal['item_name'])), $url)))
583
- if(($url = preg_replace('/%%first_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($paypal['first_name'])), $url)) && ($url = preg_replace('/%%last_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($paypal['last_name'])), $url)))
584
- if(($url = preg_replace('/%%full_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode(trim($paypal['first_name'].' '.$paypal['last_name']))), $url)))
585
- if(($url = preg_replace('/%%payer_email%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($paypal['payer_email'])), $url)))
586
- if(($url = preg_replace('/%%modification%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode((int)$modifying)), $url)))
587
-
588
- if(($url = preg_replace('/%%full_coupon_code%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($coupon['full_coupon_code'])), $url)) && ($url = preg_replace('/%%coupon_code%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($coupon['coupon_code'])), $url)) && ($url = preg_replace('/%%coupon_affiliate_id%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($coupon['affiliate_id'])), $url)))
589
-
590
- if(($url = preg_replace('/%%user_first_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($user->first_name)), $url)) && ($url = preg_replace('/%%user_last_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($user->last_name)), $url)))
591
- if(($url = preg_replace('/%%user_full_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode(trim($user->first_name.' '.$user->last_name))), $url)))
592
- if(($url = preg_replace('/%%user_email%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($user->user_email)), $url)))
593
- if(($url = preg_replace('/%%user_login%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($user->user_login)), $url)))
594
- if(($url = preg_replace('/%%user_ip%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($user_reg_ip)), $url)))
595
- if(($url = preg_replace('/%%user_id%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($user_id)), $url)))
596
- {
597
- if(is_array($fields) && !empty($fields))
598
- foreach($fields as $var => $val /* Custom Registration/Profile Fields. */)
599
- if(!($url = preg_replace('/%%'.preg_quote($var, '/').'%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode(maybe_serialize($val))), $url)))
600
- break;
 
601
 
602
- if(($url = trim($url))) // Preserve remaining replacements; parent routine may perform replacements too.
603
- $paypal['s2member_paypal_proxy_return_url'] = $url;
604
- }
605
  }
606
  $paypal['s2member_log'][] = 'Subscr. Return ( `modification='.(int)$modifying.'` ), a Proxy Return URL is ready.';
607
  }
@@ -631,29 +650,30 @@ if(!class_exists('c_ws_plugin__s2member_paypal_notify_in_subscr_or_wa_w_level'))
631
 
632
  if(($url = preg_replace('/%%cv([0-9]+)%%/ei', 'urlencode(trim(@$cv[$1]))', $url)) && ($url = preg_replace('/%%subscr_id%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($paypal['subscr_id'])), $url)))
633
  if(($url = preg_replace('/%%subscr_baid%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($paypal['subscr_baid'])), $url)) && ($url = preg_replace('/%%subscr_cid%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($paypal['subscr_cid'])), $url)))
634
- if(($url = preg_replace('/%%amount%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($paypal['mc_gross'])), $url)) && ($url = preg_replace('/%%txn_id%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($paypal['txn_id'])), $url)))
635
- if(($url = preg_replace('/%%item_number%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($paypal['item_number'])), $url)) && ($url = preg_replace('/%%item_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($paypal['item_name'])), $url)))
636
- if(($url = preg_replace('/%%first_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($paypal['first_name'])), $url)) && ($url = preg_replace('/%%last_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($paypal['last_name'])), $url)))
637
- if(($url = preg_replace('/%%full_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode(trim($paypal['first_name'].' '.$paypal['last_name']))), $url)))
638
- if(($url = preg_replace('/%%payer_email%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($paypal['payer_email'])), $url)))
639
-
640
- if(($url = preg_replace('/%%full_coupon_code%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($coupon['full_coupon_code'])), $url)) && ($url = preg_replace('/%%coupon_code%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($coupon['coupon_code'])), $url)) && ($url = preg_replace('/%%coupon_affiliate_id%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($coupon['affiliate_id'])), $url)))
641
-
642
- if(($url = preg_replace('/%%user_first_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($user->first_name)), $url)) && ($url = preg_replace('/%%user_last_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($user->last_name)), $url)))
643
- if(($url = preg_replace('/%%user_full_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode(trim($user->first_name.' '.$user->last_name))), $url)))
644
- if(($url = preg_replace('/%%user_email%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($user->user_email)), $url)))
645
- if(($url = preg_replace('/%%user_login%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($user->user_login)), $url)))
646
- if(($url = preg_replace('/%%user_ip%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($user_reg_ip)), $url)))
647
- if(($url = preg_replace('/%%user_id%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($user_id)), $url)))
648
- {
649
- if(is_array($fields) && !empty($fields))
650
- foreach($fields as $var => $val /* Custom Registration/Profile Fields. */)
651
- if(!($url = preg_replace('/%%'.preg_quote($var, '/').'%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode(maybe_serialize($val))), $url)))
652
- break;
653
 
654
- if(($url = trim(preg_replace('/%%(.+?)%%/i', '', $url))))
655
- c_ws_plugin__s2member_utils_urls::remote($url);
656
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
657
  $paypal['s2member_log'][] = 'Payment Notification URLs have been processed.';
658
  }
659
  if($GLOBALS['WS_PLUGIN__']['s2member']['o']['payment_notification_recipients'] && is_array($cv = preg_split('/\|/', $paypal['custom'])))
@@ -664,6 +684,8 @@ if(!class_exists('c_ws_plugin__s2member_paypal_notify_in_subscr_or_wa_w_level'))
664
  $msg .= 'subscr_id: %%subscr_id%%'."\n";
665
  $msg .= 'subscr_baid: %%subscr_baid%%'."\n";
666
  $msg .= 'subscr_cid: %%subscr_cid%%'."\n";
 
 
667
  $msg .= 'amount: %%amount%%'."\n";
668
  $msg .= 'txn_id: %%txn_id%%'."\n";
669
  $msg .= 'item_number: %%item_number%%'."\n";
@@ -702,31 +724,32 @@ if(!class_exists('c_ws_plugin__s2member_paypal_notify_in_subscr_or_wa_w_level'))
702
 
703
  if(($msg = preg_replace('/%%cv([0-9]+)%%/ei', 'trim(@$cv[$1])', $msg)) && ($msg = preg_replace('/%%subscr_id%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['subscr_id']), $msg)))
704
  if(($msg = preg_replace('/%%subscr_baid%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['subscr_baid']), $msg)) && ($msg = preg_replace('/%%subscr_cid%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['subscr_cid']), $msg)))
705
- if(($msg = preg_replace('/%%amount%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['mc_gross']), $msg)) && ($msg = preg_replace('/%%txn_id%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['txn_id']), $msg)))
706
- if(($msg = preg_replace('/%%item_number%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['item_number']), $msg)) && ($msg = preg_replace('/%%item_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['item_name']), $msg)))
707
- if(($msg = preg_replace('/%%first_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['first_name']), $msg)) && ($msg = preg_replace('/%%last_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['last_name']), $msg)))
708
- if(($msg = preg_replace('/%%full_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(trim($paypal['first_name'].' '.$paypal['last_name'])), $msg)))
709
- if(($msg = preg_replace('/%%payer_email%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['payer_email']), $msg)))
710
-
711
- if(($msg = preg_replace('/%%full_coupon_code%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($coupon['full_coupon_code']), $msg)) && ($msg = preg_replace('/%%coupon_code%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($coupon['coupon_code']), $msg)) && ($msg = preg_replace('/%%coupon_affiliate_id%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($coupon['affiliate_id']), $msg)))
712
-
713
- if(($msg = preg_replace('/%%user_first_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($user->first_name), $msg)) && ($msg = preg_replace('/%%user_last_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($user->last_name), $msg)))
714
- if(($msg = preg_replace('/%%user_full_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(trim($user->first_name.' '.$user->last_name)), $msg)))
715
- if(($msg = preg_replace('/%%user_email%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($user->user_email), $msg)))
716
- if(($msg = preg_replace('/%%user_login%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($user->user_login), $msg)))
717
- if(($msg = preg_replace('/%%user_ip%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($user_reg_ip), $msg)))
718
- if(($msg = preg_replace('/%%user_id%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($user_id), $msg)))
719
- {
720
- if(is_array($fields) && !empty($fields))
721
- foreach($fields as $var => $val /* Custom Registration/Profile Fields. */)
722
- if(!($msg = preg_replace('/%%'.preg_quote($var, '/').'%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(maybe_serialize($val)), $msg)))
723
- break;
724
-
725
- if($sbj && ($msg = trim(preg_replace('/%%(.+?)%%/i', '', $msg)))) // Still have a ``$sbj`` and a ``$msg``?
726
-
727
- foreach(c_ws_plugin__s2member_utils_strings::parse_emails($GLOBALS['WS_PLUGIN__']['s2member']['o']['payment_notification_recipients']) as $recipient)
728
- wp_mail($recipient, apply_filters('ws_plugin__s2member_payment_notification_email_sbj', $sbj, get_defined_vars()), apply_filters('ws_plugin__s2member_payment_notification_email_msg', $msg, get_defined_vars()), 'Content-Type: text/plain; charset=UTF-8');
729
- }
 
730
  $paypal['s2member_log'][] = 'Payment Notification Emails have been processed.';
731
  }
732
  }
73
  $paypal['period3'] = ($paypal['eotper']) ? $paypal['eotper'] : '1 L'; // 1 lifetime.
74
  $paypal['mc_amount3'] = $paypal['mc_gross']; // The 'Buy Now' amount is the full gross.
75
  }
76
+ $paypal['initial_term'] = (preg_match('/^[1-9]/', $paypal['period1'])) ? $paypal['period1'] : '0 D';
77
+ $paypal['initial'] = isset($paypal['mc_amount1'][0]) && preg_match('/^[1-9]/', $paypal['period1']) ? $paypal['mc_amount1'] : $paypal['mc_amount3'];
78
+ $paypal['regular'] = $paypal['mc_amount3']; // This is the regular payment amount that is charged to the customer. always required by PayPal.
79
+ $paypal['regular_term'] = $paypal['period3']; // This is just set to keep a standard; this way both initial_term & regular_term are available.
80
+ $paypal['recurring'] = !empty($paypal['recurring']) ? $paypal['mc_amount3'] : '0'; // If non-recurring, this should be zero, otherwise regular.
81
+ $paypal['currency'] = strtoupper($paypal['mc_currency']); // Normalize input currency.
82
+ $paypal['currency_symbol'] = c_ws_plugin__s2member_utils_cur::symbol($paypal['currency']);
83
 
84
  $ipn_signup_vars = $paypal; // Create array of IPN signup vars w/o s2member_log.
85
  unset($ipn_signup_vars['s2member_log']);
167
 
168
  if(($rec = preg_replace('/%%cv([0-9]+)%%/ei', 'trim(@$cv[$1])', $rec)) && ($rec = preg_replace('/%%subscr_id%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['subscr_id']), $rec)))
169
  if(($rec = preg_replace('/%%subscr_baid%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['subscr_baid']), $rec)) && ($rec = preg_replace('/%%subscr_cid%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['subscr_cid']), $rec)))
170
+ if(($rec = preg_replace('/%%currency%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['currency']), $rec)) && ($rec = preg_replace('/%%currency_symbol%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['currency_symbol']), $rec)))
171
+ if(($rec = preg_replace('/%%initial%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['initial']), $rec)) && ($rec = preg_replace('/%%regular%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['regular']), $rec)))
172
+ if(($rec = preg_replace('/%%initial_term%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['initial_term']), $rec)) && ($rec = preg_replace('/%%regular_term%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['regular_term']), $rec)))
173
+ if(($rec = preg_replace('/%%initial_cycle%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(c_ws_plugin__s2member_utils_time::period_term($paypal['initial_term'])), $rec)) && ($rec = preg_replace('/%%regular_cycle%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(c_ws_plugin__s2member_utils_time::period_term($paypal['regular_term'], $paypal['recurring'])), $rec)))
174
+ if(($rec = preg_replace('/%%recurring%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['recurring']), $rec)) && ($rec = preg_replace('/%%recurring\/regular_cycle%%/i', c_ws_plugin__s2member_utils_strings::esc_refs((($paypal['recurring']) ? $paypal['recurring'].' / '.c_ws_plugin__s2member_utils_time::period_term($paypal['regular_term'], TRUE) : '0 / non-recurring')), $rec)))
175
+ if(($rec = preg_replace('/%%item_number%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['item_number']), $rec)) && ($rec = preg_replace('/%%item_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['item_name']), $rec)))
176
+ if(($rec = preg_replace('/%%first_name%%/i', c_ws_plugin__s2member_utils_strings::esc_dq(c_ws_plugin__s2member_utils_strings::esc_refs($paypal['first_name'])), $rec)) && ($rec = preg_replace('/%%last_name%%/i', c_ws_plugin__s2member_utils_strings::esc_dq(c_ws_plugin__s2member_utils_strings::esc_refs($paypal['last_name'])), $rec)))
177
+ if(($rec = preg_replace('/%%full_name%%/i', c_ws_plugin__s2member_utils_strings::esc_dq(c_ws_plugin__s2member_utils_strings::esc_refs(trim($paypal['first_name'].' '.$paypal['last_name']))), $rec))) // **NOTE** c_ws_plugin__s2member_utils_strings::esc_dq() is applied here. (ex. 'N\'ame' <email>).
178
+ if(($rec = preg_replace('/%%payer_email%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['payer_email']), $rec)))
179
+
180
+ if(($rec = preg_replace('/%%full_coupon_code%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($coupon['full_coupon_code']), $rec)) && ($rec = preg_replace('/%%coupon_code%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($coupon['coupon_code']), $rec)) && ($rec = preg_replace('/%%coupon_affiliate_id%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($coupon['affiliate_id']), $rec)))
181
+
182
+ if(($rec = preg_replace('/%%user_first_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($user->first_name), $rec)) && ($rec = preg_replace('/%%user_last_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($user->last_name), $rec)))
183
+ if(($rec = preg_replace('/%%user_full_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(trim($user->first_name.' '.$user->last_name)), $rec)))
184
+ if(($rec = preg_replace('/%%user_email%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($user->user_email), $rec)))
185
+ if(($rec = preg_replace('/%%user_login%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($user->user_login), $rec)))
186
+ if(($rec = preg_replace('/%%user_ip%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($user_reg_ip), $rec)))
187
+ if(($rec = preg_replace('/%%user_id%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($user_id), $rec)))
188
+
189
+ if(($sbj = preg_replace('/%%cv([0-9]+)%%/ei', 'trim(@$cv[$1])', $sbj)) && ($sbj = preg_replace('/%%subscr_id%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['subscr_id']), $sbj)))
190
+ if(($sbj = preg_replace('/%%subscr_baid%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['subscr_baid']), $sbj)) && ($sbj = preg_replace('/%%subscr_cid%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['subscr_cid']), $sbj)))
191
+ if(($sbj = preg_replace('/%%currency%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['currency']), $sbj)) && ($sbj = preg_replace('/%%currency_symbol%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['currency_symbol']), $sbj)))
192
+ if(($sbj = preg_replace('/%%initial%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['initial']), $sbj)) && ($sbj = preg_replace('/%%regular%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['regular']), $sbj)))
193
+ if(($sbj = preg_replace('/%%initial_term%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['initial_term']), $sbj)) && ($sbj = preg_replace('/%%regular_term%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['regular_term']), $sbj)))
194
+ if(($sbj = preg_replace('/%%initial_cycle%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(c_ws_plugin__s2member_utils_time::period_term($paypal['initial_term'])), $sbj)) && ($sbj = preg_replace('/%%regular_cycle%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(c_ws_plugin__s2member_utils_time::period_term($paypal['regular_term'], $paypal['recurring'])), $sbj)))
195
+ if(($sbj = preg_replace('/%%recurring%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['recurring']), $sbj)) && ($sbj = preg_replace('/%%recurring\/regular_cycle%%/i', c_ws_plugin__s2member_utils_strings::esc_refs((($paypal['recurring']) ? $paypal['recurring'].' / '.c_ws_plugin__s2member_utils_time::period_term($paypal['regular_term'], TRUE) : '0 / non-recurring')), $sbj)))
196
+ if(($sbj = preg_replace('/%%item_number%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['item_number']), $sbj)) && ($sbj = preg_replace('/%%item_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['item_name']), $sbj)))
197
+ if(($sbj = preg_replace('/%%first_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['first_name']), $sbj)) && ($sbj = preg_replace('/%%last_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['last_name']), $sbj)))
198
+ if(($sbj = preg_replace('/%%full_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(trim($paypal['first_name'].' '.$paypal['last_name'])), $sbj)))
199
+ if(($sbj = preg_replace('/%%payer_email%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['payer_email']), $sbj)))
200
+
201
+ if(($sbj = preg_replace('/%%full_coupon_code%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($coupon['full_coupon_code']), $sbj)) && ($sbj = preg_replace('/%%coupon_code%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($coupon['coupon_code']), $sbj)) && ($sbj = preg_replace('/%%coupon_affiliate_id%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($coupon['affiliate_id']), $sbj)))
202
+
203
+ if(($sbj = preg_replace('/%%user_first_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($user->first_name), $sbj)) && ($sbj = preg_replace('/%%user_last_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($user->last_name), $sbj)))
204
+ if(($sbj = preg_replace('/%%user_full_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(trim($user->first_name.' '.$user->last_name)), $sbj)))
205
+ if(($sbj = preg_replace('/%%user_email%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($user->user_email), $sbj)))
206
+ if(($sbj = preg_replace('/%%user_login%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($user->user_login), $sbj)))
207
+ if(($sbj = preg_replace('/%%user_ip%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($user_reg_ip), $sbj)))
208
+ if(($sbj = preg_replace('/%%user_id%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($user_id), $sbj)))
209
+
210
+ if(($msg = preg_replace('/%%cv([0-9]+)%%/ei', 'trim(@$cv[$1])', $msg)) && ($msg = preg_replace('/%%subscr_id%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['subscr_id']), $msg)))
211
+ if(($msg = preg_replace('/%%subscr_baid%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['subscr_baid']), $msg)) && ($msg = preg_replace('/%%subscr_cid%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['subscr_cid']), $msg)))
212
+ if(($msg = preg_replace('/%%currency%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['currency']), $msg)) && ($msg = preg_replace('/%%currency_symbol%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['currency_symbol']), $msg)))
213
+ if(($msg = preg_replace('/%%initial%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['initial']), $msg)) && ($msg = preg_replace('/%%regular%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['regular']), $msg)))
214
+ if(($msg = preg_replace('/%%initial_term%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['initial_term']), $msg)) && ($msg = preg_replace('/%%regular_term%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['regular_term']), $msg)))
215
+ if(($msg = preg_replace('/%%initial_cycle%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(c_ws_plugin__s2member_utils_time::period_term($paypal['initial_term'])), $msg)) && ($msg = preg_replace('/%%regular_cycle%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(c_ws_plugin__s2member_utils_time::period_term($paypal['regular_term'], $paypal['recurring'])), $msg)))
216
+ if(($msg = preg_replace('/%%recurring%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['recurring']), $msg)) && ($msg = preg_replace('/%%recurring\/regular_cycle%%/i', c_ws_plugin__s2member_utils_strings::esc_refs((($paypal['recurring']) ? $paypal['recurring'].' / '.c_ws_plugin__s2member_utils_time::period_term($paypal['regular_term'], TRUE) : '0 / non-recurring')), $msg)))
217
+ if(($msg = preg_replace('/%%item_number%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['item_number']), $msg)) && ($msg = preg_replace('/%%item_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['item_name']), $msg)))
218
+ if(($msg = preg_replace('/%%first_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['first_name']), $msg)) && ($msg = preg_replace('/%%last_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['last_name']), $msg)))
219
+ if(($msg = preg_replace('/%%full_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(trim($paypal['first_name'].' '.$paypal['last_name'])), $msg)))
220
+ if(($msg = preg_replace('/%%payer_email%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['payer_email']), $msg)))
221
+
222
+ if(($msg = preg_replace('/%%full_coupon_code%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($coupon['full_coupon_code']), $msg)) && ($msg = preg_replace('/%%coupon_code%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($coupon['coupon_code']), $msg)) && ($msg = preg_replace('/%%coupon_affiliate_id%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($coupon['affiliate_id']), $msg)))
223
+
224
+ if(($msg = preg_replace('/%%user_first_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($user->first_name), $msg)) && ($msg = preg_replace('/%%user_last_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($user->last_name), $msg)))
225
+ if(($msg = preg_replace('/%%user_full_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(trim($user->first_name.' '.$user->last_name)), $msg)))
226
+ if(($msg = preg_replace('/%%user_email%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($user->user_email), $msg)))
227
+ if(($msg = preg_replace('/%%user_login%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($user->user_login), $msg)))
228
+ if(($msg = preg_replace('/%%user_ip%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($user_reg_ip), $msg)))
229
+ if(($msg = preg_replace('/%%user_id%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($user_id), $msg)))
230
+ {
231
+ if(is_array($fields) && !empty($fields)) foreach($fields as $var => $val /* Custom Registration/Profile Fields. */)
232
+ {
233
+ $rec = preg_replace('/%%'.preg_quote($var, '/').'%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(maybe_serialize($val)), $rec);
234
+ $sbj = preg_replace('/%%'.preg_quote($var, '/').'%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(maybe_serialize($val)), $sbj);
235
+ $msg = preg_replace('/%%'.preg_quote($var, '/').'%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(maybe_serialize($val)), $msg);
236
+ }
237
+ if(($rec = trim(preg_replace('/%%(.+?)%%/i', '', $rec))) && ($sbj = trim(preg_replace('/%%(.+?)%%/i', '', $sbj))) && ($msg = trim(preg_replace('/%%(.+?)%%/i', '', $msg))))
238
+ {
239
+ if(!is_multisite() || !c_ws_plugin__s2member_utils_conds::is_multisite_farm() || is_main_site())
240
+ {
241
+ $sbj = c_ws_plugin__s2member_utilities::evl($sbj, get_defined_vars());
242
+ $msg = c_ws_plugin__s2member_utilities::evl($msg, get_defined_vars());
243
+ }
244
+ foreach(c_ws_plugin__s2member_utils_strings::parse_emails($rec) as $recipient /* Go through a possible list of recipients. */)
245
+ c_ws_plugin__s2member_email_configs::email_config().wp_mail($recipient, apply_filters('ws_plugin__s2member_modification_email_sbj', $sbj, get_defined_vars()), apply_filters('ws_plugin__s2member_modification_email_msg', $msg, get_defined_vars()), 'From: "'.preg_replace('/"/', "'", $GLOBALS['WS_PLUGIN__']['s2member']['o']['reg_email_from_name']).'" <'.$GLOBALS['WS_PLUGIN__']['s2member']['o']['reg_email_from_email'].'>'."\r\n".'Content-Type: text/plain; charset=UTF-8').c_ws_plugin__s2member_email_configs::email_config_release();
246
+
247
+ $paypal['s2member_log'][] = 'Modification Confirmation Email sent to: '.$rec.'.';
248
+ }
249
+ }
250
  if($processing && $GLOBALS['WS_PLUGIN__']['s2member']['o']['modification_notification_urls'] && is_array($cv = preg_split('/\|/', $paypal['custom'])))
251
  {
252
  foreach(preg_split('/['."\r\n\t".']+/', $GLOBALS['WS_PLUGIN__']['s2member']['o']['modification_notification_urls']) as $url)
253
 
254
  if(($url = preg_replace('/%%cv([0-9]+)%%/ei', 'urlencode(trim(@$cv[$1]))', $url)) && ($url = preg_replace('/%%subscr_id%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($paypal['subscr_id'])), $url)))
255
  if(($url = preg_replace('/%%subscr_baid%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($paypal['subscr_baid'])), $url)) && ($url = preg_replace('/%%subscr_cid%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($paypal['subscr_cid'])), $url)))
256
+ if(($url = preg_replace('/%%currency%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($paypal['currency'])), $url)) && ($url = preg_replace('/%%currency_symbol%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($paypal['currency_symbol'])), $url)))
257
+ if(($url = preg_replace('/%%initial%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($paypal['initial'])), $url)) && ($url = preg_replace('/%%regular%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($paypal['regular'])), $url)) && ($url = preg_replace('/%%recurring%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($paypal['recurring'])), $url)))
258
+ if(($url = preg_replace('/%%initial_term%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($paypal['initial_term'])), $url)) && ($url = preg_replace('/%%regular_term%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($paypal['regular_term'])), $url)))
259
+ if(($url = preg_replace('/%%item_number%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($paypal['item_number'])), $url)) && ($url = preg_replace('/%%item_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($paypal['item_name'])), $url)))
260
+ if(($url = preg_replace('/%%first_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($paypal['first_name'])), $url)) && ($url = preg_replace('/%%last_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($paypal['last_name'])), $url)))
261
+ if(($url = preg_replace('/%%full_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode(trim($paypal['first_name'].' '.$paypal['last_name']))), $url)))
262
+ if(($url = preg_replace('/%%payer_email%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($paypal['payer_email'])), $url)))
263
+
264
+ if(($url = preg_replace('/%%full_coupon_code%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($coupon['full_coupon_code'])), $url)) && ($url = preg_replace('/%%coupon_code%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($coupon['coupon_code'])), $url)) && ($url = preg_replace('/%%coupon_affiliate_id%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($coupon['affiliate_id'])), $url)))
265
+
266
+ if(($url = preg_replace('/%%user_first_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($user->first_name)), $url)) && ($url = preg_replace('/%%user_last_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($user->last_name)), $url)))
267
+ if(($url = preg_replace('/%%user_full_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode(trim($user->first_name.' '.$user->last_name))), $url)))
268
+ if(($url = preg_replace('/%%user_email%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($user->user_email)), $url)))
269
+ if(($url = preg_replace('/%%user_login%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($user->user_login)), $url)))
270
+ if(($url = preg_replace('/%%user_ip%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($user_reg_ip)), $url)))
271
+ if(($url = preg_replace('/%%user_id%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($user_id)), $url)))
272
+ {
273
+ if(is_array($fields) && !empty($fields))
274
+ foreach($fields as $var => $val /* Custom Registration/Profile Fields. */)
275
+ if(!($url = preg_replace('/%%'.preg_quote($var, '/').'%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode(maybe_serialize($val))), $url)))
276
+ break;
277
+
278
+ if(($url = trim(preg_replace('/%%(.+?)%%/i', '', $url))))
279
+ c_ws_plugin__s2member_utils_urls::remote($url);
280
+ }
281
  $paypal['s2member_log'][] = 'Modification Notification URLs have been processed.';
282
  }
283
  if($processing && $GLOBALS['WS_PLUGIN__']['s2member']['o']['modification_notification_recipients'] && is_array($cv = preg_split('/\|/', $paypal['custom'])))
288
  $msg .= 'subscr_id: %%subscr_id%%'."\n";
289
  $msg .= 'subscr_baid: %%subscr_baid%%'."\n";
290
  $msg .= 'subscr_cid: %%subscr_cid%%'."\n";
291
+ $msg .= 'currency: %%currency%%'."\n";
292
+ $msg .= 'currency_symbol: %%currency_symbol%%'."\n";
293
  $msg .= 'initial: %%initial%%'."\n";
294
  $msg .= 'regular: %%regular%%'."\n";
295
  $msg .= 'recurring: %%recurring%%'."\n";
331
 
332
  if(($msg = preg_replace('/%%cv([0-9]+)%%/ei', 'trim(@$cv[$1])', $msg)) && ($msg = preg_replace('/%%subscr_id%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['subscr_id']), $msg)))
333
  if(($msg = preg_replace('/%%subscr_baid%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['subscr_baid']), $msg)) && ($msg = preg_replace('/%%subscr_cid%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['subscr_cid']), $msg)))
334
+ if(($msg = preg_replace('/%%currency%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['currency']), $msg)) && ($msg = preg_replace('/%%currency_symbol%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['currency_symbol']), $msg)))
335
+ if(($msg = preg_replace('/%%initial%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['initial']), $msg)) && ($msg = preg_replace('/%%regular%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['regular']), $msg)) && ($msg = preg_replace('/%%recurring%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['recurring']), $msg)))
336
+ if(($msg = preg_replace('/%%initial_term%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['initial_term']), $msg)) && ($msg = preg_replace('/%%regular_term%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['regular_term']), $msg)))
337
+ if(($msg = preg_replace('/%%item_number%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['item_number']), $msg)) && ($msg = preg_replace('/%%item_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['item_name']), $msg)))
338
+ if(($msg = preg_replace('/%%first_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['first_name']), $msg)) && ($msg = preg_replace('/%%last_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['last_name']), $msg)))
339
+ if(($msg = preg_replace('/%%full_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(trim($paypal['first_name'].' '.$paypal['last_name'])), $msg)))
340
+ if(($msg = preg_replace('/%%payer_email%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['payer_email']), $msg)))
341
+
342
+ if(($msg = preg_replace('/%%full_coupon_code%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($coupon['full_coupon_code']), $msg)) && ($msg = preg_replace('/%%coupon_code%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($coupon['coupon_code']), $msg)) && ($msg = preg_replace('/%%coupon_affiliate_id%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($coupon['affiliate_id']), $msg)))
343
+
344
+ if(($msg = preg_replace('/%%user_first_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($user->first_name), $msg)) && ($msg = preg_replace('/%%user_last_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($user->last_name), $msg)))
345
+ if(($msg = preg_replace('/%%user_full_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(trim($user->first_name.' '.$user->last_name)), $msg)))
346
+ if(($msg = preg_replace('/%%user_email%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($user->user_email), $msg)))
347
+ if(($msg = preg_replace('/%%user_login%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($user->user_login), $msg)))
348
+ if(($msg = preg_replace('/%%user_ip%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($user_reg_ip), $msg)))
349
+ if(($msg = preg_replace('/%%user_id%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($user_id), $msg)))
350
+ {
351
+ if(is_array($fields) && !empty($fields))
352
+ foreach($fields as $var => $val /* Custom Registration/Profile Fields. */)
353
+ if(!($msg = preg_replace('/%%'.preg_quote($var, '/').'%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(maybe_serialize($val)), $msg)))
354
+ break;
355
 
356
+ if($sbj && ($msg = trim(preg_replace('/%%(.+?)%%/i', '', $msg)))) // Still have a ``$sbj`` and a ``$msg``?
357
 
358
+ foreach(c_ws_plugin__s2member_utils_strings::parse_emails($GLOBALS['WS_PLUGIN__']['s2member']['o']['modification_notification_recipients']) as $recipient)
359
+ wp_mail($recipient, apply_filters('ws_plugin__s2member_modification_notification_email_sbj', $sbj, get_defined_vars()), apply_filters('ws_plugin__s2member_modification_notification_email_msg', $msg, get_defined_vars()), 'Content-Type: text/plain; charset=UTF-8');
360
+ }
361
  $paypal['s2member_log'][] = 'Modification Notification Emails have been processed.';
362
  }
363
  if($processing && ($code = $GLOBALS['WS_PLUGIN__']['s2member']['o']['modification_tracking_codes']) && is_array($cv = preg_split('/\|/', $paypal['custom'])))
364
  {
365
  if(($code = preg_replace('/%%cv([0-9]+)%%/ei', 'trim(@$cv[$1])', $code)) && ($code = preg_replace('/%%subscr_id%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['subscr_id']), $code)))
366
  if(($code = preg_replace('/%%subscr_baid%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['subscr_baid']), $code)) && ($code = preg_replace('/%%subscr_cid%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['subscr_cid']), $code)))
367
+ if(($code = preg_replace('/%%currency%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['currency']), $code)) && ($code = preg_replace('/%%currency_symbol%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['currency_symbol']), $code)))
368
+ if(($code = preg_replace('/%%initial%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['initial']), $code)) && ($code = preg_replace('/%%regular%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['regular']), $code)) && ($code = preg_replace('/%%recurring%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['recurring']), $code)))
369
+ if(($code = preg_replace('/%%initial_term%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['initial_term']), $code)) && ($code = preg_replace('/%%regular_term%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['regular_term']), $code)))
370
+ if(($code = preg_replace('/%%item_number%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['item_number']), $code)) && ($code = preg_replace('/%%item_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['item_name']), $code)))
371
+ if(($code = preg_replace('/%%first_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['first_name']), $code)) && ($code = preg_replace('/%%last_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['last_name']), $code)))
372
+ if(($code = preg_replace('/%%full_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(trim($paypal['first_name'].' '.$paypal['last_name'])), $code)))
373
+ if(($code = preg_replace('/%%payer_email%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['payer_email']), $code)))
374
+
375
+ if(($code = preg_replace('/%%full_coupon_code%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($coupon['full_coupon_code']), $code)) && ($code = preg_replace('/%%coupon_code%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($coupon['coupon_code']), $code)) && ($code = preg_replace('/%%coupon_affiliate_id%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($coupon['affiliate_id']), $code)))
376
+
377
+ if(($code = preg_replace('/%%user_first_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($user->first_name), $code)) && ($code = preg_replace('/%%user_last_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($user->last_name), $code)))
378
+ if(($code = preg_replace('/%%user_full_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(trim($user->first_name.' '.$user->last_name)), $code)))
379
+ if(($code = preg_replace('/%%user_email%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($user->user_email), $code)))
380
+ if(($code = preg_replace('/%%user_login%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($user->user_login), $code)))
381
+ if(($code = preg_replace('/%%user_ip%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($user_reg_ip), $code)))
382
+ if(($code = preg_replace('/%%user_id%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($user_id), $code)))
 
 
 
 
 
 
383
  {
384
+ if(is_array($fields) && !empty($fields))
385
+ foreach($fields as $var => $val /* Custom Registration/Profile Fields. */)
386
+ if(!($code = preg_replace('/%%'.preg_quote($var, '/').'%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(maybe_serialize($val)), $code)))
387
+ break;
388
+
389
+ if(($code = trim(preg_replace('/%%(.+?)%%/i', '', $code))) /* This gets stored into a transient queue. */)
390
+ {
391
+ $paypal['s2member_log'][] = 'Storing Modification Tracking Codes into a Transient Queue. These will be processed on-site.';
392
+ set_transient('s2m_'.md5('s2member_transient_modification_tracking_codes_'.$paypal['subscr_id']), $code, 43200);
393
+ }
394
  }
 
395
  }
396
  foreach(array_keys(get_defined_vars()) as $__v) $__refs[$__v] =& $$__v;
397
  do_action('ws_plugin__s2member_during_paypal_notify_during_subscr_signup_w_update_vars', get_defined_vars());
426
 
427
  if(($rec = preg_replace('/%%cv([0-9]+)%%/ei', 'trim(@$cv[$1])', $rec)) && ($rec = preg_replace('/%%subscr_id%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['subscr_id']), $rec)))
428
  if(($rec = preg_replace('/%%subscr_baid%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['subscr_baid']), $rec)) && ($rec = preg_replace('/%%subscr_cid%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['subscr_cid']), $rec)))
429
+ if(($rec = preg_replace('/%%currency%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['currency']), $rec)) && ($rec = preg_replace('/%%currency_symbol%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['currency_symbol']), $rec)))
430
+ if(($rec = preg_replace('/%%initial%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['initial']), $rec)) && ($rec = preg_replace('/%%regular%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['regular']), $rec)))
431
+ if(($rec = preg_replace('/%%initial_term%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['initial_term']), $rec)) && ($rec = preg_replace('/%%regular_term%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['regular_term']), $rec)))
432
+ if(($rec = preg_replace('/%%initial_cycle%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(c_ws_plugin__s2member_utils_time::period_term($paypal['initial_term'])), $rec)) && ($rec = preg_replace('/%%regular_cycle%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(c_ws_plugin__s2member_utils_time::period_term($paypal['regular_term'], $paypal['recurring'])), $rec)))
433
+ if(($rec = preg_replace('/%%recurring%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['recurring']), $rec)) && ($rec = preg_replace('/%%recurring\/regular_cycle%%/i', c_ws_plugin__s2member_utils_strings::esc_refs((($paypal['recurring']) ? $paypal['recurring'].' / '.c_ws_plugin__s2member_utils_time::period_term($paypal['regular_term'], TRUE) : '0 / non-recurring')), $rec)))
434
+ if(($rec = preg_replace('/%%item_number%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['item_number']), $rec)) && ($rec = preg_replace('/%%item_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['item_name']), $rec)))
435
+ if(($rec = preg_replace('/%%first_name%%/i', c_ws_plugin__s2member_utils_strings::esc_dq(c_ws_plugin__s2member_utils_strings::esc_refs($paypal['first_name'])), $rec)) && ($rec = preg_replace('/%%last_name%%/i', c_ws_plugin__s2member_utils_strings::esc_dq(c_ws_plugin__s2member_utils_strings::esc_refs($paypal['last_name'])), $rec)))
436
+ if(($rec = preg_replace('/%%full_name%%/i', c_ws_plugin__s2member_utils_strings::esc_dq(c_ws_plugin__s2member_utils_strings::esc_refs(trim($paypal['first_name'].' '.$paypal['last_name']))), $rec))) // **NOTE** c_ws_plugin__s2member_utils_strings::esc_dq() is applied here. (ex. "N\"ame" <email>).
437
+ if(($rec = preg_replace('/%%payer_email%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['payer_email']), $rec)))
438
+ if(($rec = preg_replace('/%%user_ip%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['ip']), $rec)))
439
+ if(($rec = preg_replace('/%%full_coupon_code%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($coupon['full_coupon_code']), $rec)) && ($rec = preg_replace('/%%coupon_code%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($coupon['coupon_code']), $rec)) && ($rec = preg_replace('/%%coupon_affiliate_id%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($coupon['affiliate_id']), $rec)))
440
+
441
+ if(($sbj = preg_replace('/%%cv([0-9]+)%%/ei', 'trim(@$cv[$1])', $sbj)) && ($sbj = preg_replace('/%%subscr_id%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['subscr_id']), $sbj)))
442
+ if(($sbj = preg_replace('/%%subscr_baid%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['subscr_baid']), $sbj)) && ($sbj = preg_replace('/%%subscr_cid%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['subscr_cid']), $sbj)))
443
+ if(($sbj = preg_replace('/%%currency%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['currency']), $sbj)) && ($sbj = preg_replace('/%%currency_symbol%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['currency_symbol']), $sbj)))
444
+ if(($sbj = preg_replace('/%%initial%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['initial']), $sbj)) && ($sbj = preg_replace('/%%regular%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['regular']), $sbj)))
445
+ if(($sbj = preg_replace('/%%initial_term%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['initial_term']), $sbj)) && ($sbj = preg_replace('/%%regular_term%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['regular_term']), $sbj)))
446
+ if(($sbj = preg_replace('/%%initial_cycle%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(c_ws_plugin__s2member_utils_time::period_term($paypal['initial_term'])), $sbj)) && ($sbj = preg_replace('/%%regular_cycle%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(c_ws_plugin__s2member_utils_time::period_term($paypal['regular_term'], $paypal['recurring'])), $sbj)))
447
+ if(($sbj = preg_replace('/%%recurring%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['recurring']), $sbj)) && ($sbj = preg_replace('/%%recurring\/regular_cycle%%/i', c_ws_plugin__s2member_utils_strings::esc_refs((($paypal['recurring']) ? $paypal['recurring'].' / '.c_ws_plugin__s2member_utils_time::period_term($paypal['regular_term'], TRUE) : '0 / non-recurring')), $sbj)))
448
+ if(($sbj = preg_replace('/%%item_number%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['item_number']), $sbj)) && ($sbj = preg_replace('/%%item_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['item_name']), $sbj)))
449
+ if(($sbj = preg_replace('/%%first_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['first_name']), $sbj)) && ($sbj = preg_replace('/%%last_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['last_name']), $sbj)))
450
+ if(($sbj = preg_replace('/%%full_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(trim($paypal['first_name'].' '.$paypal['last_name'])), $sbj)))
451
+ if(($sbj = preg_replace('/%%payer_email%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['payer_email']), $sbj)))
452
+ if(($sbj = preg_replace('/%%user_ip%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['ip']), $sbj)))
453
+ if(($sbj = preg_replace('/%%full_coupon_code%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($coupon['full_coupon_code']), $sbj)) && ($sbj = preg_replace('/%%coupon_code%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($coupon['coupon_code']), $sbj)) && ($sbj = preg_replace('/%%coupon_affiliate_id%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($coupon['affiliate_id']), $sbj)))
454
+
455
+ if(($msg = preg_replace('/%%cv([0-9]+)%%/ei', 'trim(@$cv[$1])', $msg)) && ($msg = preg_replace('/%%subscr_id%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['subscr_id']), $msg)))
456
+ if(($msg = preg_replace('/%%subscr_baid%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['subscr_baid']), $msg)) && ($msg = preg_replace('/%%subscr_cid%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['subscr_cid']), $msg)))
457
+ if(($msg = preg_replace('/%%currency%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['currency']), $msg)) && ($msg = preg_replace('/%%currency_symbol%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['currency_symbol']), $msg)))
458
+ if(($msg = preg_replace('/%%initial%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['initial']), $msg)) && ($msg = preg_replace('/%%regular%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['regular']), $msg)))
459
+ if(($msg = preg_replace('/%%initial_term%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['initial_term']), $msg)) && ($msg = preg_replace('/%%regular_term%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['regular_term']), $msg)))
460
+ if(($msg = preg_replace('/%%initial_cycle%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(c_ws_plugin__s2member_utils_time::period_term($paypal['initial_term'])), $msg)) && ($msg = preg_replace('/%%regular_cycle%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(c_ws_plugin__s2member_utils_time::period_term($paypal['regular_term'], $paypal['recurring'])), $msg)))
461
+ if(($msg = preg_replace('/%%recurring%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['recurring']), $msg)) && ($msg = preg_replace('/%%recurring\/regular_cycle%%/i', c_ws_plugin__s2member_utils_strings::esc_refs((($paypal['recurring']) ? $paypal['recurring'].' / '.c_ws_plugin__s2member_utils_time::period_term($paypal['regular_term'], TRUE) : '0 / non-recurring')), $msg)))
462
+ if(($msg = preg_replace('/%%item_number%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['item_number']), $msg)) && ($msg = preg_replace('/%%item_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['item_name']), $msg)))
463
+ if(($msg = preg_replace('/%%first_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['first_name']), $msg)) && ($msg = preg_replace('/%%last_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['last_name']), $msg)))
464
+ if(($msg = preg_replace('/%%full_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(trim($paypal['first_name'].' '.$paypal['last_name'])), $msg)))
465
+ if(($msg = preg_replace('/%%payer_email%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['payer_email']), $msg)))
466
+ if(($msg = preg_replace('/%%user_ip%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['ip']), $msg)))
467
+ if(($msg = preg_replace('/%%full_coupon_code%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($coupon['full_coupon_code']), $msg)) && ($msg = preg_replace('/%%coupon_code%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($coupon['coupon_code']), $msg)) && ($msg = preg_replace('/%%coupon_affiliate_id%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($coupon['affiliate_id']), $msg)))
468
+
469
+ if(($rec = trim(preg_replace('/%%(.+?)%%/i', '', $rec))) && ($sbj = trim(preg_replace('/%%(.+?)%%/i', '', $sbj))) && ($msg = trim(preg_replace('/%%(.+?)%%/i', '', $msg))))
470
+ {
471
+ if(!is_multisite() || !c_ws_plugin__s2member_utils_conds::is_multisite_farm() || is_main_site())
472
+ {
473
+ $sbj = c_ws_plugin__s2member_utilities::evl($sbj, get_defined_vars());
474
+ $msg = c_ws_plugin__s2member_utilities::evl($msg, get_defined_vars());
475
+ }
476
+ foreach(c_ws_plugin__s2member_utils_strings::parse_emails($rec) as $recipient) // Go through a possible list of recipients.
477
+ c_ws_plugin__s2member_email_configs::email_config().wp_mail($recipient, apply_filters('ws_plugin__s2member_signup_email_sbj', $sbj, get_defined_vars()), apply_filters('ws_plugin__s2member_signup_email_msg', $msg, get_defined_vars()), 'From: "'.preg_replace('/"/', "'", $GLOBALS['WS_PLUGIN__']['s2member']['o']['reg_email_from_name']).'" <'.$GLOBALS['WS_PLUGIN__']['s2member']['o']['reg_email_from_email'].'>'."\r\n".'Content-Type: text/plain; charset=UTF-8').c_ws_plugin__s2member_email_configs::email_config_release();
478
+
479
+ $paypal['s2member_log'][] = 'Signup Confirmation Email sent to: '.$rec.'.';
480
+ }
481
  if($processing && $GLOBALS['WS_PLUGIN__']['s2member']['o']['signup_notification_urls'] && is_array($cv = preg_split('/\|/', $paypal['custom'])))
482
  {
483
  foreach(preg_split('/['."\r\n\t".']+/', $GLOBALS['WS_PLUGIN__']['s2member']['o']['signup_notification_urls']) as $url)
484
 
485
  if(($url = preg_replace('/%%cv([0-9]+)%%/ei', 'urlencode(trim(@$cv[$1]))', $url)) && ($url = preg_replace('/%%subscr_id%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($paypal['subscr_id'])), $url)))
486
  if(($url = preg_replace('/%%subscr_baid%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($paypal['subscr_baid'])), $url)) && ($url = preg_replace('/%%subscr_cid%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($paypal['subscr_cid'])), $url)))
487
+ if(($url = preg_replace('/%%currency%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($paypal['currency'])), $url)) && ($url = preg_replace('/%%currency_symbol%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($paypal['currency_symbol'])), $url)))
488
+ if(($url = preg_replace('/%%initial%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($paypal['initial'])), $url)) && ($url = preg_replace('/%%regular%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($paypal['regular'])), $url)) && ($url = preg_replace('/%%recurring%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($paypal['recurring'])), $url)))
489
+ if(($url = preg_replace('/%%initial_term%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($paypal['initial_term'])), $url)) && ($url = preg_replace('/%%regular_term%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($paypal['regular_term'])), $url)))
490
+ if(($url = preg_replace('/%%item_number%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($paypal['item_number'])), $url)) && ($url = preg_replace('/%%item_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($paypal['item_name'])), $url)))
491
+ if(($url = preg_replace('/%%first_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($paypal['first_name'])), $url)) && ($url = preg_replace('/%%last_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($paypal['last_name'])), $url)))
492
+ if(($url = preg_replace('/%%full_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode(trim($paypal['first_name'].' '.$paypal['last_name']))), $url)))
493
+ if(($url = preg_replace('/%%payer_email%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($paypal['payer_email'])), $url)))
494
+ if(($url = preg_replace('/%%user_ip%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($paypal['ip'])), $url)))
495
+ if(($url = preg_replace('/%%full_coupon_code%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($coupon['full_coupon_code'])), $url)) && ($url = preg_replace('/%%coupon_code%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($coupon['coupon_code'])), $url)) && ($url = preg_replace('/%%coupon_affiliate_id%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($coupon['affiliate_id'])), $url)))
496
+
497
+ if(($url = trim(preg_replace('/%%(.+?)%%/i', '', $url))))
498
+ c_ws_plugin__s2member_utils_urls::remote($url);
499
 
500
  $paypal['s2member_log'][] = 'Signup Notification URLs have been processed.';
501
  }
507
  $msg .= 'subscr_id: %%subscr_id%%'."\n";
508
  $msg .= 'subscr_baid: %%subscr_baid%%'."\n";
509
  $msg .= 'subscr_cid: %%subscr_cid%%'."\n";
510
+ $msg .= 'currency: %%currency%%'."\n";
511
+ $msg .= 'currency_symbol: %%currency_symbol%%'."\n";
512
  $msg .= 'initial: %%initial%%'."\n";
513
  $msg .= 'regular: %%regular%%'."\n";
514
  $msg .= 'recurring: %%recurring%%'."\n";
539
 
540
  if(($msg = preg_replace('/%%cv([0-9]+)%%/ei', 'trim(@$cv[$1])', $msg)) && ($msg = preg_replace('/%%subscr_id%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['subscr_id']), $msg)))
541
  if(($msg = preg_replace('/%%subscr_baid%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['subscr_baid']), $msg)) && ($msg = preg_replace('/%%subscr_cid%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['subscr_cid']), $msg)))
542
+ if(($msg = preg_replace('/%%currency%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['currency']), $msg)) && ($msg = preg_replace('/%%currency_symbol%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['currency_symbol']), $msg)))
543
+ if(($msg = preg_replace('/%%initial%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['initial']), $msg)) && ($msg = preg_replace('/%%regular%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['regular']), $msg)) && ($msg = preg_replace('/%%recurring%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['recurring']), $msg)))
544
+ if(($msg = preg_replace('/%%initial_term%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['initial_term']), $msg)) && ($msg = preg_replace('/%%regular_term%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['regular_term']), $msg)))
545
+ if(($msg = preg_replace('/%%item_number%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['item_number']), $msg)) && ($msg = preg_replace('/%%item_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['item_name']), $msg)))
546
+ if(($msg = preg_replace('/%%first_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['first_name']), $msg)) && ($msg = preg_replace('/%%last_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['last_name']), $msg)))
547
+ if(($msg = preg_replace('/%%full_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(trim($paypal['first_name'].' '.$paypal['last_name'])), $msg)))
548
+ if(($msg = preg_replace('/%%payer_email%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['payer_email']), $msg)))
549
+ if(($msg = preg_replace('/%%user_ip%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['ip']), $msg)))
550
+ if(($msg = preg_replace('/%%full_coupon_code%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($coupon['full_coupon_code']), $msg)) && ($msg = preg_replace('/%%coupon_code%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($coupon['coupon_code']), $msg)) && ($msg = preg_replace('/%%coupon_affiliate_id%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($coupon['affiliate_id']), $msg)))
551
 
552
+ if($sbj && ($msg = trim(preg_replace('/%%(.+?)%%/i', '', $msg)))) // Still have a ``$sbj`` and a ``$msg``?
553
 
554
+ foreach(c_ws_plugin__s2member_utils_strings::parse_emails($GLOBALS['WS_PLUGIN__']['s2member']['o']['signup_notification_recipients']) as $recipient)
555
+ wp_mail($recipient, apply_filters('ws_plugin__s2member_signup_notification_email_sbj', $sbj, get_defined_vars()), apply_filters('ws_plugin__s2member_signup_notification_email_msg', $msg, get_defined_vars()), 'Content-Type: text/plain; charset=UTF-8');
556
 
557
  $paypal['s2member_log'][] = 'Signup Notification Emails have been processed.';
558
  }
560
  {
561
  if(($code = preg_replace('/%%cv([0-9]+)%%/ei', 'trim(@$cv[$1])', $code)) && ($code = preg_replace('/%%subscr_id%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['subscr_id']), $code)))
562
  if(($code = preg_replace('/%%subscr_baid%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['subscr_baid']), $code)) && ($code = preg_replace('/%%subscr_cid%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['subscr_cid']), $code)))
563
+ if(($code = preg_replace('/%%currency%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['currency']), $code)) && ($code = preg_replace('/%%currency_symbol%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['currency_symbol']), $code)))
564
+ if(($code = preg_replace('/%%initial%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['initial']), $code)) && ($code = preg_replace('/%%regular%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['regular']), $code)) && ($code = preg_replace('/%%recurring%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['recurring']), $code)))
565
+ if(($code = preg_replace('/%%initial_term%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['initial_term']), $code)) && ($code = preg_replace('/%%regular_term%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['regular_term']), $code)))
566
+ if(($code = preg_replace('/%%item_number%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['item_number']), $code)) && ($code = preg_replace('/%%item_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['item_name']), $code)))
567
+ if(($code = preg_replace('/%%first_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['first_name']), $code)) && ($code = preg_replace('/%%last_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['last_name']), $code)))
568
+ if(($code = preg_replace('/%%full_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(trim($paypal['first_name'].' '.$paypal['last_name'])), $code)))
569
+ if(($code = preg_replace('/%%payer_email%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['payer_email']), $code)))
570
+ if(($code = preg_replace('/%%user_ip%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['ip']), $code)))
571
+ if(($code = preg_replace('/%%full_coupon_code%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($coupon['full_coupon_code']), $code)) && ($code = preg_replace('/%%coupon_code%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($coupon['coupon_code']), $code)) && ($code = preg_replace('/%%coupon_affiliate_id%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($coupon['affiliate_id']), $code)))
572
+
573
+ if(($code = trim(preg_replace('/%%(.+?)%%/i', '', $code))) /* This gets stored into a Transient Queue. */)
574
+ {
575
+ $paypal['s2member_log'][] = 'Storing Signup Tracking Codes into a Transient Queue. These will be processed on-site.';
576
+ set_transient('s2m_'.md5('s2member_transient_signup_tracking_codes_'.$paypal['subscr_id']), $code, 43200);
577
+ }
578
  }
579
  foreach(array_keys(get_defined_vars()) as $__v) $__refs[$__v] =& $$__v;
580
  do_action('ws_plugin__s2member_during_paypal_notify_during_subscr_signup_wo_update_vars', get_defined_vars());
595
 
596
  if(($url = preg_replace('/%%cv([0-9]+)%%/ei', 'urlencode(trim(@$cv[$1]))', $url)) && ($url = preg_replace('/%%subscr_id%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($paypal['subscr_id'])), $url)))
597
  if(($url = preg_replace('/%%subscr_baid%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($paypal['subscr_baid'])), $url)) && ($url = preg_replace('/%%subscr_cid%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($paypal['subscr_cid'])), $url)))
598
+ if(($url = preg_replace('/%%currency%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($paypal['currency'])), $url)) && ($url = preg_replace('/%%currency_symbol%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($paypal['currency_symbol'])), $url)))
599
+ if(($url = preg_replace('/%%initial%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($paypal['initial'])), $url)) && ($url = preg_replace('/%%regular%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($paypal['regular'])), $url)) && ($url = preg_replace('/%%recurring%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($paypal['recurring'])), $url)))
600
+ if(($url = preg_replace('/%%initial_term%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($paypal['initial_term'])), $url)) && ($url = preg_replace('/%%regular_term%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($paypal['regular_term'])), $url)))
601
+ if(($url = preg_replace('/%%item_number%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($paypal['item_number'])), $url)) && ($url = preg_replace('/%%item_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($paypal['item_name'])), $url)))
602
+ if(($url = preg_replace('/%%first_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($paypal['first_name'])), $url)) && ($url = preg_replace('/%%last_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($paypal['last_name'])), $url)))
603
+ if(($url = preg_replace('/%%full_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode(trim($paypal['first_name'].' '.$paypal['last_name']))), $url)))
604
+ if(($url = preg_replace('/%%payer_email%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($paypal['payer_email'])), $url)))
605
+ if(($url = preg_replace('/%%modification%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode((int)$modifying)), $url)))
606
+
607
+ if(($url = preg_replace('/%%full_coupon_code%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($coupon['full_coupon_code'])), $url)) && ($url = preg_replace('/%%coupon_code%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($coupon['coupon_code'])), $url)) && ($url = preg_replace('/%%coupon_affiliate_id%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($coupon['affiliate_id'])), $url)))
608
+
609
+ if(($url = preg_replace('/%%user_first_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($user->first_name)), $url)) && ($url = preg_replace('/%%user_last_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($user->last_name)), $url)))
610
+ if(($url = preg_replace('/%%user_full_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode(trim($user->first_name.' '.$user->last_name))), $url)))
611
+ if(($url = preg_replace('/%%user_email%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($user->user_email)), $url)))
612
+ if(($url = preg_replace('/%%user_login%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($user->user_login)), $url)))
613
+ if(($url = preg_replace('/%%user_ip%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($user_reg_ip)), $url)))
614
+ if(($url = preg_replace('/%%user_id%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($user_id)), $url)))
615
+ {
616
+ if(is_array($fields) && !empty($fields))
617
+ foreach($fields as $var => $val /* Custom Registration/Profile Fields. */)
618
+ if(!($url = preg_replace('/%%'.preg_quote($var, '/').'%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode(maybe_serialize($val))), $url)))
619
+ break;
620
 
621
+ if(($url = trim($url))) // Preserve remaining replacements; parent routine may perform replacements too.
622
+ $paypal['s2member_paypal_proxy_return_url'] = $url;
623
+ }
624
  }
625
  $paypal['s2member_log'][] = 'Subscr. Return ( `modification='.(int)$modifying.'` ), a Proxy Return URL is ready.';
626
  }
650
 
651
  if(($url = preg_replace('/%%cv([0-9]+)%%/ei', 'urlencode(trim(@$cv[$1]))', $url)) && ($url = preg_replace('/%%subscr_id%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($paypal['subscr_id'])), $url)))
652
  if(($url = preg_replace('/%%subscr_baid%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($paypal['subscr_baid'])), $url)) && ($url = preg_replace('/%%subscr_cid%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($paypal['subscr_cid'])), $url)))
653
+ if(($url = preg_replace('/%%currency%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($paypal['currency'])), $url)) && ($url = preg_replace('/%%currency_symbol%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($paypal['currency_symbol'])), $url)))
654
+ if(($url = preg_replace('/%%amount%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($paypal['mc_gross'])), $url)) && ($url = preg_replace('/%%txn_id%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($paypal['txn_id'])), $url)))
655
+ if(($url = preg_replace('/%%item_number%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($paypal['item_number'])), $url)) && ($url = preg_replace('/%%item_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($paypal['item_name'])), $url)))
656
+ if(($url = preg_replace('/%%first_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($paypal['first_name'])), $url)) && ($url = preg_replace('/%%last_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($paypal['last_name'])), $url)))
657
+ if(($url = preg_replace('/%%full_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode(trim($paypal['first_name'].' '.$paypal['last_name']))), $url)))
658
+ if(($url = preg_replace('/%%payer_email%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($paypal['payer_email'])), $url)))
 
 
 
 
 
 
 
 
 
 
 
 
 
659
 
660
+ if(($url = preg_replace('/%%full_coupon_code%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($coupon['full_coupon_code'])), $url)) && ($url = preg_replace('/%%coupon_code%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($coupon['coupon_code'])), $url)) && ($url = preg_replace('/%%coupon_affiliate_id%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($coupon['affiliate_id'])), $url)))
661
+
662
+ if(($url = preg_replace('/%%user_first_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($user->first_name)), $url)) && ($url = preg_replace('/%%user_last_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($user->last_name)), $url)))
663
+ if(($url = preg_replace('/%%user_full_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode(trim($user->first_name.' '.$user->last_name))), $url)))
664
+ if(($url = preg_replace('/%%user_email%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($user->user_email)), $url)))
665
+ if(($url = preg_replace('/%%user_login%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($user->user_login)), $url)))
666
+ if(($url = preg_replace('/%%user_ip%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($user_reg_ip)), $url)))
667
+ if(($url = preg_replace('/%%user_id%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($user_id)), $url)))
668
+ {
669
+ if(is_array($fields) && !empty($fields))
670
+ foreach($fields as $var => $val /* Custom Registration/Profile Fields. */)
671
+ if(!($url = preg_replace('/%%'.preg_quote($var, '/').'%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode(maybe_serialize($val))), $url)))
672
+ break;
673
+
674
+ if(($url = trim(preg_replace('/%%(.+?)%%/i', '', $url))))
675
+ c_ws_plugin__s2member_utils_urls::remote($url);
676
+ }
677
  $paypal['s2member_log'][] = 'Payment Notification URLs have been processed.';
678
  }
679
  if($GLOBALS['WS_PLUGIN__']['s2member']['o']['payment_notification_recipients'] && is_array($cv = preg_split('/\|/', $paypal['custom'])))
684
  $msg .= 'subscr_id: %%subscr_id%%'."\n";
685
  $msg .= 'subscr_baid: %%subscr_baid%%'."\n";
686
  $msg .= 'subscr_cid: %%subscr_cid%%'."\n";
687
+ $msg .= 'currency: %%currency%%'."\n";
688
+ $msg .= 'currency_symbol: %%currency_symbol%%'."\n";
689
  $msg .= 'amount: %%amount%%'."\n";
690
  $msg .= 'txn_id: %%txn_id%%'."\n";
691
  $msg .= 'item_number: %%item_number%%'."\n";
724
 
725
  if(($msg = preg_replace('/%%cv([0-9]+)%%/ei', 'trim(@$cv[$1])', $msg)) && ($msg = preg_replace('/%%subscr_id%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['subscr_id']), $msg)))
726
  if(($msg = preg_replace('/%%subscr_baid%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['subscr_baid']), $msg)) && ($msg = preg_replace('/%%subscr_cid%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['subscr_cid']), $msg)))
727
+ if(($msg = preg_replace('/%%currency%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['currency']), $msg)) && ($msg = preg_replace('/%%currency_symbol%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['currency_symbol']), $msg)))
728
+ if(($msg = preg_replace('/%%amount%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['mc_gross']), $msg)) && ($msg = preg_replace('/%%txn_id%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['txn_id']), $msg)))
729
+ if(($msg = preg_replace('/%%item_number%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['item_number']), $msg)) && ($msg = preg_replace('/%%item_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['item_name']), $msg)))
730
+ if(($msg = preg_replace('/%%first_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['first_name']), $msg)) && ($msg = preg_replace('/%%last_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['last_name']), $msg)))
731
+ if(($msg = preg_replace('/%%full_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(trim($paypal['first_name'].' '.$paypal['last_name'])), $msg)))
732
+ if(($msg = preg_replace('/%%payer_email%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['payer_email']), $msg)))
733
+
734
+ if(($msg = preg_replace('/%%full_coupon_code%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($coupon['full_coupon_code']), $msg)) && ($msg = preg_replace('/%%coupon_code%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($coupon['coupon_code']), $msg)) && ($msg = preg_replace('/%%coupon_affiliate_id%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($coupon['affiliate_id']), $msg)))
735
+
736
+ if(($msg = preg_replace('/%%user_first_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($user->first_name), $msg)) && ($msg = preg_replace('/%%user_last_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($user->last_name), $msg)))
737
+ if(($msg = preg_replace('/%%user_full_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(trim($user->first_name.' '.$user->last_name)), $msg)))
738
+ if(($msg = preg_replace('/%%user_email%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($user->user_email), $msg)))
739
+ if(($msg = preg_replace('/%%user_login%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($user->user_login), $msg)))
740
+ if(($msg = preg_replace('/%%user_ip%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($user_reg_ip), $msg)))
741
+ if(($msg = preg_replace('/%%user_id%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($user_id), $msg)))
742
+ {
743
+ if(is_array($fields) && !empty($fields))
744
+ foreach($fields as $var => $val /* Custom Registration/Profile Fields. */)
745
+ if(!($msg = preg_replace('/%%'.preg_quote($var, '/').'%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(maybe_serialize($val)), $msg)))
746
+ break;
747
+
748
+ if($sbj && ($msg = trim(preg_replace('/%%(.+?)%%/i', '', $msg)))) // Still have a ``$sbj`` and a ``$msg``?
749
+
750
+ foreach(c_ws_plugin__s2member_utils_strings::parse_emails($GLOBALS['WS_PLUGIN__']['s2member']['o']['payment_notification_recipients']) as $recipient)
751
+ wp_mail($recipient, apply_filters('ws_plugin__s2member_payment_notification_email_sbj', $sbj, get_defined_vars()), apply_filters('ws_plugin__s2member_payment_notification_email_msg', $msg, get_defined_vars()), 'Content-Type: text/plain; charset=UTF-8');
752
+ }
753
  $paypal['s2member_log'][] = 'Payment Notification Emails have been processed.';
754
  }
755
  }
includes/classes/paypal-notify-in-wa-ccaps-wo-level.inc.php CHANGED
@@ -1,362 +1,376 @@
1
  <?php
2
  /**
3
- * s2Member's PayPal IPN handler (inner processing routine).
4
- *
5
- * Copyright: © 2009-2011
6
- * {@link http://www.websharks-inc.com/ WebSharks, Inc.}
7
- * (coded in the USA)
8
- *
9
- * Released under the terms of the GNU General Public License.
10
- * You should have received a copy of the GNU General Public License,
11
- * along with this software. In the main directory, see: /licensing/
12
- * If not, see: {@link http://www.gnu.org/licenses/}.
13
- *
14
- * @package s2Member\PayPal
15
- * @since 110815
16
- */
17
- if (realpath (__FILE__) === realpath ($_SERVER["SCRIPT_FILENAME"]))
18
- exit ("Do not access this file directly.");
19
-
20
- if (!class_exists ("c_ws_plugin__s2member_paypal_notify_in_wa_ccaps_wo_level"))
 
 
 
 
 
 
 
 
21
  {
22
  /**
23
- * s2Member's PayPal IPN handler (inner processing routine).
24
- *
25
- * @package s2Member\PayPal
26
- * @since 110815
27
- */
28
- class c_ws_plugin__s2member_paypal_notify_in_wa_ccaps_wo_level
 
 
 
 
 
 
 
 
 
 
 
 
 
 
29
  {
30
- /**
31
- * s2Member's PayPal IPN handler (inner processing routine).
32
- *
33
- * @package s2Member\PayPal
34
- * @since 110815
35
- *
36
- * @param array $vars Required. An array of defined variables passed by {@link s2Member\PayPal\c_ws_plugin__s2member_paypal_notify_in::paypal_notify()}.
37
- * @return array|bool The original ``$paypal`` array passed in (extracted) from ``$vars``, or false when conditions do NOT apply.
38
- */
39
- public static function cp ($vars = array()) // Conditional phase for ``c_ws_plugin__s2member_paypal_notify_in::paypal_notify()``.
 
 
 
 
 
 
 
40
  {
41
- extract ($vars, EXTR_OVERWRITE | EXTR_REFS); // Extract all vars passed in from: ``c_ws_plugin__s2member_paypal_notify_in::paypal_notify()``.
42
-
43
- if ((!empty($paypal["txn_type"]) && preg_match ("/^web_accept$/i", $paypal["txn_type"]))
44
- && (!empty($paypal["item_number"]) && preg_match ($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["membership_item_number_wo_level_regex"], $paypal["item_number"]))
45
- && (empty($paypal["payment_status"]) || empty($payment_status_issues) || !preg_match ($payment_status_issues, $paypal["payment_status"]))
46
- && (!empty($paypal["txn_id"])) && (!empty($paypal["payer_email"]))
47
- && (!empty($paypal["txn_baid"]) || ($paypal["txn_baid"] = $paypal["txn_id"]))
48
- && (!empty($paypal["txn_cid"]) || ($paypal["txn_cid"] = $paypal["txn_id"])))
49
  {
50
- foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;
51
- do_action("ws_plugin__s2member_during_paypal_notify_before_new_ccaps", get_defined_vars ());
52
- unset($__refs, $__v);
53
 
54
- if (!get_transient ($transient_ipn = "s2m_ipn_" . md5 ("s2member_transient_" . $_paypal_s)) && set_transient ($transient_ipn, time (), 31556926 * 10))
55
- {
56
- $paypal["s2member_log"][] = "s2Member `txn_type` identified as ( `web_accept` ) w/ update vars for Capabilities w/o Level.";
57
-
58
- list ($paypal["level"], $paypal["ccaps"], $paypal["eotper"]) = preg_split ("/\:/", $paypal["item_number"], 3);
59
-
60
- $paypal["ip"] = (preg_match ("/ip address/i", $paypal["option_name2"]) && $paypal["option_selection2"]) ? $paypal["option_selection2"] : "";
61
- $paypal["ip"] = (!$paypal["ip"] && preg_match ("/^[a-z0-9]+~[0-9\.]+$/i", $paypal["invoice"])) ? preg_replace ("/^[a-z0-9]+~/i", "", $paypal["invoice"]) : $paypal["ip"];
62
-
63
- if (preg_match ("/(referenc|associat|updat|upgrad)/i", $paypal["option_name1"]) && $paypal["option_selection1"]) // Must have this information for Capability additions.
64
- {
65
- if (($user_id = c_ws_plugin__s2member_utils_users::get_user_id_with ($paypal["txn_id"], $paypal["option_selection1"])) && is_object ($user = new WP_User ($user_id)) && $user->ID)
66
- {
67
- if (!$user->has_cap ("administrator")) // Do NOT process this routine on Administrators.
68
- {
69
- $processing = $during = true; // Yes, we ARE processing this.
70
-
71
- foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;
72
- do_action("ws_plugin__s2member_during_paypal_notify_during_before_new_ccaps", get_defined_vars ());
73
- unset($__refs, $__v);
74
-
75
- $fields = get_user_option ("s2member_custom_fields", $user_id); // These will be needed in the routines below.
76
- $user_reg_ip = get_user_option ("s2member_registration_ip", $user_id); // Original IP during Registration.
77
- $user_reg_ip = $paypal["ip"] = ($user_reg_ip) ? $user_reg_ip : $paypal["ip"]; // Now merge conditionally.
78
-
79
- if (is_multisite () && !is_user_member_of_blog ($user_id)) // Must have a Role on this Blog.
80
- {
81
- add_existing_user_to_blog (array("user_id" => $user_id, "role" => get_option ("default_role")));
82
- $user = new WP_User ($user_id);
83
- }
84
- if ($paypal["ccaps"] && preg_match ("/^-all/", str_replace ("+", "", $paypal["ccaps"])))
85
- foreach ($user->allcaps as $cap => $cap_enabled)
86
- if (preg_match ("/^access_s2member_ccap_/", $cap))
87
- $user->remove_cap ($ccap = $cap);
88
-
89
- if ($paypal["ccaps"] && preg_replace ("/^-all[\r\n\t\s;,]*/", "", str_replace ("+", "", $paypal["ccaps"])))
90
- foreach (preg_split ("/[\r\n\t\s;,]+/", preg_replace ("/^-all[\r\n\t\s;,]*/", "", str_replace ("+", "", $paypal["ccaps"]))) as $ccap)
91
- if (strlen ($ccap = trim (strtolower (preg_replace ("/[^a-z_0-9]/i", "", $ccap)))))
92
- $user->add_cap ("access_s2member_ccap_" . $ccap);
93
-
94
- if (!get_user_option ("s2member_registration_ip", $user_id))
95
- update_user_option ($user_id, "s2member_registration_ip", $paypal["ip"]);
96
-
97
- $paypal["s2member_log"][] = "s2Member Custom Capabilities updated w/ advanced update routines.";
98
-
99
- $sbj = $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["ccap_email_subject"]; // The same for standard and w/ Pro Forms.
100
- $msg = $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["ccap_email_message"]; // The same for standard and w/ Pro Forms.
101
- $rec = $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["ccap_email_recipients"]; // The same for standard and w/ Pro Forms.
102
-
103
- if (($rec = preg_replace ("/%%cv([0-9]+)%%/ei", 'trim(@$cv[$1])', $rec)) && ($rec = preg_replace ("/%%(?:subscr|txn)_id%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($paypal["txn_id"]), $rec)))
104
- if (($rec = preg_replace ("/%%(?:subscr|txn)_baid%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($paypal["txn_baid"]), $rec)) && ($rec = preg_replace ("/%%(?:subscr|txn)_cid%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($paypal["txn_cid"]), $rec)))
105
- if (($rec = preg_replace ("/%%amount%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($paypal["mc_gross"]), $rec)) && ($rec = preg_replace ("/%%txn_id%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($paypal["txn_id"]), $rec)))
106
- if (($rec = preg_replace ("/%%item_number%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($paypal["item_number"]), $rec)) && ($rec = preg_replace ("/%%item_name%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($paypal["item_name"]), $rec)))
107
- if (($rec = preg_replace ("/%%first_name%%/i", c_ws_plugin__s2member_utils_strings::esc_dq (c_ws_plugin__s2member_utils_strings::esc_refs ($paypal["first_name"])), $rec)) && ($rec = preg_replace ("/%%last_name%%/i", c_ws_plugin__s2member_utils_strings::esc_dq (c_ws_plugin__s2member_utils_strings::esc_refs ($paypal["last_name"])), $rec)))
108
- if (($rec = preg_replace ("/%%full_name%%/i", c_ws_plugin__s2member_utils_strings::esc_dq (c_ws_plugin__s2member_utils_strings::esc_refs (trim ($paypal["first_name"] . " " . $paypal["last_name"]))), $rec))) // **NOTE** c_ws_plugin__s2member_utils_strings::esc_dq() is applied here. (ex. "N\"ame" <email>).
109
- if (($rec = preg_replace ("/%%payer_email%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($paypal["payer_email"]), $rec)))
110
-
111
- if (($rec = preg_replace ("/%%full_coupon_code%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($coupon["full_coupon_code"]), $rec)) && ($rec = preg_replace ("/%%coupon_code%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($coupon["coupon_code"]), $rec)) && ($rec = preg_replace ("/%%coupon_affiliate_id%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($coupon["affiliate_id"]), $rec)))
112
-
113
- if (($rec = preg_replace ("/%%user_first_name%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($user->first_name), $rec)) && ($rec = preg_replace ("/%%user_last_name%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($user->last_name), $rec)))
114
- if (($rec = preg_replace ("/%%user_full_name%%/i", c_ws_plugin__s2member_utils_strings::esc_refs (trim ($user->first_name . " " . $user->last_name)), $rec)))
115
- if (($rec = preg_replace ("/%%user_email%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($user->user_email), $rec)))
116
- if (($rec = preg_replace ("/%%user_login%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($user->user_login), $rec)))
117
- if (($rec = preg_replace ("/%%user_ip%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($user_reg_ip), $rec)))
118
- if (($rec = preg_replace ("/%%user_id%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($user_id), $rec)))
119
-
120
- if (($sbj = preg_replace ("/%%cv([0-9]+)%%/ei", 'trim(@$cv[$1])', $sbj)) && ($sbj = preg_replace ("/%%(?:subscr|txn)_id%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($paypal["txn_id"]), $sbj)))
121
- if (($sbj = preg_replace ("/%%(?:subscr|txn)_baid%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($paypal["txn_baid"]), $sbj)) && ($sbj = preg_replace ("/%%(?:subscr|txn)_cid%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($paypal["txn_cid"]), $sbj)))
122
- if (($sbj = preg_replace ("/%%amount%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($paypal["mc_gross"]), $sbj)) && ($sbj = preg_replace ("/%%txn_id%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($paypal["txn_id"]), $sbj)))
123
- if (($sbj = preg_replace ("/%%item_number%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($paypal["item_number"]), $sbj)) && ($sbj = preg_replace ("/%%item_name%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($paypal["item_name"]), $sbj)))
124
- if (($sbj = preg_replace ("/%%first_name%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($paypal["first_name"]), $sbj)) && ($sbj = preg_replace ("/%%last_name%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($paypal["last_name"]), $sbj)))
125
- if (($sbj = preg_replace ("/%%full_name%%/i", c_ws_plugin__s2member_utils_strings::esc_refs (trim ($paypal["first_name"] . " " . $paypal["last_name"])), $sbj)))
126
- if (($sbj = preg_replace ("/%%payer_email%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($paypal["payer_email"]), $sbj)))
127
-
128
- if (($sbj = preg_replace ("/%%full_coupon_code%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($coupon["full_coupon_code"]), $sbj)) && ($sbj = preg_replace ("/%%coupon_code%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($coupon["coupon_code"]), $sbj)) && ($sbj = preg_replace ("/%%coupon_affiliate_id%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($coupon["affiliate_id"]), $sbj)))
129
-
130
- if (($sbj = preg_replace ("/%%user_first_name%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($user->first_name), $sbj)) && ($sbj = preg_replace ("/%%user_last_name%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($user->last_name), $sbj)))
131
- if (($sbj = preg_replace ("/%%user_full_name%%/i", c_ws_plugin__s2member_utils_strings::esc_refs (trim ($user->first_name . " " . $user->last_name)), $sbj)))
132
- if (($sbj = preg_replace ("/%%user_email%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($user->user_email), $sbj)))
133
- if (($sbj = preg_replace ("/%%user_login%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($user->user_login), $sbj)))
134
- if (($sbj = preg_replace ("/%%user_ip%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($user_reg_ip), $sbj)))
135
- if (($sbj = preg_replace ("/%%user_id%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($user_id), $sbj)))
136
-
137
- if (($msg = preg_replace ("/%%cv([0-9]+)%%/ei", 'trim(@$cv[$1])', $msg)) && ($msg = preg_replace ("/%%(?:subscr|txn)_id%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($paypal["txn_id"]), $msg)))
138
- if (($msg = preg_replace ("/%%(?:subscr|txn)_baid%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($paypal["txn_baid"]), $msg)) && ($msg = preg_replace ("/%%(?:subscr|txn)_cid%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($paypal["txn_cid"]), $msg)))
139
- if (($msg = preg_replace ("/%%amount%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($paypal["mc_gross"]), $msg)) && ($msg = preg_replace ("/%%txn_id%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($paypal["txn_id"]), $msg)))
140
- if (($msg = preg_replace ("/%%item_number%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($paypal["item_number"]), $msg)) && ($msg = preg_replace ("/%%item_name%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($paypal["item_name"]), $msg)))
141
- if (($msg = preg_replace ("/%%first_name%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($paypal["first_name"]), $msg)) && ($msg = preg_replace ("/%%last_name%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($paypal["last_name"]), $msg)))
142
- if (($msg = preg_replace ("/%%full_name%%/i", c_ws_plugin__s2member_utils_strings::esc_refs (trim ($paypal["first_name"] . " " . $paypal["last_name"])), $msg)))
143
- if (($msg = preg_replace ("/%%payer_email%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($paypal["payer_email"]), $msg)))
144
-
145
- if (($msg = preg_replace ("/%%full_coupon_code%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($coupon["full_coupon_code"]), $msg)) && ($msg = preg_replace ("/%%coupon_code%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($coupon["coupon_code"]), $msg)) && ($msg = preg_replace ("/%%coupon_affiliate_id%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($coupon["affiliate_id"]), $msg)))
146
-
147
- if (($msg = preg_replace ("/%%user_first_name%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($user->first_name), $msg)) && ($msg = preg_replace ("/%%user_last_name%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($user->last_name), $msg)))
148
- if (($msg = preg_replace ("/%%user_full_name%%/i", c_ws_plugin__s2member_utils_strings::esc_refs (trim ($user->first_name . " " . $user->last_name)), $msg)))
149
- if (($msg = preg_replace ("/%%user_email%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($user->user_email), $msg)))
150
- if (($msg = preg_replace ("/%%user_login%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($user->user_login), $msg)))
151
- if (($msg = preg_replace ("/%%user_ip%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($user_reg_ip), $msg)))
152
- if (($msg = preg_replace ("/%%user_id%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($user_id), $msg)))
153
- {
154
- if (is_array($fields) && !empty($fields)) foreach /* Custom Registration/Profile Fields. */ ($fields as $var => $val)
155
- {
156
- $rec = preg_replace ("/%%" . preg_quote ($var, "/") . "%%/i", c_ws_plugin__s2member_utils_strings::esc_refs (maybe_serialize ($val)), $rec);
157
- $sbj = preg_replace ("/%%" . preg_quote ($var, "/") . "%%/i", c_ws_plugin__s2member_utils_strings::esc_refs (maybe_serialize ($val)), $sbj);
158
- $msg = preg_replace ("/%%" . preg_quote ($var, "/") . "%%/i", c_ws_plugin__s2member_utils_strings::esc_refs (maybe_serialize ($val)), $msg);
159
- }
160
- if (($rec = trim (preg_replace ("/%%(.+?)%%/i", "", $rec))) && ($sbj = trim (preg_replace ("/%%(.+?)%%/i", "", $sbj))) && ($msg = trim (preg_replace ("/%%(.+?)%%/i", "", $msg))))
161
- {
162
- if (!is_multisite () || !c_ws_plugin__s2member_utils_conds::is_multisite_farm () || is_main_site ())
163
- {
164
- $sbj = c_ws_plugin__s2member_utilities::evl($sbj, get_defined_vars());
165
- $msg = c_ws_plugin__s2member_utilities::evl($msg, get_defined_vars());
166
- }
167
- foreach /* Go through a possible list of recipients. */(c_ws_plugin__s2member_utils_strings::parse_emails ($rec) as $recipient)
168
- c_ws_plugin__s2member_email_configs::email_config () . wp_mail ($recipient, apply_filters("ws_plugin__s2member_capabilities_email_sbj", $sbj, get_defined_vars ()), apply_filters("ws_plugin__s2member_capabilities_email_msg", $msg, get_defined_vars ()), "From: \"" . preg_replace ('/"/', "'", $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["reg_email_from_name"]) . "\" <" . $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["reg_email_from_email"] . ">\r\nContent-Type: text/plain; charset=UTF-8") . c_ws_plugin__s2member_email_configs::email_config_release ();
169
-
170
- $paypal["s2member_log"][] = "Capability Confirmation Email sent to: " . $rec . ".";
171
- }
172
- }
173
- if ($processing && $_REQUEST["s2member_paypal_proxy"] && ($url = $_REQUEST["s2member_paypal_proxy_return_url"]) && is_array($cv = preg_split ("/\|/", $paypal["custom"]))) // A Proxy is requesting a Return URL?
174
- {
175
- if (($url = preg_replace ("/%%cv([0-9]+)%%/ei", 'urlencode(trim(@$cv[$1]))', $url)) && ($url = preg_replace ("/%%(?:subscr|txn)_id%%/i", c_ws_plugin__s2member_utils_strings::esc_refs (urlencode ($paypal["txn_id"])), $url)))
176
- if (($url = preg_replace ("/%%(?:subscr|txn)_baid%%/i", c_ws_plugin__s2member_utils_strings::esc_refs (urlencode ($paypal["txn_baid"])), $url)) && ($url = preg_replace ("/%%(?:subscr|txn)_cid%%/i", c_ws_plugin__s2member_utils_strings::esc_refs (urlencode ($paypal["txn_cid"])), $url)))
177
- if (($url = preg_replace ("/%%amount%%/i", c_ws_plugin__s2member_utils_strings::esc_refs (urlencode ($paypal["mc_gross"])), $url)) && ($url = preg_replace ("/%%txn_id%%/i", c_ws_plugin__s2member_utils_strings::esc_refs (urlencode ($paypal["txn_id"])), $url)))
178
- if (($url = preg_replace ("/%%item_number%%/i", c_ws_plugin__s2member_utils_strings::esc_refs (urlencode ($paypal["item_number"])), $url)) && ($url = preg_replace ("/%%item_name%%/i", c_ws_plugin__s2member_utils_strings::esc_refs (urlencode ($paypal["item_name"])), $url)))
179
- if (($url = preg_replace ("/%%first_name%%/i", c_ws_plugin__s2member_utils_strings::esc_refs (urlencode ($paypal["first_name"])), $url)) && ($url = preg_replace ("/%%last_name%%/i", c_ws_plugin__s2member_utils_strings::esc_refs (urlencode ($paypal["last_name"])), $url)))
180
- if (($url = preg_replace ("/%%full_name%%/i", c_ws_plugin__s2member_utils_strings::esc_refs (urlencode (trim ($paypal["first_name"] . " " . $paypal["last_name"]))), $url)))
181
- if (($url = preg_replace ("/%%payer_email%%/i", c_ws_plugin__s2member_utils_strings::esc_refs (urlencode ($paypal["payer_email"])), $url)))
182
-
183
- if (($url = preg_replace ("/%%full_coupon_code%%/i", c_ws_plugin__s2member_utils_strings::esc_refs (urlencode($coupon["full_coupon_code"])), $url)) && ($url = preg_replace ("/%%coupon_code%%/i", c_ws_plugin__s2member_utils_strings::esc_refs (urlencode($coupon["coupon_code"])), $url)) && ($url = preg_replace ("/%%coupon_affiliate_id%%/i", c_ws_plugin__s2member_utils_strings::esc_refs (urlencode($coupon["affiliate_id"])), $url)))
184
-
185
- if (($url = preg_replace ("/%%user_first_name%%/i", c_ws_plugin__s2member_utils_strings::esc_refs (urlencode ($user->first_name)), $url)) && ($url = preg_replace ("/%%user_last_name%%/i", c_ws_plugin__s2member_utils_strings::esc_refs (urlencode ($user->last_name)), $url)))
186
- if (($url = preg_replace ("/%%user_full_name%%/i", c_ws_plugin__s2member_utils_strings::esc_refs (urlencode (trim ($user->first_name . " " . $user->last_name))), $url)))
187
- if (($url = preg_replace ("/%%user_email%%/i", c_ws_plugin__s2member_utils_strings::esc_refs (urlencode ($user->user_email)), $url)))
188
- if (($url = preg_replace ("/%%user_login%%/i", c_ws_plugin__s2member_utils_strings::esc_refs (urlencode ($user->user_login)), $url)))
189
- if (($url = preg_replace ("/%%user_ip%%/i", c_ws_plugin__s2member_utils_strings::esc_refs (urlencode ($user_reg_ip)), $url)))
190
- if (($url = preg_replace ("/%%user_id%%/i", c_ws_plugin__s2member_utils_strings::esc_refs (urlencode ($user_id)), $url)))
191
- {
192
- if (is_array($fields) && !empty($fields))
193
- foreach /* Custom Registration/Profile Fields. */ ($fields as $var => $val)
194
- if (!($url = preg_replace ("/%%" . preg_quote ($var, "/") . "%%/i", c_ws_plugin__s2member_utils_strings::esc_refs (urlencode (maybe_serialize ($val))), $url)))
195
- break;
196
-
197
- if (($url = trim ($url))) // Preserve remaining replacements.
198
- // Because the parent routine may perform replacements too.
199
- $paypal["s2member_paypal_proxy_return_url"] = $url;
200
- }
201
- $paypal["s2member_log"][] = "Capability Return, a Proxy Return URL is ready.";
202
- }
203
- if ($processing && $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["payment_notification_urls"] && is_array($cv = preg_split ("/\|/", $paypal["custom"])))
204
- {
205
- foreach (preg_split ("/[\r\n\t]+/", $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["payment_notification_urls"]) as $url)
206
-
207
- if (($url = preg_replace ("/%%cv([0-9]+)%%/ei", 'urlencode(trim(@$cv[$1]))', $url)) && ($url = preg_replace ("/%%(?:subscr|txn)_id%%/i", c_ws_plugin__s2member_utils_strings::esc_refs (urlencode ($paypal["txn_id"])), $url)))
208
- if (($url = preg_replace ("/%%(?:subscr|txn)_baid%%/i", c_ws_plugin__s2member_utils_strings::esc_refs (urlencode ($paypal["txn_baid"])), $url)) && ($url = preg_replace ("/%%(?:subscr|txn)_cid%%/i", c_ws_plugin__s2member_utils_strings::esc_refs (urlencode ($paypal["txn_cid"])), $url)))
209
- if (($url = preg_replace ("/%%amount%%/i", c_ws_plugin__s2member_utils_strings::esc_refs (urlencode ($paypal["mc_gross"])), $url)) && ($url = preg_replace ("/%%txn_id%%/i", c_ws_plugin__s2member_utils_strings::esc_refs (urlencode ($paypal["txn_id"])), $url)))
210
- if (($url = preg_replace ("/%%item_number%%/i", c_ws_plugin__s2member_utils_strings::esc_refs (urlencode ($paypal["item_number"])), $url)) && ($url = preg_replace ("/%%item_name%%/i", c_ws_plugin__s2member_utils_strings::esc_refs (urlencode ($paypal["item_name"])), $url)))
211
- if (($url = preg_replace ("/%%first_name%%/i", c_ws_plugin__s2member_utils_strings::esc_refs (urlencode ($paypal["first_name"])), $url)) && ($url = preg_replace ("/%%last_name%%/i", c_ws_plugin__s2member_utils_strings::esc_refs (urlencode ($paypal["last_name"])), $url)))
212
- if (($url = preg_replace ("/%%full_name%%/i", c_ws_plugin__s2member_utils_strings::esc_refs (urlencode (trim ($paypal["first_name"] . " " . $paypal["last_name"]))), $url)))
213
- if (($url = preg_replace ("/%%payer_email%%/i", c_ws_plugin__s2member_utils_strings::esc_refs (urlencode ($paypal["payer_email"])), $url)))
214
-
215
- if (($url = preg_replace ("/%%full_coupon_code%%/i", c_ws_plugin__s2member_utils_strings::esc_refs (urlencode($coupon["full_coupon_code"])), $url)) && ($url = preg_replace ("/%%coupon_code%%/i", c_ws_plugin__s2member_utils_strings::esc_refs (urlencode($coupon["coupon_code"])), $url)) && ($url = preg_replace ("/%%coupon_affiliate_id%%/i", c_ws_plugin__s2member_utils_strings::esc_refs (urlencode($coupon["affiliate_id"])), $url)))
216
-
217
- if (($url = preg_replace ("/%%user_first_name%%/i", c_ws_plugin__s2member_utils_strings::esc_refs (urlencode ($user->first_name)), $url)) && ($url = preg_replace ("/%%user_last_name%%/i", c_ws_plugin__s2member_utils_strings::esc_refs (urlencode ($user->last_name)), $url)))
218
- if (($url = preg_replace ("/%%user_full_name%%/i", c_ws_plugin__s2member_utils_strings::esc_refs (urlencode (trim ($user->first_name . " " . $user->last_name))), $url)))
219
- if (($url = preg_replace ("/%%user_email%%/i", c_ws_plugin__s2member_utils_strings::esc_refs (urlencode ($user->user_email)), $url)))
220
- if (($url = preg_replace ("/%%user_login%%/i", c_ws_plugin__s2member_utils_strings::esc_refs (urlencode ($user->user_login)), $url)))
221
- if (($url = preg_replace ("/%%user_ip%%/i", c_ws_plugin__s2member_utils_strings::esc_refs (urlencode ($user_reg_ip)), $url)))
222
- if (($url = preg_replace ("/%%user_id%%/i", c_ws_plugin__s2member_utils_strings::esc_refs (urlencode ($user_id)), $url)))
223
- {
224
- if (is_array($fields) && !empty($fields))
225
- foreach /* Custom Registration/Profile Fields. */ ($fields as $var => $val)
226
- if (!($url = preg_replace ("/%%" . preg_quote ($var, "/") . "%%/i", c_ws_plugin__s2member_utils_strings::esc_refs (urlencode (maybe_serialize ($val))), $url)))
227
- break;
228
-
229
- if (($url = trim (preg_replace ("/%%(.+?)%%/i", "", $url))))
230
- c_ws_plugin__s2member_utils_urls::remote ($url);
231
- }
232
- $paypal["s2member_log"][] = "Payment Notification URLs have been processed.";
233
- }
234
- if ($processing && $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["payment_notification_recipients"] && is_array($cv = preg_split ("/\|/", $paypal["custom"])))
235
- {
236
- $msg = $sbj = "(s2Member / API Notification Email) - Payment";
237
- $msg .= "\n\n"; // Spacing in the message body.
238
-
239
- $msg .= "amount: %%amount%%\n";
240
- $msg .= "txn_id: %%txn_id%%\n";
241
- $msg .= "txn_baid: %%txn_baid%%\n";
242
- $msg .= "txn_cid: %%txn_cid%%\n";
243
- $msg .= "item_number: %%item_number%%\n";
244
- $msg .= "item_name: %%item_name%%\n";
245
- $msg .= "first_name: %%first_name%%\n";
246
- $msg .= "last_name: %%last_name%%\n";
247
- $msg .= "full_name: %%full_name%%\n";
248
- $msg .= "payer_email: %%payer_email%%\n";
249
-
250
- $msg .= "full_coupon_code: %%full_coupon_code%%\n";
251
- $msg .= "coupon_code: %%coupon_code%%\n";
252
- $msg .= "coupon_affiliate_id: %%coupon_affiliate_id%%\n";
253
-
254
- $msg .= "user_first_name: %%user_first_name%%\n";
255
- $msg .= "user_last_name: %%user_last_name%%\n";
256
- $msg .= "user_full_name: %%user_full_name%%\n";
257
- $msg .= "user_email: %%user_email%%\n";
258
- $msg .= "user_login: %%user_login%%\n";
259
- $msg .= "user_ip: %%user_ip%%\n";
260
- $msg .= "user_id: %%user_id%%\n";
261
-
262
- if (is_array($fields) && !empty($fields))
263
- foreach ($fields as $var => $val)
264
- $msg .= $var . ": %%" . $var . "%%\n";
265
-
266
- $msg .= "cv0: %%cv0%%\n";
267
- $msg .= "cv1: %%cv1%%\n";
268
- $msg .= "cv2: %%cv2%%\n";
269
- $msg .= "cv3: %%cv3%%\n";
270
- $msg .= "cv4: %%cv4%%\n";
271
- $msg .= "cv5: %%cv5%%\n";
272
- $msg .= "cv6: %%cv6%%\n";
273
- $msg .= "cv7: %%cv7%%\n";
274
- $msg .= "cv8: %%cv8%%\n";
275
- $msg .= "cv9: %%cv9%%";
276
-
277
- if (($msg = preg_replace ("/%%cv([0-9]+)%%/ei", 'trim(@$cv[$1])', $msg)) && ($msg = preg_replace ("/%%(?:subscr|txn)_id%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($paypal["txn_id"]), $msg)))
278
- if (($msg = preg_replace ("/%%(?:subscr|txn)_baid%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($paypal["txn_baid"]), $msg)) && ($msg = preg_replace ("/%%(?:subscr|txn)_cid%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($paypal["txn_cid"]), $msg)))
279
- if (($msg = preg_replace ("/%%amount%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($paypal["mc_gross"]), $msg)) && ($msg = preg_replace ("/%%txn_id%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($paypal["txn_id"]), $msg)))
280
- if (($msg = preg_replace ("/%%item_number%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($paypal["item_number"]), $msg)) && ($msg = preg_replace ("/%%item_name%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($paypal["item_name"]), $msg)))
281
- if (($msg = preg_replace ("/%%first_name%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($paypal["first_name"]), $msg)) && ($msg = preg_replace ("/%%last_name%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($paypal["last_name"]), $msg)))
282
- if (($msg = preg_replace ("/%%full_name%%/i", c_ws_plugin__s2member_utils_strings::esc_refs (trim ($paypal["first_name"] . " " . $paypal["last_name"])), $msg)))
283
- if (($msg = preg_replace ("/%%payer_email%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($paypal["payer_email"]), $msg)))
284
-
285
- if (($msg = preg_replace ("/%%full_coupon_code%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($coupon["full_coupon_code"]), $msg)) && ($msg = preg_replace ("/%%coupon_code%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($coupon["coupon_code"]), $msg)) && ($msg = preg_replace ("/%%coupon_affiliate_id%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($coupon["affiliate_id"]), $msg)))
286
-
287
- if (($msg = preg_replace ("/%%user_first_name%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($user->first_name), $msg)) && ($msg = preg_replace ("/%%user_last_name%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($user->last_name), $msg)))
288
- if (($msg = preg_replace ("/%%user_full_name%%/i", c_ws_plugin__s2member_utils_strings::esc_refs (trim ($user->first_name . " " . $user->last_name)), $msg)))
289
- if (($msg = preg_replace ("/%%user_email%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($user->user_email), $msg)))
290
- if (($msg = preg_replace ("/%%user_login%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($user->user_login), $msg)))
291
- if (($msg = preg_replace ("/%%user_ip%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($user_reg_ip), $msg)))
292
- if (($msg = preg_replace ("/%%user_id%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($user_id), $msg)))
293
- {
294
- if (is_array($fields) && !empty($fields))
295
- foreach /* Custom Registration/Profile Fields. */ ($fields as $var => $val)
296
- if (!($msg = preg_replace ("/%%" . preg_quote ($var, "/") . "%%/i", c_ws_plugin__s2member_utils_strings::esc_refs (maybe_serialize ($val)), $msg)))
297
- break;
298
-
299
- if ($sbj && ($msg = trim (preg_replace ("/%%(.+?)%%/i", "", $msg)))) // Still have a ``$sbj`` and a ``$msg``?
300
-
301
- foreach (c_ws_plugin__s2member_utils_strings::parse_emails ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["payment_notification_recipients"]) as $recipient)
302
- wp_mail ($recipient, apply_filters("ws_plugin__s2member_payment_notification_email_sbj", $sbj, get_defined_vars ()), apply_filters("ws_plugin__s2member_payment_notification_email_msg", $msg, get_defined_vars ()), "Content-Type: text/plain; charset=UTF-8");
303
- }
304
- $paypal["s2member_log"][] = "Payment Notification Emails have been processed.";
305
- }
306
- if ($processing && ($code = $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["ccap_tracking_codes"]) && is_array($cv = preg_split ("/\|/", $paypal["custom"])))
307
- {
308
- if (($code = preg_replace ("/%%cv([0-9]+)%%/ei", 'trim(@$cv[$1])', $code)) && ($code = preg_replace ("/%%(?:subscr|txn)_id%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($paypal["txn_id"]), $code)))
309
- if (($code = preg_replace ("/%%(?:subscr|txn)_baid%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($paypal["txn_baid"]), $code)) && ($code = preg_replace ("/%%(?:subscr|txn)_cid%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($paypal["txn_cid"]), $code)))
310
- if (($code = preg_replace ("/%%amount%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($paypal["mc_gross"]), $code)) && ($code = preg_replace ("/%%txn_id%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($paypal["txn_id"]), $code)))
311
- if (($code = preg_replace ("/%%item_number%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($paypal["item_number"]), $code)) && ($code = preg_replace ("/%%item_name%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($paypal["item_name"]), $code)))
312
- if (($code = preg_replace ("/%%first_name%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($paypal["first_name"]), $code)) && ($code = preg_replace ("/%%last_name%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($paypal["last_name"]), $code)))
313
- if (($code = preg_replace ("/%%full_name%%/i", c_ws_plugin__s2member_utils_strings::esc_refs (trim ($paypal["first_name"] . " " . $paypal["last_name"])), $code)))
314
- if (($code = preg_replace ("/%%payer_email%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($paypal["payer_email"]), $code)))
315
-
316
- if (($code = preg_replace ("/%%full_coupon_code%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($coupon["full_coupon_code"]), $code)) && ($code = preg_replace ("/%%coupon_code%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($coupon["coupon_code"]), $code)) && ($code = preg_replace ("/%%coupon_affiliate_id%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($coupon["affiliate_id"]), $code)))
317
-
318
- if (($code = preg_replace ("/%%user_first_name%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($user->first_name), $code)) && ($code = preg_replace ("/%%user_last_name%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($user->last_name), $code)))
319
- if (($code = preg_replace ("/%%user_full_name%%/i", c_ws_plugin__s2member_utils_strings::esc_refs (trim ($user->first_name . " " . $user->last_name)), $code)))
320
- if (($code = preg_replace ("/%%user_email%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($user->user_email), $code)))
321
- if (($code = preg_replace ("/%%user_login%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($user->user_login), $code)))
322
- if (($code = preg_replace ("/%%user_ip%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($user_reg_ip), $code)))
323
- if (($code = preg_replace ("/%%user_id%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($user_id), $code)))
324
- {
325
- if (is_array($fields) && !empty($fields))
326
- foreach /* Custom Registration/Profile Fields. */ ($fields as $var => $val)
327
- if (!($code = preg_replace ("/%%" . preg_quote ($var, "/") . "%%/i", c_ws_plugin__s2member_utils_strings::esc_refs (maybe_serialize ($val)), $code)))
328
- break;
329
-
330
- if (($code = trim (preg_replace ("/%%(.+?)%%/i", "", $code)))) // This gets stored into a Transient Queue.
331
- {
332
- $paypal["s2member_log"][] = "Storing Payment Tracking Codes into a Transient Queue. These will be processed on-site.";
333
- set_transient ("s2m_" . md5 ("s2member_transient_ccap_tracking_codes_" . $paypal["txn_id"]), $code, 43200);
334
- }
335
- }
336
- }
337
- foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;
338
- do_action("ws_plugin__s2member_during_paypal_notify_during_new_ccaps", get_defined_vars ());
339
- unset($__refs, $__v);
340
- }
341
- else $paypal["s2member_log"][] = "Unable to add new Capabilities. The existing User ID is associated with an Administrator. Stopping here. Otherwise, an Administrator could lose access.";
342
- }
343
- else $paypal["s2member_log"][] = "Unable to add new Capabilities. Could not get the existing User ID from the DB. Please check the `on0` and `os0` variables in your Button Code.";
344
- }
345
- else $paypal["s2member_log"][] = "Unable to add new Capabilities. Missing User/Member details. Please check the `on0` and `os0` variables in your Button Code.";
346
- }
347
- else // Else, this is a duplicate IPN. Must stop here.
348
- {
349
- $paypal["s2member_log"][] = "Not processing. Duplicate IPN.";
350
- $paypal["s2member_log"][] = "s2Member `txn_type` identified as ( `web_accept` ) w/ update vars for Capabilities w/o Level.";
351
- $paypal["s2member_log"][] = "Duplicate IPN. Already processed. This IPN will be ignored.";
352
- }
353
- foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;
354
- do_action("ws_plugin__s2member_during_paypal_notify_after_new_ccaps", get_defined_vars ());
355
  unset($__refs, $__v);
356
 
357
- return apply_filters("c_ws_plugin__s2member_paypal_notify_in_wa_ccaps_wo_level", $paypal, get_defined_vars ());
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
358
  }
359
- else return apply_filters("c_ws_plugin__s2member_paypal_notify_in_wa_ccaps_wo_level", false, get_defined_vars ());
 
 
360
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
361
  }
362
- }
 
 
 
1
  <?php
2
  /**
3
+ * s2Member's PayPal IPN handler (inner processing routine).
4
+ *
5
+ * Copyright: © 2009-2011
6
+ * {@link http://www.websharks-inc.com/ WebSharks, Inc.}
7
+ * (coded in the USA)
8
+ *
9
+ * Released under the terms of the GNU General Public License.
10
+ * You should have received a copy of the GNU General Public License,
11
+ * along with this software. In the main directory, see: /licensing/
12
+ * If not, see: {@link http://www.gnu.org/licenses/}.
13
+ *
14
+ * @package s2Member\PayPal
15
+ * @since 110815
16
+ */
17
+ if(realpath(__FILE__) === realpath($_SERVER['SCRIPT_FILENAME']))
18
+ exit ('Do not access this file directly.');
19
+
20
+ if(!class_exists('c_ws_plugin__s2member_paypal_notify_in_wa_ccaps_wo_level'))
21
+ {
22
+ /**
23
+ * s2Member's PayPal IPN handler (inner processing routine).
24
+ *
25
+ * @package s2Member\PayPal
26
+ * @since 110815
27
+ */
28
+ class c_ws_plugin__s2member_paypal_notify_in_wa_ccaps_wo_level
29
  {
30
  /**
31
+ * s2Member's PayPal IPN handler (inner processing routine).
32
+ *
33
+ * @package s2Member\PayPal
34
+ * @since 110815
35
+ *
36
+ * @param array $vars Required. An array of defined variables passed by {@link s2Member\PayPal\c_ws_plugin__s2member_paypal_notify_in::paypal_notify()}.
37
+ *
38
+ * @return array|bool The original ``$paypal`` array passed in (extracted) from ``$vars``, or false when conditions do NOT apply.
39
+ */
40
+ public static function cp($vars = array()) // Conditional phase for ``c_ws_plugin__s2member_paypal_notify_in::paypal_notify()``.
41
+ {
42
+ extract($vars, EXTR_OVERWRITE | EXTR_REFS); // Extract all vars passed in from: ``c_ws_plugin__s2member_paypal_notify_in::paypal_notify()``.
43
+
44
+ if((!empty($paypal['txn_type']) && preg_match('/^web_accept$/i', $paypal['txn_type']))
45
+ && (!empty($paypal['item_number']) && preg_match($GLOBALS['WS_PLUGIN__']['s2member']['c']['membership_item_number_wo_level_regex'], $paypal['item_number']))
46
+ && (empty($paypal['payment_status']) || empty($payment_status_issues) || !preg_match($payment_status_issues, $paypal['payment_status']))
47
+ && (!empty($paypal['txn_id'])) && (!empty($paypal['payer_email']))
48
+ && (!empty($paypal['txn_baid']) || ($paypal['txn_baid'] = $paypal['txn_id']))
49
+ && (!empty($paypal['txn_cid']) || ($paypal['txn_cid'] = $paypal['txn_id']))
50
+ )
51
  {
52
+ foreach(array_keys(get_defined_vars()) as $__v) $__refs[$__v] =& $$__v;
53
+ do_action('ws_plugin__s2member_during_paypal_notify_before_new_ccaps', get_defined_vars());
54
+ unset($__refs, $__v);
55
+
56
+ if(!get_transient($transient_ipn = 's2m_ipn_'.md5('s2member_transient_'.$_paypal_s)) && set_transient($transient_ipn, time(), 31556926 * 10))
57
+ {
58
+ $paypal['s2member_log'][] = 's2Member `txn_type` identified as ( `web_accept` ) w/ update vars for Capabilities w/o Level.';
59
+
60
+ list ($paypal['level'], $paypal['ccaps'], $paypal['eotper']) = preg_split('/\:/', $paypal['item_number'], 3);
61
+
62
+ $paypal['ip'] = (preg_match('/ip address/i', $paypal['option_name2']) && $paypal['option_selection2']) ? $paypal['option_selection2'] : '';
63
+ $paypal['ip'] = (!$paypal['ip'] && preg_match('/^[a-z0-9]+~[0-9\.]+$/i', $paypal['invoice'])) ? preg_replace('/^[a-z0-9]+~/i', '', $paypal['invoice']) : $paypal['ip'];
64
+
65
+ $paypal['currency'] = strtoupper($paypal['mc_currency']); // Normalize input currency.
66
+ $paypal['currency_symbol'] = c_ws_plugin__s2member_utils_cur::symbol($paypal['currency']);
67
+
68
+ if(preg_match('/(referenc|associat|updat|upgrad)/i', $paypal['option_name1']) && $paypal['option_selection1']) // Must have this information for Capability additions.
69
  {
70
+ if(($user_id = c_ws_plugin__s2member_utils_users::get_user_id_with($paypal['txn_id'], $paypal['option_selection1'])) && is_object($user = new WP_User ($user_id)) && $user->ID)
71
+ {
72
+ if(!$user->has_cap('administrator')) // Do NOT process this routine on Administrators.
 
 
 
 
 
73
  {
74
+ $processing = $during = TRUE; // Yes, we ARE processing this.
 
 
75
 
76
+ foreach(array_keys(get_defined_vars()) as $__v) $__refs[$__v] =& $$__v;
77
+ do_action('ws_plugin__s2member_during_paypal_notify_during_before_new_ccaps', get_defined_vars());
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
78
  unset($__refs, $__v);
79
 
80
+ $fields = get_user_option('s2member_custom_fields', $user_id); // These will be needed in the routines below.
81
+ $user_reg_ip = get_user_option('s2member_registration_ip', $user_id); // Original IP during Registration.
82
+ $user_reg_ip = $paypal['ip'] = ($user_reg_ip) ? $user_reg_ip : $paypal['ip']; // Now merge conditionally.
83
+
84
+ if(is_multisite() && !is_user_member_of_blog($user_id)) // Must have a Role on this Blog.
85
+ {
86
+ add_existing_user_to_blog(array('user_id' => $user_id, 'role' => get_option('default_role')));
87
+ $user = new WP_User ($user_id);
88
+ }
89
+ if($paypal['ccaps'] && preg_match('/^-all/', str_replace('+', '', $paypal['ccaps'])))
90
+ foreach($user->allcaps as $cap => $cap_enabled)
91
+ if(preg_match('/^access_s2member_ccap_/', $cap))
92
+ $user->remove_cap($ccap = $cap);
93
+
94
+ if($paypal['ccaps'] && preg_replace('/^-all['."\r\n\t".'\s;,]*/', '', str_replace('+', '', $paypal['ccaps'])))
95
+ foreach(preg_split('/['."\r\n\t".'\s;,]+/', preg_replace('/^-all['."\r\n\t".'\s;,]*/', '', str_replace('+', '', $paypal['ccaps']))) as $ccap)
96
+ if(strlen($ccap = trim(strtolower(preg_replace('/[^a-z_0-9]/i', '', $ccap)))))
97
+ $user->add_cap('access_s2member_ccap_'.$ccap);
98
+
99
+ if(!get_user_option('s2member_registration_ip', $user_id))
100
+ update_user_option($user_id, 's2member_registration_ip', $paypal['ip']);
101
+
102
+ $paypal['s2member_log'][] = 's2Member Custom Capabilities updated w/ advanced update routines.';
103
+
104
+ $sbj = $GLOBALS['WS_PLUGIN__']['s2member']['o']['ccap_email_subject']; // The same for standard and w/ Pro Forms.
105
+ $msg = $GLOBALS['WS_PLUGIN__']['s2member']['o']['ccap_email_message']; // The same for standard and w/ Pro Forms.
106
+ $rec = $GLOBALS['WS_PLUGIN__']['s2member']['o']['ccap_email_recipients']; // The same for standard and w/ Pro Forms.
107
+
108
+ if(($rec = preg_replace('/%%cv([0-9]+)%%/ei', 'trim(@$cv[$1])', $rec)) && ($rec = preg_replace('/%%(?:subscr|txn)_id%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['txn_id']), $rec)))
109
+ if(($rec = preg_replace('/%%(?:subscr|txn)_baid%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['txn_baid']), $rec)) && ($rec = preg_replace('/%%(?:subscr|txn)_cid%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['txn_cid']), $rec)))
110
+ if(($rec = preg_replace('/%%currency%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['currency']), $rec)) && ($rec = preg_replace('/%%currency_symbol%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['currency_symbol']), $rec)))
111
+ if(($rec = preg_replace('/%%amount%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['mc_gross']), $rec)) && ($rec = preg_replace('/%%txn_id%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['txn_id']), $rec)))
112
+ if(($rec = preg_replace('/%%item_number%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['item_number']), $rec)) && ($rec = preg_replace('/%%item_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['item_name']), $rec)))
113
+ if(($rec = preg_replace('/%%first_name%%/i', c_ws_plugin__s2member_utils_strings::esc_dq(c_ws_plugin__s2member_utils_strings::esc_refs($paypal['first_name'])), $rec)) && ($rec = preg_replace('/%%last_name%%/i', c_ws_plugin__s2member_utils_strings::esc_dq(c_ws_plugin__s2member_utils_strings::esc_refs($paypal['last_name'])), $rec)))
114
+ if(($rec = preg_replace('/%%full_name%%/i', c_ws_plugin__s2member_utils_strings::esc_dq(c_ws_plugin__s2member_utils_strings::esc_refs(trim($paypal['first_name'].' '.$paypal['last_name']))), $rec))) // **NOTE** c_ws_plugin__s2member_utils_strings::esc_dq() is applied here. (ex. 'N\'ame' <email>).
115
+ if(($rec = preg_replace('/%%payer_email%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['payer_email']), $rec)))
116
+
117
+ if(($rec = preg_replace('/%%full_coupon_code%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($coupon['full_coupon_code']), $rec)) && ($rec = preg_replace('/%%coupon_code%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($coupon['coupon_code']), $rec)) && ($rec = preg_replace('/%%coupon_affiliate_id%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($coupon['affiliate_id']), $rec)))
118
+
119
+ if(($rec = preg_replace('/%%user_first_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($user->first_name), $rec)) && ($rec = preg_replace('/%%user_last_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($user->last_name), $rec)))
120
+ if(($rec = preg_replace('/%%user_full_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(trim($user->first_name.' '.$user->last_name)), $rec)))
121
+ if(($rec = preg_replace('/%%user_email%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($user->user_email), $rec)))
122
+ if(($rec = preg_replace('/%%user_login%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($user->user_login), $rec)))
123
+ if(($rec = preg_replace('/%%user_ip%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($user_reg_ip), $rec)))
124
+ if(($rec = preg_replace('/%%user_id%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($user_id), $rec)))
125
+
126
+ if(($sbj = preg_replace('/%%cv([0-9]+)%%/ei', 'trim(@$cv[$1])', $sbj)) && ($sbj = preg_replace('/%%(?:subscr|txn)_id%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['txn_id']), $sbj)))
127
+ if(($sbj = preg_replace('/%%(?:subscr|txn)_baid%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['txn_baid']), $sbj)) && ($sbj = preg_replace('/%%(?:subscr|txn)_cid%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['txn_cid']), $sbj)))
128
+ if(($sbj = preg_replace('/%%currency%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['currency']), $sbj)) && ($sbj = preg_replace('/%%currency_symbol%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['currency_symbol']), $sbj)))
129
+ if(($sbj = preg_replace('/%%amount%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['mc_gross']), $sbj)) && ($sbj = preg_replace('/%%txn_id%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['txn_id']), $sbj)))
130
+ if(($sbj = preg_replace('/%%item_number%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['item_number']), $sbj)) && ($sbj = preg_replace('/%%item_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['item_name']), $sbj)))
131
+ if(($sbj = preg_replace('/%%first_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['first_name']), $sbj)) && ($sbj = preg_replace('/%%last_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['last_name']), $sbj)))
132
+ if(($sbj = preg_replace('/%%full_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(trim($paypal['first_name'].' '.$paypal['last_name'])), $sbj)))
133
+ if(($sbj = preg_replace('/%%payer_email%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['payer_email']), $sbj)))
134
+
135
+ if(($sbj = preg_replace('/%%full_coupon_code%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($coupon['full_coupon_code']), $sbj)) && ($sbj = preg_replace('/%%coupon_code%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($coupon['coupon_code']), $sbj)) && ($sbj = preg_replace('/%%coupon_affiliate_id%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($coupon['affiliate_id']), $sbj)))
136
+
137
+ if(($sbj = preg_replace('/%%user_first_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($user->first_name), $sbj)) && ($sbj = preg_replace('/%%user_last_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($user->last_name), $sbj)))
138
+ if(($sbj = preg_replace('/%%user_full_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(trim($user->first_name.' '.$user->last_name)), $sbj)))
139
+ if(($sbj = preg_replace('/%%user_email%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($user->user_email), $sbj)))
140
+ if(($sbj = preg_replace('/%%user_login%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($user->user_login), $sbj)))
141
+ if(($sbj = preg_replace('/%%user_ip%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($user_reg_ip), $sbj)))
142
+ if(($sbj = preg_replace('/%%user_id%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($user_id), $sbj)))
143
+
144
+ if(($msg = preg_replace('/%%cv([0-9]+)%%/ei', 'trim(@$cv[$1])', $msg)) && ($msg = preg_replace('/%%(?:subscr|txn)_id%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['txn_id']), $msg)))
145
+ if(($msg = preg_replace('/%%(?:subscr|txn)_baid%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['txn_baid']), $msg)) && ($msg = preg_replace('/%%(?:subscr|txn)_cid%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['txn_cid']), $msg)))
146
+ if(($msg = preg_replace('/%%currency%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['currency']), $msg)) && ($msg = preg_replace('/%%currency_symbol%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['currency_symbol']), $msg)))
147
+ if(($msg = preg_replace('/%%amount%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['mc_gross']), $msg)) && ($msg = preg_replace('/%%txn_id%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['txn_id']), $msg)))
148
+ if(($msg = preg_replace('/%%item_number%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['item_number']), $msg)) && ($msg = preg_replace('/%%item_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['item_name']), $msg)))
149
+ if(($msg = preg_replace('/%%first_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['first_name']), $msg)) && ($msg = preg_replace('/%%last_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['last_name']), $msg)))
150
+ if(($msg = preg_replace('/%%full_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(trim($paypal['first_name'].' '.$paypal['last_name'])), $msg)))
151
+ if(($msg = preg_replace('/%%payer_email%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['payer_email']), $msg)))
152
+
153
+ if(($msg = preg_replace('/%%full_coupon_code%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($coupon['full_coupon_code']), $msg)) && ($msg = preg_replace('/%%coupon_code%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($coupon['coupon_code']), $msg)) && ($msg = preg_replace('/%%coupon_affiliate_id%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($coupon['affiliate_id']), $msg)))
154
+
155
+ if(($msg = preg_replace('/%%user_first_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($user->first_name), $msg)) && ($msg = preg_replace('/%%user_last_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($user->last_name), $msg)))
156
+ if(($msg = preg_replace('/%%user_full_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(trim($user->first_name.' '.$user->last_name)), $msg)))
157
+ if(($msg = preg_replace('/%%user_email%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($user->user_email), $msg)))
158
+ if(($msg = preg_replace('/%%user_login%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($user->user_login), $msg)))
159
+ if(($msg = preg_replace('/%%user_ip%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($user_reg_ip), $msg)))
160
+ if(($msg = preg_replace('/%%user_id%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($user_id), $msg)))
161
+ {
162
+ if(is_array($fields) && !empty($fields)) foreach($fields as $var => $val /* Custom Registration/Profile Fields. */)
163
+ {
164
+ $rec = preg_replace('/%%'.preg_quote($var, '/').'%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(maybe_serialize($val)), $rec);
165
+ $sbj = preg_replace('/%%'.preg_quote($var, '/').'%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(maybe_serialize($val)), $sbj);
166
+ $msg = preg_replace('/%%'.preg_quote($var, '/').'%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(maybe_serialize($val)), $msg);
167
+ }
168
+ if(($rec = trim(preg_replace('/%%(.+?)%%/i', '', $rec))) && ($sbj = trim(preg_replace('/%%(.+?)%%/i', '', $sbj))) && ($msg = trim(preg_replace('/%%(.+?)%%/i', '', $msg))))
169
+ {
170
+ if(!is_multisite() || !c_ws_plugin__s2member_utils_conds::is_multisite_farm() || is_main_site())
171
+ {
172
+ $sbj = c_ws_plugin__s2member_utilities::evl($sbj, get_defined_vars());
173
+ $msg = c_ws_plugin__s2member_utilities::evl($msg, get_defined_vars());
174
+ }
175
+ foreach(c_ws_plugin__s2member_utils_strings::parse_emails($rec) as $recipient /* Go through a possible list of recipients. */)
176
+ c_ws_plugin__s2member_email_configs::email_config().wp_mail($recipient, apply_filters('ws_plugin__s2member_capabilities_email_sbj', $sbj, get_defined_vars()), apply_filters('ws_plugin__s2member_capabilities_email_msg', $msg, get_defined_vars()), 'From: "'.preg_replace('/"/', '"', $GLOBALS['WS_PLUGIN__']['s2member']['o']['reg_email_from_name']).'" <'.$GLOBALS['WS_PLUGIN__']['s2member']['o']['reg_email_from_email'].'>'."\r\n".'Content-Type: text/plain; charset=UTF-8').c_ws_plugin__s2member_email_configs::email_config_release();
177
+
178
+ $paypal['s2member_log'][] = 'Capability Confirmation Email sent to: '.$rec.'.';
179
+ }
180
+ }
181
+ if($processing && $_REQUEST['s2member_paypal_proxy'] && ($url = $_REQUEST['s2member_paypal_proxy_return_url']) && is_array($cv = preg_split('/\|/', $paypal['custom']))) // A Proxy is requesting a Return URL?
182
+ {
183
+ if(($url = preg_replace('/%%cv([0-9]+)%%/ei', 'urlencode(trim(@$cv[$1]))', $url)) && ($url = preg_replace('/%%(?:subscr|txn)_id%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($paypal['txn_id'])), $url)))
184
+ if(($url = preg_replace('/%%(?:subscr|txn)_baid%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($paypal['txn_baid'])), $url)) && ($url = preg_replace('/%%(?:subscr|txn)_cid%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($paypal['txn_cid'])), $url)))
185
+ if(($url = preg_replace('/%%currency%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($paypal['currency'])), $url)) && ($url = preg_replace('/%%currency_symbol%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($paypal['currency_symbol'])), $url)))
186
+ if(($url = preg_replace('/%%amount%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($paypal['mc_gross'])), $url)) && ($url = preg_replace('/%%txn_id%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($paypal['txn_id'])), $url)))
187
+ if(($url = preg_replace('/%%item_number%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($paypal['item_number'])), $url)) && ($url = preg_replace('/%%item_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($paypal['item_name'])), $url)))
188
+ if(($url = preg_replace('/%%first_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($paypal['first_name'])), $url)) && ($url = preg_replace('/%%last_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($paypal['last_name'])), $url)))
189
+ if(($url = preg_replace('/%%full_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode(trim($paypal['first_name'].' '.$paypal['last_name']))), $url)))
190
+ if(($url = preg_replace('/%%payer_email%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($paypal['payer_email'])), $url)))
191
+
192
+ if(($url = preg_replace('/%%full_coupon_code%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($coupon['full_coupon_code'])), $url)) && ($url = preg_replace('/%%coupon_code%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($coupon['coupon_code'])), $url)) && ($url = preg_replace('/%%coupon_affiliate_id%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($coupon['affiliate_id'])), $url)))
193
+
194
+ if(($url = preg_replace('/%%user_first_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($user->first_name)), $url)) && ($url = preg_replace('/%%user_last_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($user->last_name)), $url)))
195
+ if(($url = preg_replace('/%%user_full_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode(trim($user->first_name.' '.$user->last_name))), $url)))
196
+ if(($url = preg_replace('/%%user_email%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($user->user_email)), $url)))
197
+ if(($url = preg_replace('/%%user_login%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($user->user_login)), $url)))
198
+ if(($url = preg_replace('/%%user_ip%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($user_reg_ip)), $url)))
199
+ if(($url = preg_replace('/%%user_id%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($user_id)), $url)))
200
+ {
201
+ if(is_array($fields) && !empty($fields))
202
+ foreach($fields as $var => $val /* Custom Registration/Profile Fields. */)
203
+ if(!($url = preg_replace('/%%'.preg_quote($var, '/').'%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode(maybe_serialize($val))), $url)))
204
+ break;
205
+
206
+ if(($url = trim($url))) // Preserve remaining replacements.
207
+ // Because the parent routine may perform replacements too.
208
+ $paypal['s2member_paypal_proxy_return_url'] = $url;
209
+ }
210
+ $paypal['s2member_log'][] = 'Capability Return, a Proxy Return URL is ready.';
211
+ }
212
+ if($processing && $GLOBALS['WS_PLUGIN__']['s2member']['o']['payment_notification_urls'] && is_array($cv = preg_split('/\|/', $paypal['custom'])))
213
+ {
214
+ foreach(preg_split('/['."\r\n\t".']+/', $GLOBALS['WS_PLUGIN__']['s2member']['o']['payment_notification_urls']) as $url)
215
+
216
+ if(($url = preg_replace('/%%cv([0-9]+)%%/ei', 'urlencode(trim(@$cv[$1]))', $url)) && ($url = preg_replace('/%%(?:subscr|txn)_id%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($paypal['txn_id'])), $url)))
217
+ if(($url = preg_replace('/%%(?:subscr|txn)_baid%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($paypal['txn_baid'])), $url)) && ($url = preg_replace('/%%(?:subscr|txn)_cid%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($paypal['txn_cid'])), $url)))
218
+ if(($url = preg_replace('/%%currency%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($paypal['currency'])), $url)) && ($url = preg_replace('/%%currency_symbol%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($paypal['currency_symbol'])), $url)))
219
+ if(($url = preg_replace('/%%amount%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($paypal['mc_gross'])), $url)) && ($url = preg_replace('/%%txn_id%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($paypal['txn_id'])), $url)))
220
+ if(($url = preg_replace('/%%item_number%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($paypal['item_number'])), $url)) && ($url = preg_replace('/%%item_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($paypal['item_name'])), $url)))
221
+ if(($url = preg_replace('/%%first_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($paypal['first_name'])), $url)) && ($url = preg_replace('/%%last_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($paypal['last_name'])), $url)))
222
+ if(($url = preg_replace('/%%full_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode(trim($paypal['first_name'].' '.$paypal['last_name']))), $url)))
223
+ if(($url = preg_replace('/%%payer_email%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($paypal['payer_email'])), $url)))
224
+
225
+ if(($url = preg_replace('/%%full_coupon_code%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($coupon['full_coupon_code'])), $url)) && ($url = preg_replace('/%%coupon_code%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($coupon['coupon_code'])), $url)) && ($url = preg_replace('/%%coupon_affiliate_id%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($coupon['affiliate_id'])), $url)))
226
+
227
+ if(($url = preg_replace('/%%user_first_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($user->first_name)), $url)) && ($url = preg_replace('/%%user_last_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($user->last_name)), $url)))
228
+ if(($url = preg_replace('/%%user_full_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode(trim($user->first_name.' '.$user->last_name))), $url)))
229
+ if(($url = preg_replace('/%%user_email%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($user->user_email)), $url)))
230
+ if(($url = preg_replace('/%%user_login%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($user->user_login)), $url)))
231
+ if(($url = preg_replace('/%%user_ip%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($user_reg_ip)), $url)))
232
+ if(($url = preg_replace('/%%user_id%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($user_id)), $url)))
233
+ {
234
+ if(is_array($fields) && !empty($fields))
235
+ foreach($fields as $var => $val /* Custom Registration/Profile Fields. */)
236
+ if(!($url = preg_replace('/%%'.preg_quote($var, '/').'%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode(maybe_serialize($val))), $url)))
237
+ break;
238
+
239
+ if(($url = trim(preg_replace('/%%(.+?)%%/i', '', $url))))
240
+ c_ws_plugin__s2member_utils_urls::remote($url);
241
+ }
242
+ $paypal['s2member_log'][] = 'Payment Notification URLs have been processed.';
243
+ }
244
+ if($processing && $GLOBALS['WS_PLUGIN__']['s2member']['o']['payment_notification_recipients'] && is_array($cv = preg_split('/\|/', $paypal['custom'])))
245
+ {
246
+ $msg = $sbj = '(s2Member / API Notification Email) - Payment';
247
+ $msg .= "\n\n"; // Spacing in the message body.
248
+
249
+ $msg .= 'currency: %%currency%%'."\n";
250
+ $msg .= 'currency_symbol: %%currency_symbol%%'."\n";
251
+ $msg .= 'amount: %%amount%%'."\n";
252
+ $msg .= 'txn_id: %%txn_id%%'."\n";
253
+ $msg .= 'txn_baid: %%txn_baid%%'."\n";
254
+ $msg .= 'txn_cid: %%txn_cid%%'."\n";
255
+ $msg .= 'item_number: %%item_number%%'."\n";
256
+ $msg .= 'item_name: %%item_name%%'."\n";
257
+ $msg .= 'first_name: %%first_name%%'."\n";
258
+ $msg .= 'last_name: %%last_name%%'."\n";
259
+ $msg .= 'full_name: %%full_name%%'."\n";
260
+ $msg .= 'payer_email: %%payer_email%%'."\n";
261
+
262
+ $msg .= 'full_coupon_code: %%full_coupon_code%%'."\n";
263
+ $msg .= 'coupon_code: %%coupon_code%%'."\n";
264
+ $msg .= 'coupon_affiliate_id: %%coupon_affiliate_id%%'."\n";
265
+
266
+ $msg .= 'user_first_name: %%user_first_name%%'."\n";
267
+ $msg .= 'user_last_name: %%user_last_name%%'."\n";
268
+ $msg .= 'user_full_name: %%user_full_name%%'."\n";
269
+ $msg .= 'user_email: %%user_email%%'."\n";
270
+ $msg .= 'user_login: %%user_login%%'."\n";
271
+ $msg .= 'user_ip: %%user_ip%%'."\n";
272
+ $msg .= 'user_id: %%user_id%%'."\n";
273
+
274
+ if(is_array($fields) && !empty($fields))
275
+ foreach($fields as $var => $val)
276
+ $msg .= $var.': %%'.$var.'%%'."\n";
277
+
278
+ $msg .= 'cv0: %%cv0%%'."\n";
279
+ $msg .= 'cv1: %%cv1%%'."\n";
280
+ $msg .= 'cv2: %%cv2%%'."\n";
281
+ $msg .= 'cv3: %%cv3%%'."\n";
282
+ $msg .= 'cv4: %%cv4%%'."\n";
283
+ $msg .= 'cv5: %%cv5%%'."\n";
284
+ $msg .= 'cv6: %%cv6%%'."\n";
285
+ $msg .= 'cv7: %%cv7%%'."\n";
286
+ $msg .= 'cv8: %%cv8%%'."\n";
287
+ $msg .= 'cv9: %%cv9%%';
288
+
289
+ if(($msg = preg_replace('/%%cv([0-9]+)%%/ei', 'trim(@$cv[$1])', $msg)) && ($msg = preg_replace('/%%(?:subscr|txn)_id%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['txn_id']), $msg)))
290
+ if(($msg = preg_replace('/%%(?:subscr|txn)_baid%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['txn_baid']), $msg)) && ($msg = preg_replace('/%%(?:subscr|txn)_cid%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['txn_cid']), $msg)))
291
+ if(($msg = preg_replace('/%%currency%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['currency']), $msg)) && ($msg = preg_replace('/%%currency_symbol%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['currency_symbol']), $msg)))
292
+ if(($msg = preg_replace('/%%amount%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['mc_gross']), $msg)) && ($msg = preg_replace('/%%txn_id%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['txn_id']), $msg)))
293
+ if(($msg = preg_replace('/%%item_number%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['item_number']), $msg)) && ($msg = preg_replace('/%%item_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['item_name']), $msg)))
294
+ if(($msg = preg_replace('/%%first_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['first_name']), $msg)) && ($msg = preg_replace('/%%last_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['last_name']), $msg)))
295
+ if(($msg = preg_replace('/%%full_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(trim($paypal['first_name'].' '.$paypal['last_name'])), $msg)))
296
+ if(($msg = preg_replace('/%%payer_email%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['payer_email']), $msg)))
297
+
298
+ if(($msg = preg_replace('/%%full_coupon_code%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($coupon['full_coupon_code']), $msg)) && ($msg = preg_replace('/%%coupon_code%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($coupon['coupon_code']), $msg)) && ($msg = preg_replace('/%%coupon_affiliate_id%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($coupon['affiliate_id']), $msg)))
299
+
300
+ if(($msg = preg_replace('/%%user_first_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($user->first_name), $msg)) && ($msg = preg_replace('/%%user_last_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($user->last_name), $msg)))
301
+ if(($msg = preg_replace('/%%user_full_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(trim($user->first_name.' '.$user->last_name)), $msg)))
302
+ if(($msg = preg_replace('/%%user_email%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($user->user_email), $msg)))
303
+ if(($msg = preg_replace('/%%user_login%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($user->user_login), $msg)))
304
+ if(($msg = preg_replace('/%%user_ip%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($user_reg_ip), $msg)))
305
+ if(($msg = preg_replace('/%%user_id%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($user_id), $msg)))
306
+ {
307
+ if(is_array($fields) && !empty($fields))
308
+ foreach($fields as $var => $val /* Custom Registration/Profile Fields. */)
309
+ if(!($msg = preg_replace('/%%'.preg_quote($var, '/').'%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(maybe_serialize($val)), $msg)))
310
+ break;
311
+
312
+ if($sbj && ($msg = trim(preg_replace('/%%(.+?)%%/i', '', $msg)))) // Still have a ``$sbj`` and a ``$msg``?
313
+
314
+ foreach(c_ws_plugin__s2member_utils_strings::parse_emails($GLOBALS['WS_PLUGIN__']['s2member']['o']['payment_notification_recipients']) as $recipient)
315
+ wp_mail($recipient, apply_filters('ws_plugin__s2member_payment_notification_email_sbj', $sbj, get_defined_vars()), apply_filters('ws_plugin__s2member_payment_notification_email_msg', $msg, get_defined_vars()), 'Content-Type: text/plain; charset=UTF-8');
316
+ }
317
+ $paypal['s2member_log'][] = 'Payment Notification Emails have been processed.';
318
+ }
319
+ if($processing && ($code = $GLOBALS['WS_PLUGIN__']['s2member']['o']['ccap_tracking_codes']) && is_array($cv = preg_split('/\|/', $paypal['custom'])))
320
+ {
321
+ if(($code = preg_replace('/%%cv([0-9]+)%%/ei', 'trim(@$cv[$1])', $code)) && ($code = preg_replace('/%%(?:subscr|txn)_id%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['txn_id']), $code)))
322
+ if(($code = preg_replace('/%%(?:subscr|txn)_baid%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['txn_baid']), $code)) && ($code = preg_replace('/%%(?:subscr|txn)_cid%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['txn_cid']), $code)))
323
+ if(($code = preg_replace('/%%currency%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['currency']), $code)) && ($code = preg_replace('/%%currency_symbol%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['currency_symbol']), $code)))
324
+ if(($code = preg_replace('/%%amount%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['mc_gross']), $code)) && ($code = preg_replace('/%%txn_id%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['txn_id']), $code)))
325
+ if(($code = preg_replace('/%%item_number%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['item_number']), $code)) && ($code = preg_replace('/%%item_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['item_name']), $code)))
326
+ if(($code = preg_replace('/%%first_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['first_name']), $code)) && ($code = preg_replace('/%%last_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['last_name']), $code)))
327
+ if(($code = preg_replace('/%%full_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(trim($paypal['first_name'].' '.$paypal['last_name'])), $code)))
328
+ if(($code = preg_replace('/%%payer_email%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['payer_email']), $code)))
329
+
330
+ if(($code = preg_replace('/%%full_coupon_code%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($coupon['full_coupon_code']), $code)) && ($code = preg_replace('/%%coupon_code%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($coupon['coupon_code']), $code)) && ($code = preg_replace('/%%coupon_affiliate_id%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($coupon['affiliate_id']), $code)))
331
+
332
+ if(($code = preg_replace('/%%user_first_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($user->first_name), $code)) && ($code = preg_replace('/%%user_last_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($user->last_name), $code)))
333
+ if(($code = preg_replace('/%%user_full_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(trim($user->first_name.' '.$user->last_name)), $code)))
334
+ if(($code = preg_replace('/%%user_email%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($user->user_email), $code)))
335
+ if(($code = preg_replace('/%%user_login%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($user->user_login), $code)))
336
+ if(($code = preg_replace('/%%user_ip%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($user_reg_ip), $code)))
337
+ if(($code = preg_replace('/%%user_id%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($user_id), $code)))
338
+ {
339
+ if(is_array($fields) && !empty($fields))
340
+ foreach($fields as $var => $val /* Custom Registration/Profile Fields. */)
341
+ if(!($code = preg_replace('/%%'.preg_quote($var, '/').'%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(maybe_serialize($val)), $code)))
342
+ break;
343
+
344
+ if(($code = trim(preg_replace('/%%(.+?)%%/i', '', $code)))) // This gets stored into a Transient Queue.
345
+ {
346
+ $paypal['s2member_log'][] = 'Storing Payment Tracking Codes into a Transient Queue. These will be processed on-site.';
347
+ set_transient('s2m_'.md5('s2member_transient_ccap_tracking_codes_'.$paypal['txn_id']), $code, 43200);
348
+ }
349
+ }
350
+ }
351
+ foreach(array_keys(get_defined_vars()) as $__v) $__refs[$__v] =& $$__v;
352
+ do_action('ws_plugin__s2member_during_paypal_notify_during_new_ccaps', get_defined_vars());
353
+ unset($__refs, $__v);
354
  }
355
+ else $paypal['s2member_log'][] = 'Unable to add new Capabilities. The existing User ID is associated with an Administrator. Stopping here. Otherwise, an Administrator could lose access.';
356
+ }
357
+ else $paypal['s2member_log'][] = 'Unable to add new Capabilities. Could not get the existing User ID from the DB. Please check the `on0` and `os0` variables in your Button Code.';
358
  }
359
+ else $paypal['s2member_log'][] = 'Unable to add new Capabilities. Missing User/Member details. Please check the `on0` and `os0` variables in your Button Code.';
360
+ }
361
+ else // Else, this is a duplicate IPN. Must stop here.
362
+ {
363
+ $paypal['s2member_log'][] = 'Not processing. Duplicate IPN.';
364
+ $paypal['s2member_log'][] = 's2Member `txn_type` identified as ( `web_accept` ) w/ update vars for Capabilities w/o Level.';
365
+ $paypal['s2member_log'][] = 'Duplicate IPN. Already processed. This IPN will be ignored.';
366
+ }
367
+ foreach(array_keys(get_defined_vars()) as $__v) $__refs[$__v] =& $$__v;
368
+ do_action('ws_plugin__s2member_during_paypal_notify_after_new_ccaps', get_defined_vars());
369
+ unset($__refs, $__v);
370
+
371
+ return apply_filters('c_ws_plugin__s2member_paypal_notify_in_wa_ccaps_wo_level', $paypal, get_defined_vars());
372
  }
373
+ else return apply_filters('c_ws_plugin__s2member_paypal_notify_in_wa_ccaps_wo_level', FALSE, get_defined_vars());
374
+ }
375
+ }
376
+ }
includes/classes/paypal-notify-in-web-accept-sp.inc.php CHANGED
@@ -1,257 +1,271 @@
1
  <?php
2
  /**
3
- * s2Member's PayPal IPN handler (inner processing routine).
4
- *
5
- * Copyright: © 2009-2011
6
- * {@link http://www.websharks-inc.com/ WebSharks, Inc.}
7
- * (coded in the USA)
8
- *
9
- * Released under the terms of the GNU General Public License.
10
- * You should have received a copy of the GNU General Public License,
11
- * along with this software. In the main directory, see: /licensing/
12
- * If not, see: {@link http://www.gnu.org/licenses/}.
13
- *
14
- * @package s2Member\PayPal
15
- * @since 110720
16
- */
17
- if (realpath (__FILE__) === realpath ($_SERVER["SCRIPT_FILENAME"]))
18
- exit ("Do not access this file directly.");
19
 
20
- if (!class_exists ("c_ws_plugin__s2member_paypal_notify_in_web_accept_sp"))
 
 
 
 
 
 
 
 
21
  {
22
  /**
23
- * s2Member's PayPal IPN handler (inner processing routine).
24
- *
25
- * @package s2Member\PayPal
26
- * @since 110720
27
- */
28
- class c_ws_plugin__s2member_paypal_notify_in_web_accept_sp
29
- {
30
- /**
31
- * s2Member's PayPal IPN handler (inner processing routine).
32
- *
33
- * @package s2Member\PayPal
34
- * @since 110720
35
- *
36
- * @param array $vars Required. An array of defined variables passed by {@link s2Member\PayPal\c_ws_plugin__s2member_paypal_notify_in::paypal_notify()}.
37
- * @return array|bool The original ``$paypal`` array passed in (extracted) from ``$vars``, or false when conditions do NOT apply.
38
- */
39
- public static function cp ($vars = array()) // Conditional phase for ``c_ws_plugin__s2member_paypal_notify_in::paypal_notify()``.
40
- {
41
- extract ($vars, EXTR_OVERWRITE | EXTR_REFS); // Extract all vars passed in from: ``c_ws_plugin__s2member_paypal_notify_in::paypal_notify()``.
42
 
43
- if ((!empty($paypal["txn_type"]) && preg_match ("/^web_accept$/i", $paypal["txn_type"]))
44
- && (!empty($paypal["item_number"]) && preg_match ($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["sp_access_item_number_regex"], $paypal["item_number"]))
45
- && (empty($paypal["payment_status"]) || empty($payment_status_issues) || !preg_match ($payment_status_issues, $paypal["payment_status"]))
46
- && (!empty($paypal["payer_email"])) && (!empty($paypal["txn_id"])) && (!empty($paypal["txn_baid"]) || ($paypal["txn_baid"] = $paypal["txn_id"]))
47
- && (!empty($paypal["txn_cid"]) || ($paypal["txn_cid"] = $paypal["txn_id"])))
48
- {
49
- foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;
50
- do_action("ws_plugin__s2member_during_paypal_notify_before_sp_access", get_defined_vars ());
51
- unset($__refs, $__v);
 
52
 
53
- if (!get_transient ($transient_ipn = "s2m_ipn_" . md5 ("s2member_transient_" . $_paypal_s)) && set_transient ($transient_ipn, time (), 31556926 * 10))
54
- {
55
- $paypal["s2member_log"][] = "s2Member `txn_type` identified as ( `web_accept` ) for Specific Post/Page Access.";
56
 
57
- list (, $paypal["sp_ids"], $paypal["hours"]) = preg_split ("/\:/", $paypal["item_number"], 3);
58
 
59
- $paypal["ip"] = (preg_match ("/ip address/i", $paypal["option_name2"]) && $paypal["option_selection2"]) ? $paypal["option_selection2"] : "";
60
- $paypal["ip"] = (!$paypal["ip"] && preg_match ("/^[a-z0-9]+~[0-9\.]+$/i", $paypal["invoice"])) ? preg_replace ("/^[a-z0-9]+~/i", "", $paypal["invoice"]) : $paypal["ip"];
61
 
62
- if (($sp_access_url = c_ws_plugin__s2member_sp_access::sp_access_link_gen ($paypal["sp_ids"], $paypal["hours"])) && is_array($cv = preg_split ("/\|/", $paypal["custom"])))
63
- {
64
- $processing = $during = true; // Yes, we ARE processing this.
65
 
66
- if (preg_match ("/(referenc|associat)/i", $paypal["option_name1"]) && $paypal["option_selection1"]) // Associating this purchase with a Member?
67
- if (($user_id = c_ws_plugin__s2member_utils_users::get_user_id_with ($paypal["option_selection1"], $paypal["option_selection1"])) && is_object ($user = new WP_User ($user_id)) && $user->ID)
68
- {
69
- $sp_references = (array)get_user_option ("s2member_sp_references", $user_id);
70
- $_sp_reference = array("time" => time (), "ids" => $paypal["sp_ids"], "hours" => $paypal["hours"], "url" => $sp_access_url);
71
- $sp_references = c_ws_plugin__s2member_utils_arrays::array_unique (array_merge ($sp_references, $_sp_reference));
72
- update_user_option ($user_id, "s2member_sp_references", $sp_references);
73
 
74
- $paypal["s2member_log"][] = "Specific Post/Page ~ Sale associated with User ID: " . $user_id . ".";
75
- }
76
- $sbj = preg_replace ("/%%sp_access_url%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($sp_access_url), $GLOBALS["WS_PLUGIN__"]["s2member"]["o"][(($_REQUEST["s2member_paypal_proxy"] && preg_match ("/pro-emails/", $_REQUEST["s2member_paypal_proxy_use"])) ? "pro_" : "") . "sp_email_subject"]);
77
- $sbj = preg_replace ("/%%sp_access_exp%%/i", c_ws_plugin__s2member_utils_strings::esc_refs (c_ws_plugin__s2member_utils_time::approx_time_difference (time (), strtotime ("+" . $paypal["hours"] . " hours"))), $sbj);
 
 
 
78
 
79
- $msg = preg_replace ("/%%sp_access_url%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($sp_access_url), $GLOBALS["WS_PLUGIN__"]["s2member"]["o"][(($_REQUEST["s2member_paypal_proxy"] && preg_match ("/pro-emails/", $_REQUEST["s2member_paypal_proxy_use"])) ? "pro_" : "") . "sp_email_message"]);
80
- $msg = preg_replace ("/%%sp_access_exp%%/i", c_ws_plugin__s2member_utils_strings::esc_refs (c_ws_plugin__s2member_utils_time::approx_time_difference (time (), strtotime ("+" . $paypal["hours"] . " hours"))), $msg);
 
 
81
 
82
- $rec = preg_replace ("/%%sp_access_url%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($sp_access_url), $GLOBALS["WS_PLUGIN__"]["s2member"]["o"][(($_REQUEST["s2member_paypal_proxy"] && preg_match ("/pro-emails/", $_REQUEST["s2member_paypal_proxy_use"])) ? "pro_" : "") . "sp_email_recipients"]);
83
- $rec = preg_replace ("/%%sp_access_exp%%/i", c_ws_plugin__s2member_utils_strings::esc_refs (c_ws_plugin__s2member_utils_time::approx_time_difference (time (), strtotime ("+" . $paypal["hours"] . " hours"))), $rec);
84
 
85
- if (($rec = preg_replace ("/%%cv([0-9]+)%%/ei", 'trim(@$cv[$1])', $rec)) && ($rec = preg_replace ("/%%txn_id%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($paypal["txn_id"]), $rec)))
86
- if (($rec = preg_replace ("/%%amount%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($paypal["mc_gross"]), $rec))) // Full amount of the payment, before fee is subtracted.
87
- if (($rec = preg_replace ("/%%txn_baid%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($paypal["txn_baid"]), $rec)) && ($rec = preg_replace ("/%%txn_cid%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($paypal["txn_cid"]), $rec)))
88
- if (($rec = preg_replace ("/%%item_number%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($paypal["item_number"]), $rec)) && ($rec = preg_replace ("/%%item_name%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($paypal["item_name"]), $rec)))
89
- if (($rec = preg_replace ("/%%first_name%%/i", c_ws_plugin__s2member_utils_strings::esc_dq (c_ws_plugin__s2member_utils_strings::esc_refs ($paypal["first_name"])), $rec)) && ($rec = preg_replace ("/%%last_name%%/i", c_ws_plugin__s2member_utils_strings::esc_dq (c_ws_plugin__s2member_utils_strings::esc_refs ($paypal["last_name"])), $rec)))
90
- if (($rec = preg_replace ("/%%full_name%%/i", c_ws_plugin__s2member_utils_strings::esc_dq (c_ws_plugin__s2member_utils_strings::esc_refs (trim ($paypal["first_name"] . " " . $paypal["last_name"]))), $rec))) // **NOTE** c_ws_plugin__s2member_utils_strings::esc_dq() is applied here. (ex. "N\"ame" <email>).
91
- if (($rec = preg_replace ("/%%payer_email%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($paypal["payer_email"]), $rec)))
92
- if (($rec = preg_replace ("/%%user_ip%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($paypal["ip"]), $rec)))
93
- if (($rec = preg_replace ("/%%full_coupon_code%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($coupon["full_coupon_code"]), $rec)) && ($rec = preg_replace ("/%%coupon_code%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($coupon["coupon_code"]), $rec)) && ($rec = preg_replace ("/%%coupon_affiliate_id%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($coupon["affiliate_id"]), $rec)))
94
 
95
- if (($sbj = preg_replace ("/%%cv([0-9]+)%%/ei", 'trim(@$cv[$1])', $sbj)) && ($sbj = preg_replace ("/%%txn_id%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($paypal["txn_id"]), $sbj)))
96
- if (($sbj = preg_replace ("/%%amount%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($paypal["mc_gross"]), $sbj))) // Full amount of the payment, before fee is subtracted.
97
- if (($sbj = preg_replace ("/%%txn_baid%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($paypal["txn_baid"]), $sbj)) && ($sbj = preg_replace ("/%%txn_cid%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($paypal["txn_cid"]), $sbj)))
98
- if (($sbj = preg_replace ("/%%item_number%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($paypal["item_number"]), $sbj)) && ($sbj = preg_replace ("/%%item_name%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($paypal["item_name"]), $sbj)))
99
- if (($sbj = preg_replace ("/%%first_name%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($paypal["first_name"]), $sbj)) && ($sbj = preg_replace ("/%%last_name%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($paypal["last_name"]), $sbj)))
100
- if (($sbj = preg_replace ("/%%full_name%%/i", c_ws_plugin__s2member_utils_strings::esc_refs (trim ($paypal["first_name"] . " " . $paypal["last_name"])), $sbj)))
101
- if (($sbj = preg_replace ("/%%payer_email%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($paypal["payer_email"]), $sbj)))
102
- if (($sbj = preg_replace ("/%%user_ip%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($paypal["ip"]), $sbj)))
103
- if (($sbj = preg_replace ("/%%full_coupon_code%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($coupon["full_coupon_code"]), $sbj)) && ($sbj = preg_replace ("/%%coupon_code%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($coupon["coupon_code"]), $sbj)) && ($sbj = preg_replace ("/%%coupon_affiliate_id%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($coupon["affiliate_id"]), $sbj)))
 
104
 
105
- if (($msg = preg_replace ("/%%cv([0-9]+)%%/ei", 'trim(@$cv[$1])', $msg)) && ($msg = preg_replace ("/%%txn_id%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($paypal["txn_id"]), $msg)))
106
- if (($msg = preg_replace ("/%%amount%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($paypal["mc_gross"]), $msg))) // Full amount of the payment, before fee is subtracted.
107
- if (($msg = preg_replace ("/%%txn_baid%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($paypal["txn_baid"]), $msg)) && ($msg = preg_replace ("/%%txn_cid%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($paypal["txn_cid"]), $msg)))
108
- if (($msg = preg_replace ("/%%item_number%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($paypal["item_number"]), $msg)) && ($msg = preg_replace ("/%%item_name%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($paypal["item_name"]), $msg)))
109
- if (($msg = preg_replace ("/%%first_name%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($paypal["first_name"]), $msg)) && ($msg = preg_replace ("/%%last_name%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($paypal["last_name"]), $msg)))
110
- if (($msg = preg_replace ("/%%full_name%%/i", c_ws_plugin__s2member_utils_strings::esc_refs (trim ($paypal["first_name"] . " " . $paypal["last_name"])), $msg)))
111
- if (($msg = preg_replace ("/%%payer_email%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($paypal["payer_email"]), $msg)))
112
- if (($msg = preg_replace ("/%%user_ip%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($paypal["ip"]), $msg)))
113
- if (($msg = preg_replace ("/%%full_coupon_code%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($coupon["full_coupon_code"]), $msg)) && ($msg = preg_replace ("/%%coupon_code%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($coupon["coupon_code"]), $msg)) && ($msg = preg_replace ("/%%coupon_affiliate_id%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($coupon["affiliate_id"]), $msg)))
 
114
 
115
- if (($rec = trim (preg_replace ("/%%(.+?)%%/i", "", $rec))) && ($sbj = trim (preg_replace ("/%%(.+?)%%/i", "", $sbj))) && ($msg = trim (preg_replace ("/%%(.+?)%%/i", "", $msg))))
116
- {
117
- if (!is_multisite () || !c_ws_plugin__s2member_utils_conds::is_multisite_farm () || is_main_site ())
118
- {
119
- $sbj = c_ws_plugin__s2member_utilities::evl($sbj, get_defined_vars());
120
- $msg = c_ws_plugin__s2member_utilities::evl($msg, get_defined_vars());
121
- }
122
- foreach (c_ws_plugin__s2member_utils_strings::parse_emails ($rec) as $recipient) // Go through a possible list of recipients.
123
- c_ws_plugin__s2member_email_configs::email_config () . wp_mail ($recipient, apply_filters("ws_plugin__s2member_sp_email_sbj", $sbj, get_defined_vars ()), apply_filters("ws_plugin__s2member_sp_email_msg", $msg, get_defined_vars ()), "From: \"" . preg_replace ('/"/', "'", $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["reg_email_from_name"]) . "\" <" . $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["reg_email_from_email"] . ">\r\nContent-Type: text/plain; charset=UTF-8") . c_ws_plugin__s2member_email_configs::email_config_release ();
 
124
 
125
- $paypal["s2member_log"][] = "Specific Post/Page Confirmation Email sent to: " . $rec . ".";
126
- }
127
- if ($processing && $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["sp_sale_notification_urls"] && is_array($cv = preg_split ("/\|/", $paypal["custom"])))
128
- {
129
- foreach (preg_split ("/[\r\n\t]+/", $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["sp_sale_notification_urls"]) as $url)
 
 
 
 
130
 
131
- if (($url = preg_replace ("/%%cv([0-9]+)%%/ei", 'urlencode(trim(@$cv[$1]))', $url)) && ($url = preg_replace ("/%%sp_access_url%%/i", c_ws_plugin__s2member_utils_strings::esc_refs (rawurlencode ($sp_access_url)), $url)))
132
- if (($url = preg_replace ("/%%sp_access_exp%%/i", c_ws_plugin__s2member_utils_strings::esc_refs (urlencode (c_ws_plugin__s2member_utils_time::approx_time_difference (time (), strtotime ("+" . $paypal["hours"] . " hours")))), $url)))
133
- if (($url = preg_replace ("/%%amount%%/i", c_ws_plugin__s2member_utils_strings::esc_refs (urlencode ($paypal["mc_gross"])), $url)) && ($url = preg_replace ("/%%txn_id%%/i", c_ws_plugin__s2member_utils_strings::esc_refs (urlencode ($paypal["txn_id"])), $url)))
134
- if (($url = preg_replace ("/%%txn_baid%%/i", c_ws_plugin__s2member_utils_strings::esc_refs (urlencode ($paypal["txn_baid"])), $url)) && ($url = preg_replace ("/%%txn_cid%%/i", c_ws_plugin__s2member_utils_strings::esc_refs (urlencode ($paypal["txn_cid"])), $url)))
135
- if (($url = preg_replace ("/%%item_number%%/i", c_ws_plugin__s2member_utils_strings::esc_refs (urlencode ($paypal["item_number"])), $url)) && ($url = preg_replace ("/%%item_name%%/i", c_ws_plugin__s2member_utils_strings::esc_refs (urlencode ($paypal["item_name"])), $url)))
136
- if (($url = preg_replace ("/%%first_name%%/i", c_ws_plugin__s2member_utils_strings::esc_refs (urlencode ($paypal["first_name"])), $url)) && ($url = preg_replace ("/%%last_name%%/i", c_ws_plugin__s2member_utils_strings::esc_refs (urlencode ($paypal["last_name"])), $url)))
137
- if (($url = preg_replace ("/%%full_name%%/i", c_ws_plugin__s2member_utils_strings::esc_refs (urlencode (trim ($paypal["first_name"] . " " . $paypal["last_name"]))), $url)))
138
- if (($url = preg_replace ("/%%payer_email%%/i", c_ws_plugin__s2member_utils_strings::esc_refs (urlencode ($paypal["payer_email"])), $url)))
139
- if (($url = preg_replace ("/%%user_ip%%/i", c_ws_plugin__s2member_utils_strings::esc_refs (urlencode ($paypal["ip"])), $url)))
140
- if (($url = preg_replace ("/%%full_coupon_code%%/i", c_ws_plugin__s2member_utils_strings::esc_refs (urlencode($coupon["full_coupon_code"])), $url)) && ($url = preg_replace ("/%%coupon_code%%/i", c_ws_plugin__s2member_utils_strings::esc_refs (urlencode($coupon["coupon_code"])), $url)) && ($url = preg_replace ("/%%coupon_affiliate_id%%/i", c_ws_plugin__s2member_utils_strings::esc_refs (urlencode($coupon["affiliate_id"])), $url)))
141
 
142
- if (($url = trim (preg_replace ("/%%(.+?)%%/i", "", $url))))
143
- c_ws_plugin__s2member_utils_urls::remote ($url);
 
 
 
 
 
 
 
 
 
144
 
145
- $paypal["s2member_log"][] = "Specific Post/Page ~ Sale Notification URLs have been processed.";
146
- }
147
- if ($processing && $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["sp_sale_notification_recipients"] && is_array($cv = preg_split ("/\|/", $paypal["custom"])))
148
- {
149
- $msg = $sbj = "(s2Member / API Notification Email) - Specific Post/Page ~ Sale";
150
- $msg .= "\n\n"; // Spacing in the message body.
151
 
152
- $msg .= "sp_access_url: %%sp_access_url%%\n";
153
- $msg .= "sp_access_exp: %%sp_access_exp%%\n";
 
 
 
 
154
 
155
- $msg .= "amount: %%amount%%\n";
156
- $msg .= "txn_id: %%txn_id%%\n";
157
- $msg .= "txn_baid: %%txn_baid%%\n";
158
- $msg .= "txn_cid: %%txn_cid%%\n";
159
- $msg .= "item_number: %%item_number%%\n";
160
- $msg .= "item_name: %%item_name%%\n";
161
- $msg .= "first_name: %%first_name%%\n";
162
- $msg .= "last_name: %%last_name%%\n";
163
- $msg .= "full_name: %%full_name%%\n";
164
- $msg .= "payer_email: %%payer_email%%\n";
165
- $msg .= "user_ip: %%user_ip%%\n";
166
 
167
- $msg .= "full_coupon_code: %%full_coupon_code%%\n";
168
- $msg .= "coupon_code: %%coupon_code%%\n";
169
- $msg .= "coupon_affiliate_id: %%coupon_affiliate_id%%\n";
 
 
 
 
 
 
 
 
 
 
170
 
171
- $msg .= "cv0: %%cv0%%\n";
172
- $msg .= "cv1: %%cv1%%\n";
173
- $msg .= "cv2: %%cv2%%\n";
174
- $msg .= "cv3: %%cv3%%\n";
175
- $msg .= "cv4: %%cv4%%\n";
176
- $msg .= "cv5: %%cv5%%\n";
177
- $msg .= "cv6: %%cv6%%\n";
178
- $msg .= "cv7: %%cv7%%\n";
179
- $msg .= "cv8: %%cv8%%\n";
180
- $msg .= "cv9: %%cv9%%";
181
 
182
- if (($msg = preg_replace ("/%%cv([0-9]+)%%/ei", 'trim(@$cv[$1])', $msg)) && ($msg = preg_replace ("/%%sp_access_url%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($sp_access_url), $msg)))
183
- if (($msg = preg_replace ("/%%sp_access_exp%%/i", c_ws_plugin__s2member_utils_strings::esc_refs (c_ws_plugin__s2member_utils_time::approx_time_difference (time (), strtotime ("+" . $paypal["hours"] . " hours"))), $msg)))
184
- if (($msg = preg_replace ("/%%amount%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($paypal["mc_gross"]), $msg)) && ($msg = preg_replace ("/%%txn_id%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($paypal["txn_id"]), $msg)))
185
- if (($msg = preg_replace ("/%%txn_baid%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($paypal["txn_baid"]), $msg)) && ($msg = preg_replace ("/%%txn_cid%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($paypal["txn_cid"]), $msg)))
186
- if (($msg = preg_replace ("/%%item_number%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($paypal["item_number"]), $msg)) && ($msg = preg_replace ("/%%item_name%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($paypal["item_name"]), $msg)))
187
- if (($msg = preg_replace ("/%%first_name%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($paypal["first_name"]), $msg)) && ($msg = preg_replace ("/%%last_name%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($paypal["last_name"]), $msg)))
188
- if (($msg = preg_replace ("/%%full_name%%/i", c_ws_plugin__s2member_utils_strings::esc_refs (trim ($paypal["first_name"] . " " . $paypal["last_name"])), $msg)))
189
- if (($msg = preg_replace ("/%%payer_email%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($paypal["payer_email"]), $msg)))
190
- if (($msg = preg_replace ("/%%user_ip%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($paypal["ip"]), $msg)))
191
- if (($msg = preg_replace ("/%%full_coupon_code%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($coupon["full_coupon_code"]), $msg)) && ($msg = preg_replace ("/%%coupon_code%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($coupon["coupon_code"]), $msg)) && ($msg = preg_replace ("/%%coupon_affiliate_id%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($coupon["affiliate_id"]), $msg)))
192
 
193
- if ($sbj && ($msg = trim (preg_replace ("/%%(.+?)%%/i", "", $msg)))) // Still have a ``$sbj`` and a ``$msg``?
 
 
 
 
 
 
 
 
 
 
194
 
195
- foreach (c_ws_plugin__s2member_utils_strings::parse_emails ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["sp_sale_notification_recipients"]) as $recipient)
196
- wp_mail ($recipient, apply_filters("ws_plugin__s2member_sp_sale_notification_email_sbj", $sbj, get_defined_vars ()), apply_filters("ws_plugin__s2member_sp_sale_notification_email_msg", $msg, get_defined_vars ()), "Content-Type: text/plain; charset=UTF-8");
197
 
198
- $paypal["s2member_log"][] = "Specific Post/Page ~ Sale Notification Emails have been processed.";
199
- }
200
- if ($processing && $_REQUEST["s2member_paypal_proxy"] && ($url = $_REQUEST["s2member_paypal_proxy_return_url"]) && is_array($cv = preg_split ("/\|/", $paypal["custom"]))) // A Proxy is requesting a Return URL?
201
- {
202
- if (($url = preg_replace ("/%%cv([0-9]+)%%/ei", 'urlencode(trim(@$cv[$1]))', $url)) && ($url = preg_replace ("/%%sp_access_url%%/i", c_ws_plugin__s2member_utils_strings::esc_refs (rawurlencode ($sp_access_url)), $url)))
203
- if (($url = preg_replace ("/%%sp_access_exp%%/i", c_ws_plugin__s2member_utils_strings::esc_refs (urlencode (c_ws_plugin__s2member_utils_time::approx_time_difference (time (), strtotime ("+" . $paypal["hours"] . " hours")))), $url)))
204
- if (($url = preg_replace ("/%%amount%%/i", c_ws_plugin__s2member_utils_strings::esc_refs (urlencode ($paypal["mc_gross"])), $url)) && ($url = preg_replace ("/%%txn_id%%/i", c_ws_plugin__s2member_utils_strings::esc_refs (urlencode ($paypal["txn_id"])), $url)))
205
- if (($url = preg_replace ("/%%txn_baid%%/i", c_ws_plugin__s2member_utils_strings::esc_refs (urlencode ($paypal["txn_baid"])), $url)) && ($url = preg_replace ("/%%txn_cid%%/i", c_ws_plugin__s2member_utils_strings::esc_refs (urlencode ($paypal["txn_cid"])), $url)))
206
- if (($url = preg_replace ("/%%item_number%%/i", c_ws_plugin__s2member_utils_strings::esc_refs (urlencode ($paypal["item_number"])), $url)) && ($url = preg_replace ("/%%item_name%%/i", c_ws_plugin__s2member_utils_strings::esc_refs (urlencode ($paypal["item_name"])), $url)))
207
- if (($url = preg_replace ("/%%first_name%%/i", c_ws_plugin__s2member_utils_strings::esc_refs (urlencode ($paypal["first_name"])), $url)) && ($url = preg_replace ("/%%last_name%%/i", c_ws_plugin__s2member_utils_strings::esc_refs (urlencode ($paypal["last_name"])), $url)))
208
- if (($url = preg_replace ("/%%full_name%%/i", c_ws_plugin__s2member_utils_strings::esc_refs (urlencode (trim ($paypal["first_name"] . " " . $paypal["last_name"]))), $url)))
209
- if (($url = preg_replace ("/%%payer_email%%/i", c_ws_plugin__s2member_utils_strings::esc_refs (urlencode ($paypal["payer_email"])), $url)))
210
- if (($url = preg_replace ("/%%user_ip%%/i", c_ws_plugin__s2member_utils_strings::esc_refs (urlencode ($paypal["ip"])), $url)))
211
- if (($url = preg_replace ("/%%full_coupon_code%%/i", c_ws_plugin__s2member_utils_strings::esc_refs (urlencode($coupon["full_coupon_code"])), $url)) && ($url = preg_replace ("/%%coupon_code%%/i", c_ws_plugin__s2member_utils_strings::esc_refs (urlencode($coupon["coupon_code"])), $url)) && ($url = preg_replace ("/%%coupon_affiliate_id%%/i", c_ws_plugin__s2member_utils_strings::esc_refs (urlencode($coupon["affiliate_id"])), $url)))
212
 
213
- if (($url = trim ($url))) // Preserve Remaining replacements.
214
- // Because the parent routine may perform replacements too.
215
- $paypal["s2member_paypal_proxy_return_url"] = $url;
 
 
 
 
 
 
 
 
 
 
 
 
216
 
217
- $paypal["s2member_log"][] = "Specific Post/Page Return, a Proxy Return URL is ready.";
218
- }
219
- if ($processing && ($code = $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["sp_tracking_codes"]) && is_array($cv = preg_split ("/\|/", $paypal["custom"])))
220
- {
221
- if (($code = preg_replace ("/%%cv([0-9]+)%%/ei", 'trim(@$cv[$1])', $code)) && ($code = preg_replace ("/%%amount%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($paypal["mc_gross"]), $code)) && ($code = preg_replace ("/%%txn_id%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($paypal["txn_id"]), $code)))
222
- if (($code = preg_replace ("/%%txn_baid%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($paypal["txn_baid"]), $code)) && ($code = preg_replace ("/%%txn_cid%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($paypal["txn_cid"]), $code)))
223
- if (($code = preg_replace ("/%%item_number%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($paypal["item_number"]), $code)) && ($code = preg_replace ("/%%item_name%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($paypal["item_name"]), $code)))
224
- if (($code = preg_replace ("/%%first_name%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($paypal["first_name"]), $code)) && ($code = preg_replace ("/%%last_name%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($paypal["last_name"]), $code)))
225
- if (($code = preg_replace ("/%%full_name%%/i", c_ws_plugin__s2member_utils_strings::esc_refs (trim ($paypal["first_name"] . " " . $paypal["last_name"])), $code)))
226
- if (($code = preg_replace ("/%%payer_email%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($paypal["payer_email"]), $code)))
227
- if (($code = preg_replace ("/%%user_ip%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($paypal["ip"]), $code)))
228
- if (($code = preg_replace ("/%%full_coupon_code%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($coupon["full_coupon_code"]), $code)) && ($code = preg_replace ("/%%coupon_code%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($coupon["coupon_code"]), $code)) && ($code = preg_replace ("/%%coupon_affiliate_id%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($coupon["affiliate_id"]), $code)))
229
 
230
- if (($code = trim (preg_replace ("/%%(.+?)%%/i", "", $code)))) // This gets stored into a Transient Queue.
231
- {
232
- $paypal["s2member_log"][] = "Storing Specific Post/Page Tracking Codes into a Transient Queue. These will be processed on-site.";
233
- set_transient ("s2m_" . md5 ("s2member_transient_sp_tracking_codes_" . $paypal["txn_id"]), $code, 43200);
234
- }
235
- }
236
- foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;
237
- do_action("ws_plugin__s2member_during_paypal_notify_during_sp_access", get_defined_vars ());
238
- unset($__refs, $__v);
239
- }
240
- else $paypal["s2member_log"][] = "Unable to generate Access Link for Specific Post/Page Access. Does your Leading Post/Page still exist?";
241
- }
242
- else // Else, this is a duplicate IPN. Must stop here.
243
- {
244
- $paypal["s2member_log"][] = "Not processing. Duplicate IPN.";
245
- $paypal["s2member_log"][] = "s2Member `txn_type` identified as ( `web_accept` ) for Specific Post/Page Access.";
246
- $paypal["s2member_log"][] = "Duplicate IPN. Already processed. This IPN will be ignored.";
247
- }
248
- foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;
249
- do_action("ws_plugin__s2member_during_paypal_notify_after_sp_access", get_defined_vars ());
250
- unset($__refs, $__v);
251
 
252
- return apply_filters("c_ws_plugin__s2member_paypal_notify_in_web_accept_sp", $paypal, get_defined_vars ());
253
- }
254
- else return apply_filters("c_ws_plugin__s2member_paypal_notify_in_web_accept_sp", false, get_defined_vars ());
 
 
 
 
 
 
255
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
256
  }
257
- }
 
 
 
1
  <?php
2
  /**
3
+ * s2Member's PayPal IPN handler (inner processing routine).
4
+ *
5
+ * Copyright: © 2009-2011
6
+ * {@link http://www.websharks-inc.com/ WebSharks, Inc.}
7
+ * (coded in the USA)
8
+ *
9
+ * Released under the terms of the GNU General Public License.
10
+ * You should have received a copy of the GNU General Public License,
11
+ * along with this software. In the main directory, see: /licensing/
12
+ * If not, see: {@link http://www.gnu.org/licenses/}.
13
+ *
14
+ * @package s2Member\PayPal
15
+ * @since 110720
16
+ */
17
+ if(realpath(__FILE__) === realpath($_SERVER['SCRIPT_FILENAME']))
18
+ exit ('Do not access this file directly.');
19
 
20
+ if(!class_exists('c_ws_plugin__s2member_paypal_notify_in_web_accept_sp'))
21
+ {
22
+ /**
23
+ * s2Member's PayPal IPN handler (inner processing routine).
24
+ *
25
+ * @package s2Member\PayPal
26
+ * @since 110720
27
+ */
28
+ class c_ws_plugin__s2member_paypal_notify_in_web_accept_sp
29
  {
30
  /**
31
+ * s2Member's PayPal IPN handler (inner processing routine).
32
+ *
33
+ * @package s2Member\PayPal
34
+ * @since 110720
35
+ *
36
+ * @param array $vars Required. An array of defined variables passed by {@link s2Member\PayPal\c_ws_plugin__s2member_paypal_notify_in::paypal_notify()}.
37
+ *
38
+ * @return array|bool The original ``$paypal`` array passed in (extracted) from ``$vars``, or false when conditions do NOT apply.
39
+ */
40
+ public static function cp($vars = array()) // Conditional phase for ``c_ws_plugin__s2member_paypal_notify_in::paypal_notify()``.
41
+ {
42
+ extract($vars, EXTR_OVERWRITE | EXTR_REFS); // Extract all vars passed in from: ``c_ws_plugin__s2member_paypal_notify_in::paypal_notify()``.
 
 
 
 
 
 
 
43
 
44
+ if((!empty($paypal['txn_type']) && preg_match('/^web_accept$/i', $paypal['txn_type']))
45
+ && (!empty($paypal['item_number']) && preg_match($GLOBALS['WS_PLUGIN__']['s2member']['c']['sp_access_item_number_regex'], $paypal['item_number']))
46
+ && (empty($paypal['payment_status']) || empty($payment_status_issues) || !preg_match($payment_status_issues, $paypal['payment_status']))
47
+ && (!empty($paypal['payer_email'])) && (!empty($paypal['txn_id'])) && (!empty($paypal['txn_baid']) || ($paypal['txn_baid'] = $paypal['txn_id']))
48
+ && (!empty($paypal['txn_cid']) || ($paypal['txn_cid'] = $paypal['txn_id']))
49
+ )
50
+ {
51
+ foreach(array_keys(get_defined_vars()) as $__v) $__refs[$__v] =& $$__v;
52
+ do_action('ws_plugin__s2member_during_paypal_notify_before_sp_access', get_defined_vars());
53
+ unset($__refs, $__v);
54
 
55
+ if(!get_transient($transient_ipn = 's2m_ipn_'.md5('s2member_transient_'.$_paypal_s)) && set_transient($transient_ipn, time(), 31556926 * 10))
56
+ {
57
+ $paypal['s2member_log'][] = 's2Member `txn_type` identified as ( `web_accept` ) for Specific Post/Page Access.';
58
 
59
+ list (, $paypal['sp_ids'], $paypal['hours']) = preg_split('/\:/', $paypal['item_number'], 3);
60
 
61
+ $paypal['ip'] = (preg_match('/ip address/i', $paypal['option_name2']) && $paypal['option_selection2']) ? $paypal['option_selection2'] : '';
62
+ $paypal['ip'] = (!$paypal['ip'] && preg_match('/^[a-z0-9]+~[0-9\.]+$/i', $paypal['invoice'])) ? preg_replace('/^[a-z0-9]+~/i', '', $paypal['invoice']) : $paypal['ip'];
63
 
64
+ $paypal['currency'] = strtoupper($paypal['mc_currency']); // Normalize input currency.
65
+ $paypal['currency_symbol'] = c_ws_plugin__s2member_utils_cur::symbol($paypal['currency']);
 
66
 
67
+ if(($sp_access_url = c_ws_plugin__s2member_sp_access::sp_access_link_gen($paypal['sp_ids'], $paypal['hours'])) && is_array($cv = preg_split('/\|/', $paypal['custom'])))
68
+ {
69
+ $processing = $during = TRUE; // Yes, we ARE processing this.
 
 
 
 
70
 
71
+ if(preg_match('/(referenc|associat)/i', $paypal['option_name1']) && $paypal['option_selection1']) // Associating this purchase with a Member?
72
+ if(($user_id = c_ws_plugin__s2member_utils_users::get_user_id_with($paypal['option_selection1'], $paypal['option_selection1'])) && is_object($user = new WP_User ($user_id)) && $user->ID)
73
+ {
74
+ $sp_references = (array)get_user_option('s2member_sp_references', $user_id);
75
+ $_sp_reference = array('time' => time(), 'ids' => $paypal['sp_ids'], 'hours' => $paypal['hours'], 'url' => $sp_access_url);
76
+ $sp_references = c_ws_plugin__s2member_utils_arrays::array_unique(array_merge($sp_references, $_sp_reference));
77
+ update_user_option($user_id, 's2member_sp_references', $sp_references);
78
 
79
+ $paypal['s2member_log'][] = 'Specific Post/Page ~ Sale associated with User ID: '.$user_id.'.';
80
+ }
81
+ $sbj = preg_replace('/%%sp_access_url%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($sp_access_url), $GLOBALS['WS_PLUGIN__']['s2member']['o'][(($_REQUEST['s2member_paypal_proxy'] && preg_match('/pro-emails/', $_REQUEST['s2member_paypal_proxy_use'])) ? 'pro_' : '').'sp_email_subject']);
82
+ $sbj = preg_replace('/%%sp_access_exp%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(c_ws_plugin__s2member_utils_time::approx_time_difference(time(), strtotime('+'.$paypal['hours'].' hours'))), $sbj);
83
 
84
+ $msg = preg_replace('/%%sp_access_url%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($sp_access_url), $GLOBALS['WS_PLUGIN__']['s2member']['o'][(($_REQUEST['s2member_paypal_proxy'] && preg_match('/pro-emails/', $_REQUEST['s2member_paypal_proxy_use'])) ? 'pro_' : '').'sp_email_message']);
85
+ $msg = preg_replace('/%%sp_access_exp%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(c_ws_plugin__s2member_utils_time::approx_time_difference(time(), strtotime('+'.$paypal['hours'].' hours'))), $msg);
86
 
87
+ $rec = preg_replace('/%%sp_access_url%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($sp_access_url), $GLOBALS['WS_PLUGIN__']['s2member']['o'][(($_REQUEST['s2member_paypal_proxy'] && preg_match('/pro-emails/', $_REQUEST['s2member_paypal_proxy_use'])) ? 'pro_' : '').'sp_email_recipients']);
88
+ $rec = preg_replace('/%%sp_access_exp%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(c_ws_plugin__s2member_utils_time::approx_time_difference(time(), strtotime('+'.$paypal['hours'].' hours'))), $rec);
 
 
 
 
 
 
 
89
 
90
+ if(($rec = preg_replace('/%%cv([0-9]+)%%/ei', 'trim(@$cv[$1])', $rec)) && ($rec = preg_replace('/%%txn_id%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['txn_id']), $rec)))
91
+ if(($rec = preg_replace('/%%amount%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['mc_gross']), $rec))) // Full amount of the payment, before fee is subtracted.
92
+ if(($rec = preg_replace('/%%currency%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['currency']), $rec)) && ($rec = preg_replace('/%%currency_symbol%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['currency_symbol']), $rec)))
93
+ if(($rec = preg_replace('/%%txn_baid%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['txn_baid']), $rec)) && ($rec = preg_replace('/%%txn_cid%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['txn_cid']), $rec)))
94
+ if(($rec = preg_replace('/%%item_number%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['item_number']), $rec)) && ($rec = preg_replace('/%%item_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['item_name']), $rec)))
95
+ if(($rec = preg_replace('/%%first_name%%/i', c_ws_plugin__s2member_utils_strings::esc_dq(c_ws_plugin__s2member_utils_strings::esc_refs($paypal['first_name'])), $rec)) && ($rec = preg_replace('/%%last_name%%/i', c_ws_plugin__s2member_utils_strings::esc_dq(c_ws_plugin__s2member_utils_strings::esc_refs($paypal['last_name'])), $rec)))
96
+ if(($rec = preg_replace('/%%full_name%%/i', c_ws_plugin__s2member_utils_strings::esc_dq(c_ws_plugin__s2member_utils_strings::esc_refs(trim($paypal['first_name'].' '.$paypal['last_name']))), $rec))) // **NOTE** c_ws_plugin__s2member_utils_strings::esc_dq() is applied here. (ex. 'N\'ame' <email>).
97
+ if(($rec = preg_replace('/%%payer_email%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['payer_email']), $rec)))
98
+ if(($rec = preg_replace('/%%user_ip%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['ip']), $rec)))
99
+ if(($rec = preg_replace('/%%full_coupon_code%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($coupon['full_coupon_code']), $rec)) && ($rec = preg_replace('/%%coupon_code%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($coupon['coupon_code']), $rec)) && ($rec = preg_replace('/%%coupon_affiliate_id%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($coupon['affiliate_id']), $rec)))
100
 
101
+ if(($sbj = preg_replace('/%%cv([0-9]+)%%/ei', 'trim(@$cv[$1])', $sbj)) && ($sbj = preg_replace('/%%txn_id%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['txn_id']), $sbj)))
102
+ if(($sbj = preg_replace('/%%amount%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['mc_gross']), $sbj))) // Full amount of the payment, before fee is subtracted.
103
+ if(($sbj = preg_replace('/%%currency%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['currency']), $sbj)) && ($sbj = preg_replace('/%%currency_symbol%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['currency_symbol']), $sbj)))
104
+ if(($sbj = preg_replace('/%%txn_baid%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['txn_baid']), $sbj)) && ($sbj = preg_replace('/%%txn_cid%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['txn_cid']), $sbj)))
105
+ if(($sbj = preg_replace('/%%item_number%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['item_number']), $sbj)) && ($sbj = preg_replace('/%%item_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['item_name']), $sbj)))
106
+ if(($sbj = preg_replace('/%%first_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['first_name']), $sbj)) && ($sbj = preg_replace('/%%last_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['last_name']), $sbj)))
107
+ if(($sbj = preg_replace('/%%full_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(trim($paypal['first_name'].' '.$paypal['last_name'])), $sbj)))
108
+ if(($sbj = preg_replace('/%%payer_email%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['payer_email']), $sbj)))
109
+ if(($sbj = preg_replace('/%%user_ip%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['ip']), $sbj)))
110
+ if(($sbj = preg_replace('/%%full_coupon_code%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($coupon['full_coupon_code']), $sbj)) && ($sbj = preg_replace('/%%coupon_code%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($coupon['coupon_code']), $sbj)) && ($sbj = preg_replace('/%%coupon_affiliate_id%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($coupon['affiliate_id']), $sbj)))
111
 
112
+ if(($msg = preg_replace('/%%cv([0-9]+)%%/ei', 'trim(@$cv[$1])', $msg)) && ($msg = preg_replace('/%%txn_id%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['txn_id']), $msg)))
113
+ if(($msg = preg_replace('/%%amount%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['mc_gross']), $msg))) // Full amount of the payment, before fee is subtracted.
114
+ if(($msg = preg_replace('/%%currency%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['currency']), $msg)) && ($msg = preg_replace('/%%currency_symbol%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['currency_symbol']), $msg)))
115
+ if(($msg = preg_replace('/%%txn_baid%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['txn_baid']), $msg)) && ($msg = preg_replace('/%%txn_cid%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['txn_cid']), $msg)))
116
+ if(($msg = preg_replace('/%%item_number%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['item_number']), $msg)) && ($msg = preg_replace('/%%item_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['item_name']), $msg)))
117
+ if(($msg = preg_replace('/%%first_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['first_name']), $msg)) && ($msg = preg_replace('/%%last_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['last_name']), $msg)))
118
+ if(($msg = preg_replace('/%%full_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(trim($paypal['first_name'].' '.$paypal['last_name'])), $msg)))
119
+ if(($msg = preg_replace('/%%payer_email%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['payer_email']), $msg)))
120
+ if(($msg = preg_replace('/%%user_ip%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['ip']), $msg)))
121
+ if(($msg = preg_replace('/%%full_coupon_code%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($coupon['full_coupon_code']), $msg)) && ($msg = preg_replace('/%%coupon_code%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($coupon['coupon_code']), $msg)) && ($msg = preg_replace('/%%coupon_affiliate_id%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($coupon['affiliate_id']), $msg)))
122
 
123
+ if(($rec = trim(preg_replace('/%%(.+?)%%/i', '', $rec))) && ($sbj = trim(preg_replace('/%%(.+?)%%/i', '', $sbj))) && ($msg = trim(preg_replace('/%%(.+?)%%/i', '', $msg))))
124
+ {
125
+ if(!is_multisite() || !c_ws_plugin__s2member_utils_conds::is_multisite_farm() || is_main_site())
126
+ {
127
+ $sbj = c_ws_plugin__s2member_utilities::evl($sbj, get_defined_vars());
128
+ $msg = c_ws_plugin__s2member_utilities::evl($msg, get_defined_vars());
129
+ }
130
+ foreach(c_ws_plugin__s2member_utils_strings::parse_emails($rec) as $recipient) // Go through a possible list of recipients.
131
+ c_ws_plugin__s2member_email_configs::email_config().wp_mail($recipient, apply_filters('ws_plugin__s2member_sp_email_sbj', $sbj, get_defined_vars()), apply_filters('ws_plugin__s2member_sp_email_msg', $msg, get_defined_vars()), 'From: "'.preg_replace('/"/', '"', $GLOBALS['WS_PLUGIN__']['s2member']['o']['reg_email_from_name']).'" <'.$GLOBALS['WS_PLUGIN__']['s2member']['o']['reg_email_from_email'].'>'."\r\n".'Content-Type: text/plain; charset=UTF-8').c_ws_plugin__s2member_email_configs::email_config_release();
132
 
133
+ $paypal['s2member_log'][] = 'Specific Post/Page Confirmation Email sent to: '.$rec.'.';
134
+ }
135
+ if($processing && $GLOBALS['WS_PLUGIN__']['s2member']['o']['sp_sale_notification_urls'] && is_array($cv = preg_split('/\|/', $paypal['custom'])))
136
+ {
137
+ foreach(preg_split('/['."\r\n\t".']+/', $GLOBALS['WS_PLUGIN__']['s2member']['o']['sp_sale_notification_urls']) as $url)
 
 
 
 
 
138
 
139
+ if(($url = preg_replace('/%%cv([0-9]+)%%/ei', 'urlencode(trim(@$cv[$1]))', $url)) && ($url = preg_replace('/%%sp_access_url%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(rawurlencode($sp_access_url)), $url)))
140
+ if(($url = preg_replace('/%%sp_access_exp%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode(c_ws_plugin__s2member_utils_time::approx_time_difference(time(), strtotime('+'.$paypal['hours'].' hours')))), $url)))
141
+ if(($url = preg_replace('/%%currency%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($paypal['currency'])), $url)) && ($url = preg_replace('/%%currency_symbol%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($paypal['currency_symbol'])), $url)))
142
+ if(($url = preg_replace('/%%amount%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($paypal['mc_gross'])), $url)) && ($url = preg_replace('/%%txn_id%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($paypal['txn_id'])), $url)))
143
+ if(($url = preg_replace('/%%txn_baid%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($paypal['txn_baid'])), $url)) && ($url = preg_replace('/%%txn_cid%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($paypal['txn_cid'])), $url)))
144
+ if(($url = preg_replace('/%%item_number%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($paypal['item_number'])), $url)) && ($url = preg_replace('/%%item_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($paypal['item_name'])), $url)))
145
+ if(($url = preg_replace('/%%first_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($paypal['first_name'])), $url)) && ($url = preg_replace('/%%last_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($paypal['last_name'])), $url)))
146
+ if(($url = preg_replace('/%%full_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode(trim($paypal['first_name'].' '.$paypal['last_name']))), $url)))
147
+ if(($url = preg_replace('/%%payer_email%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($paypal['payer_email'])), $url)))
148
+ if(($url = preg_replace('/%%user_ip%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($paypal['ip'])), $url)))
149
+ if(($url = preg_replace('/%%full_coupon_code%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($coupon['full_coupon_code'])), $url)) && ($url = preg_replace('/%%coupon_code%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($coupon['coupon_code'])), $url)) && ($url = preg_replace('/%%coupon_affiliate_id%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($coupon['affiliate_id'])), $url)))
150
 
151
+ if(($url = trim(preg_replace('/%%(.+?)%%/i', '', $url))))
152
+ c_ws_plugin__s2member_utils_urls::remote($url);
 
 
 
 
153
 
154
+ $paypal['s2member_log'][] = 'Specific Post/Page ~ Sale Notification URLs have been processed.';
155
+ }
156
+ if($processing && $GLOBALS['WS_PLUGIN__']['s2member']['o']['sp_sale_notification_recipients'] && is_array($cv = preg_split('/\|/', $paypal['custom'])))
157
+ {
158
+ $msg = $sbj = '(s2Member / API Notification Email) - Specific Post/Page ~ Sale';
159
+ $msg .= "\n\n"; // Spacing in the message body.
160
 
161
+ $msg .= 'sp_access_url: %%sp_access_url%%'."\n";
162
+ $msg .= 'sp_access_exp: %%sp_access_exp%%'."\n";
 
 
 
 
 
 
 
 
 
163
 
164
+ $msg .= 'currency: %%currency%%'."\n";
165
+ $msg .= 'currency_symbol: %%currency_symbol%%'."\n";
166
+ $msg .= 'amount: %%amount%%'."\n";
167
+ $msg .= 'txn_id: %%txn_id%%'."\n";
168
+ $msg .= 'txn_baid: %%txn_baid%%'."\n";
169
+ $msg .= 'txn_cid: %%txn_cid%%'."\n";
170
+ $msg .= 'item_number: %%item_number%%'."\n";
171
+ $msg .= 'item_name: %%item_name%%'."\n";
172
+ $msg .= 'first_name: %%first_name%%'."\n";
173
+ $msg .= 'last_name: %%last_name%%'."\n";
174
+ $msg .= 'full_name: %%full_name%%'."\n";
175
+ $msg .= 'payer_email: %%payer_email%%'."\n";
176
+ $msg .= 'user_ip: %%user_ip%%'."\n";
177
 
178
+ $msg .= 'full_coupon_code: %%full_coupon_code%%'."\n";
179
+ $msg .= 'coupon_code: %%coupon_code%%'."\n";
180
+ $msg .= 'coupon_affiliate_id: %%coupon_affiliate_id%%'."\n";
 
 
 
 
 
 
 
181
 
182
+ $msg .= 'cv0: %%cv0%%'."\n";
183
+ $msg .= 'cv1: %%cv1%%'."\n";
184
+ $msg .= 'cv2: %%cv2%%'."\n";
185
+ $msg .= 'cv3: %%cv3%%'."\n";
186
+ $msg .= 'cv4: %%cv4%%'."\n";
187
+ $msg .= 'cv5: %%cv5%%'."\n";
188
+ $msg .= 'cv6: %%cv6%%'."\n";
189
+ $msg .= 'cv7: %%cv7%%'."\n";
190
+ $msg .= 'cv8: %%cv8%%'."\n";
191
+ $msg .= 'cv9: %%cv9%%';
192
 
193
+ if(($msg = preg_replace('/%%cv([0-9]+)%%/ei', 'trim(@$cv[$1])', $msg)) && ($msg = preg_replace('/%%sp_access_url%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($sp_access_url), $msg)))
194
+ if(($msg = preg_replace('/%%sp_access_exp%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(c_ws_plugin__s2member_utils_time::approx_time_difference(time(), strtotime('+'.$paypal['hours'].' hours'))), $msg)))
195
+ if(($msg = preg_replace('/%%currency%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['currency']), $msg)) && ($msg = preg_replace('/%%currency_symbol%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['currency_symbol']), $msg)))
196
+ if(($msg = preg_replace('/%%amount%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['mc_gross']), $msg)) && ($msg = preg_replace('/%%txn_id%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['txn_id']), $msg)))
197
+ if(($msg = preg_replace('/%%txn_baid%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['txn_baid']), $msg)) && ($msg = preg_replace('/%%txn_cid%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['txn_cid']), $msg)))
198
+ if(($msg = preg_replace('/%%item_number%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['item_number']), $msg)) && ($msg = preg_replace('/%%item_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['item_name']), $msg)))
199
+ if(($msg = preg_replace('/%%first_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['first_name']), $msg)) && ($msg = preg_replace('/%%last_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['last_name']), $msg)))
200
+ if(($msg = preg_replace('/%%full_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(trim($paypal['first_name'].' '.$paypal['last_name'])), $msg)))
201
+ if(($msg = preg_replace('/%%payer_email%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['payer_email']), $msg)))
202
+ if(($msg = preg_replace('/%%user_ip%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['ip']), $msg)))
203
+ if(($msg = preg_replace('/%%full_coupon_code%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($coupon['full_coupon_code']), $msg)) && ($msg = preg_replace('/%%coupon_code%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($coupon['coupon_code']), $msg)) && ($msg = preg_replace('/%%coupon_affiliate_id%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($coupon['affiliate_id']), $msg)))
204
 
205
+ if($sbj && ($msg = trim(preg_replace('/%%(.+?)%%/i', '', $msg)))) // Still have a ``$sbj`` and a ``$msg``?
 
206
 
207
+ foreach(c_ws_plugin__s2member_utils_strings::parse_emails($GLOBALS['WS_PLUGIN__']['s2member']['o']['sp_sale_notification_recipients']) as $recipient)
208
+ wp_mail($recipient, apply_filters('ws_plugin__s2member_sp_sale_notification_email_sbj', $sbj, get_defined_vars()), apply_filters('ws_plugin__s2member_sp_sale_notification_email_msg', $msg, get_defined_vars()), 'Content-Type: text/plain; charset=UTF-8');
 
 
 
 
 
 
 
 
 
 
 
 
209
 
210
+ $paypal['s2member_log'][] = 'Specific Post/Page ~ Sale Notification Emails have been processed.';
211
+ }
212
+ if($processing && $_REQUEST['s2member_paypal_proxy'] && ($url = $_REQUEST['s2member_paypal_proxy_return_url']) && is_array($cv = preg_split('/\|/', $paypal['custom']))) // A Proxy is requesting a Return URL?
213
+ {
214
+ if(($url = preg_replace('/%%cv([0-9]+)%%/ei', 'urlencode(trim(@$cv[$1]))', $url)) && ($url = preg_replace('/%%sp_access_url%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(rawurlencode($sp_access_url)), $url)))
215
+ if(($url = preg_replace('/%%sp_access_exp%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode(c_ws_plugin__s2member_utils_time::approx_time_difference(time(), strtotime('+'.$paypal['hours'].' hours')))), $url)))
216
+ if(($url = preg_replace('/%%currency%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($paypal['currency'])), $url)) && ($url = preg_replace('/%%currency_symbol%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($paypal['currency_symbol'])), $url)))
217
+ if(($url = preg_replace('/%%amount%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($paypal['mc_gross'])), $url)) && ($url = preg_replace('/%%txn_id%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($paypal['txn_id'])), $url)))
218
+ if(($url = preg_replace('/%%txn_baid%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($paypal['txn_baid'])), $url)) && ($url = preg_replace('/%%txn_cid%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($paypal['txn_cid'])), $url)))
219
+ if(($url = preg_replace('/%%item_number%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($paypal['item_number'])), $url)) && ($url = preg_replace('/%%item_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($paypal['item_name'])), $url)))
220
+ if(($url = preg_replace('/%%first_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($paypal['first_name'])), $url)) && ($url = preg_replace('/%%last_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($paypal['last_name'])), $url)))
221
+ if(($url = preg_replace('/%%full_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode(trim($paypal['first_name'].' '.$paypal['last_name']))), $url)))
222
+ if(($url = preg_replace('/%%payer_email%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($paypal['payer_email'])), $url)))
223
+ if(($url = preg_replace('/%%user_ip%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($paypal['ip'])), $url)))
224
+ if(($url = preg_replace('/%%full_coupon_code%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($coupon['full_coupon_code'])), $url)) && ($url = preg_replace('/%%coupon_code%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($coupon['coupon_code'])), $url)) && ($url = preg_replace('/%%coupon_affiliate_id%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($coupon['affiliate_id'])), $url)))
225
 
226
+ if(($url = trim($url))) // Preserve Remaining replacements.
227
+ // Because the parent routine may perform replacements too.
228
+ $paypal['s2member_paypal_proxy_return_url'] = $url;
 
 
 
 
 
 
 
 
 
229
 
230
+ $paypal['s2member_log'][] = 'Specific Post/Page Return, a Proxy Return URL is ready.';
231
+ }
232
+ if($processing && ($code = $GLOBALS['WS_PLUGIN__']['s2member']['o']['sp_tracking_codes']) && is_array($cv = preg_split('/\|/', $paypal['custom'])))
233
+ {
234
+ if(($code = preg_replace('/%%cv([0-9]+)%%/ei', 'trim(@$cv[$1])', $code)) && ($code = preg_replace('/%%amount%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['mc_gross']), $code)) && ($code = preg_replace('/%%txn_id%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['txn_id']), $code)))
235
+ if(($code = preg_replace('/%%currency%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['currency']), $code)) && ($code = preg_replace('/%%currency_symbol%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['currency_symbol']), $code)))
236
+ if(($code = preg_replace('/%%txn_baid%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['txn_baid']), $code)) && ($code = preg_replace('/%%txn_cid%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['txn_cid']), $code)))
237
+ if(($code = preg_replace('/%%item_number%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['item_number']), $code)) && ($code = preg_replace('/%%item_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['item_name']), $code)))
238
+ if(($code = preg_replace('/%%first_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['first_name']), $code)) && ($code = preg_replace('/%%last_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['last_name']), $code)))
239
+ if(($code = preg_replace('/%%full_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(trim($paypal['first_name'].' '.$paypal['last_name'])), $code)))
240
+ if(($code = preg_replace('/%%payer_email%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['payer_email']), $code)))
241
+ if(($code = preg_replace('/%%user_ip%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['ip']), $code)))
242
+ if(($code = preg_replace('/%%full_coupon_code%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($coupon['full_coupon_code']), $code)) && ($code = preg_replace('/%%coupon_code%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($coupon['coupon_code']), $code)) && ($code = preg_replace('/%%coupon_affiliate_id%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($coupon['affiliate_id']), $code)))
 
 
 
 
 
 
 
 
243
 
244
+ if(($code = trim(preg_replace('/%%(.+?)%%/i', '', $code)))) // This gets stored into a Transient Queue.
245
+ {
246
+ $paypal['s2member_log'][] = 'Storing Specific Post/Page Tracking Codes into a Transient Queue. These will be processed on-site.';
247
+ set_transient('s2m_'.md5('s2member_transient_sp_tracking_codes_'.$paypal['txn_id']), $code, 43200);
248
+ }
249
+ }
250
+ foreach(array_keys(get_defined_vars()) as $__v) $__refs[$__v] =& $$__v;
251
+ do_action('ws_plugin__s2member_during_paypal_notify_during_sp_access', get_defined_vars());
252
+ unset($__refs, $__v);
253
  }
254
+ else $paypal['s2member_log'][] = 'Unable to generate Access Link for Specific Post/Page Access. Does your Leading Post/Page still exist?';
255
+ }
256
+ else // Else, this is a duplicate IPN. Must stop here.
257
+ {
258
+ $paypal['s2member_log'][] = 'Not processing. Duplicate IPN.';
259
+ $paypal['s2member_log'][] = 's2Member `txn_type` identified as ( `web_accept` ) for Specific Post/Page Access.';
260
+ $paypal['s2member_log'][] = 'Duplicate IPN. Already processed. This IPN will be ignored.';
261
+ }
262
+ foreach(array_keys(get_defined_vars()) as $__v) $__refs[$__v] =& $$__v;
263
+ do_action('ws_plugin__s2member_during_paypal_notify_after_sp_access', get_defined_vars());
264
+ unset($__refs, $__v);
265
+
266
+ return apply_filters('c_ws_plugin__s2member_paypal_notify_in_web_accept_sp', $paypal, get_defined_vars());
267
  }
268
+ else return apply_filters('c_ws_plugin__s2member_paypal_notify_in_web_accept_sp', FALSE, get_defined_vars());
269
+ }
270
+ }
271
+ }
includes/classes/paypal-notify-in.inc.php CHANGED
@@ -140,9 +140,6 @@ if(!class_exists('c_ws_plugin__s2member_paypal_notify_in'))
140
  else if(($_paypal_cp = c_ws_plugin__s2member_paypal_notify_in_billing_agreement_signup::cp(get_defined_vars())))
141
  $paypal = $_paypal_cp;
142
 
143
- else if(($_paypal_cp = c_ws_plugin__s2member_paypal_notify_in_merch_pmt::cp(get_defined_vars())))
144
- $paypal = $_paypal_cp;
145
-
146
  else // Ignoring this IPN request. The txn_type/status does NOT require any action.
147
  $paypal['s2member_log'][] = 'Ignoring this IPN request. The `txn_type/status` does NOT require any action on the part of s2Member.';
148
  }
140
  else if(($_paypal_cp = c_ws_plugin__s2member_paypal_notify_in_billing_agreement_signup::cp(get_defined_vars())))
141
  $paypal = $_paypal_cp;
142
 
 
 
 
143
  else // Ignoring this IPN request. The txn_type/status does NOT require any action.
144
  $paypal['s2member_log'][] = 'Ignoring this IPN request. The `txn_type/status` does NOT require any action on the part of s2Member.';
145
  }
includes/classes/paypal-return-in-subscr-modify-w-level.inc.php CHANGED
@@ -1,234 +1,240 @@
1
  <?php
2
  /**
3
- * s2Member's PayPal Auto-Return/PDT handler (inner processing routine).
4
- *
5
- * Copyright: © 2009-2011
6
- * {@link http://www.websharks-inc.com/ WebSharks, Inc.}
7
- * (coded in the USA)
8
- *
9
- * Released under the terms of the GNU General Public License.
10
- * You should have received a copy of the GNU General Public License,
11
- * along with this software. In the main directory, see: /licensing/
12
- * If not, see: {@link http://www.gnu.org/licenses/}.
13
- *
14
- * @package s2Member\PayPal
15
- * @since 110720
16
- */
17
- if(realpath(__FILE__) === realpath($_SERVER["SCRIPT_FILENAME"]))
18
- exit("Do not access this file directly.");
19
-
20
- if(!class_exists("c_ws_plugin__s2member_paypal_return_in_subscr_modify_w_level"))
 
 
 
 
 
 
 
 
21
  {
22
  /**
23
- * s2Member's PayPal Auto-Return/PDT handler (inner processing routine).
24
- *
25
- * @package s2Member\PayPal
26
- * @since 110720
27
- */
28
- class c_ws_plugin__s2member_paypal_return_in_subscr_modify_w_level
 
 
 
 
 
 
 
 
 
 
 
 
29
  {
30
- /**
31
- * s2Member's PayPal Auto-Return/PDT handler (inner processing routine).
32
- *
33
- * @package s2Member\PayPal
34
- * @since 110720
35
- *
36
- * @param array $vars Required. An array of defined variables passed by {@link s2Member\PayPal\c_ws_plugin__s2member_paypal_return_in::paypal_return()}.
37
- * @return array|bool The original ``$paypal`` array passed in (extracted) from ``$vars``, or false when conditions do NOT apply.
38
- */
39
- public static function /* Conditional phase for ``c_ws_plugin__s2member_paypal_notify_in::paypal_notify()``. */ cp($vars = array())
 
 
 
 
 
 
 
 
40
  {
41
- extract /* Extract all vars passed in from: ``c_ws_plugin__s2member_paypal_notify_in::paypal_notify()``. */($vars, EXTR_OVERWRITE | EXTR_REFS);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
42
 
43
- if((!empty($paypal["txn_type"]) && preg_match("/^subscr_modify$/i", $paypal["txn_type"]))
44
- && (!empty($paypal["item_number"]) && preg_match($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["membership_item_number_w_level_regex"], $paypal["item_number"]))
45
- && (!empty($paypal["subscr_id"])) && (!empty($paypal["subscr_baid"]) || ($paypal["subscr_baid"] = $paypal["subscr_id"]))
46
- && (!empty($paypal["subscr_cid"]) || ($paypal["subscr_cid"] = $paypal["subscr_id"])))
47
  {
48
- foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;
49
- do_action("ws_plugin__s2member_during_paypal_return_before_subscr_modify", get_defined_vars());
50
- unset($__refs, $__v);
51
-
52
- if(!get_transient($transient_rtn = "s2m_rtn_".md5("s2member_transient_".$_paypal_s)) && set_transient($transient_rtn, time(), 31556926 * 10))
53
- {
54
- $paypal["s2member_log"][] = "s2Member `txn_type` identified as ( `subscr_modify` ), a Subscription Modification.";
55
-
56
- list($paypal["level"], $paypal["ccaps"]/*, $paypal["eotper"] */) = preg_split("/\:/", $paypal["item_number"], 2);
57
-
58
- $paypal["ip"] = (preg_match("/ip address/i", $paypal["option_name2"]) && $paypal["option_selection2"]) ? $paypal["option_selection2"] : "";
59
- $paypal["ip"] = (!$paypal["ip"] && preg_match("/^[a-z0-9]+~[0-9\.]+$/i", $paypal["invoice"])) ? preg_replace("/^[a-z0-9]+~/i", "", $paypal["invoice"]) : $paypal["ip"];
60
- $paypal["ip"] = (!$paypal["ip"] && $_SERVER["REMOTE_ADDR"]) ? $_SERVER["REMOTE_ADDR"] : $paypal["ip"];
61
-
62
- $paypal["period1"] = (preg_match("/^[1-9]/", $paypal["period1"])) ? $paypal["period1"] : /* Defaults to "0 D" (zero days). */ "0 D";
63
- $paypal["mc_amount1"] = (strlen($paypal["mc_amount1"]) && $paypal["mc_amount1"] > 0) ? $paypal["mc_amount1"] : "0.00";
64
-
65
- if /* Conversions for Lifetime & Fixed-Term sales. */(preg_match("/^web_accept$/i", $paypal["txn_type"]))
66
- {
67
- $paypal["period3"] = ($paypal["eotper"]) ? $paypal["eotper"] : /* 1 Lifetime. */ "1 L";
68
- $paypal["mc_amount3"] = /* The "Buy Now" amount is the full gross. */ $paypal["mc_gross"];
69
- }
70
- $paypal["initial_term"] = (preg_match("/^[1-9]/", $paypal["period1"])) ? $paypal["period1"] : /* Defaults to "0 D" (zero days). */ "0 D";
71
- $paypal["initial"] = (strlen($paypal["mc_amount1"]) && preg_match("/^[1-9]/", $paypal["period1"])) ? $paypal["mc_amount1"] : $paypal["mc_amount3"];
72
- $paypal["regular"] = /* This is the Regular Payment Amount that is charged to the Customer. Always required by PayPal. */ $paypal["mc_amount3"];
73
- $paypal["regular_term"] = /* This is just set to keep a standard; this way both initial_term & regular_term are available. */ $paypal["period3"];
74
- $paypal["recurring"] = /* If non-recurring, this should be zero, otherwise Regular. */ ($paypal["recurring"]) ? $paypal["mc_amount3"] : "0";
75
-
76
- $ipn_signup_vars = $paypal; /* Create array of wouldbe IPN signup vars w/o s2member_log. */ unset($ipn_signup_vars["s2member_log"]);
77
-
78
- if(($user_id = c_ws_plugin__s2member_utils_users::get_user_id_with($paypal["subscr_id"])) && is_object($user = new WP_User($user_id)) && $user->ID)
79
- {
80
- if /* Do NOT process this routine on Administrators. */(!$user->has_cap("administrator"))
81
- {
82
- $processing = $modifying = $during = /* Yes, we ARE processing this. */ true;
83
-
84
- foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;
85
- do_action("ws_plugin__s2member_during_paypal_return_during_before_subscr_modify", get_defined_vars());
86
- do_action("ws_plugin__s2member_during_collective_mods", $user_id, get_defined_vars(), "rtn-upgrade-downgrade", "modification", "s2member_level".$paypal["level"]);
87
- unset($__refs, $__v);
88
-
89
- $fields = /* These will be needed in the routines below. */ get_user_option("s2member_custom_fields", $user_id);
90
- $user_reg_ip = /* Original IP during Registration. */ get_user_option("s2member_registration_ip", $user_id);
91
- $user_reg_ip = $paypal["ip"] = /* Now merge conditionally. */ ($user_reg_ip) ? $user_reg_ip : $paypal["ip"];
92
-
93
- if(is_multisite() && !is_user_member_of_blog($user_id) /* Must have a Role on this Blog. */)
94
- {
95
- add_existing_user_to_blog(array("user_id" => $user_id, "role" => "s2member_level".$paypal["level"]));
96
- $user = /* Now update the $user object we're using. */ new WP_User($user_id);
97
- }
98
- $current_role = c_ws_plugin__s2member_user_access::user_access_role($user);
99
-
100
- if /* Only if we need to. */($current_role !== "s2member_level".$paypal["level"])
101
- $user->set_role /* (upgrade/downgrade) */("s2member_level".$paypal["level"]);
102
-
103
- if($paypal["ccaps"] && preg_match("/^-all/", str_replace("+", "", $paypal["ccaps"])))
104
- foreach($user->allcaps as $cap => $cap_enabled)
105
- if(preg_match("/^access_s2member_ccap_/", $cap))
106
- $user->remove_cap($ccap = $cap);
107
-
108
- if($paypal["ccaps"] && preg_replace("/^-all[\r\n\t\s;,]*/", "", str_replace("+", "", $paypal["ccaps"])))
109
- foreach(preg_split("/[\r\n\t\s;,]+/", preg_replace("/^-all[\r\n\t\s;,]*/", "", str_replace("+", "", $paypal["ccaps"]))) as $ccap)
110
- if(strlen($ccap = trim(strtolower(preg_replace("/[^a-z_0-9]/i", "", $ccap)))))
111
- $user->add_cap("access_s2member_ccap_".$ccap);
112
-
113
- update_user_option($user_id, "s2member_subscr_gateway", $paypal["subscr_gateway"]);
114
- update_user_option($user_id, "s2member_subscr_id", $paypal["subscr_id"]);
115
- update_user_option($user_id, "s2member_subscr_baid", $paypal["subscr_baid"]);
116
- update_user_option($user_id, "s2member_subscr_cid", $paypal["subscr_cid"]);
117
-
118
- update_user_option($user_id, "s2member_custom", $paypal["custom"]);
119
-
120
- if(!get_user_option("s2member_registration_ip", $user_id))
121
- update_user_option($user_id, "s2member_registration_ip", $paypal["ip"]);
122
-
123
- update_user_option($user_id, "s2member_ipn_signup_vars", $ipn_signup_vars);
124
-
125
- delete_user_option($user_id, "s2member_file_download_access_log");
126
-
127
- delete_user_option($user_id, "s2member_auto_eot_time");
128
-
129
- $pr_times = get_user_option("s2member_paid_registration_times", $user_id);
130
- $pr_times["level"] = /* Preserve existing. */ (!$pr_times["level"]) ? time() : $pr_times["level"];
131
- $pr_times["level".$paypal["level"]] = (!$pr_times["level".$paypal["level"]]) ? time() : $pr_times["level".$paypal["level"]];
132
- update_user_option($user_id, "s2member_paid_registration_times", $pr_times);
133
-
134
- c_ws_plugin__s2member_user_notes::clear_user_note_lines($user_id, "/^Demoted by s2Member\:/");
135
- c_ws_plugin__s2member_user_notes::clear_user_note_lines ($user_id, "/^Paid Subscr\. ID @ time of demotion\:/");
136
-
137
- $paypal["s2member_log"][] = "s2Member Level/Capabilities updated on ( `subscr_modify` ), a Subscription Modification.";
138
-
139
- setcookie("s2member_tracking", ($s2member_tracking = c_ws_plugin__s2member_utils_encryption::encrypt($paypal["subscr_id"])), time() + 31556926, COOKIEPATH, COOKIE_DOMAIN).setcookie("s2member_tracking", $s2member_tracking, time() + 31556926, SITECOOKIEPATH, COOKIE_DOMAIN).($_COOKIE["s2member_tracking"] = $s2member_tracking);
140
-
141
- $paypal["s2member_log"][] = "Transient Tracking Cookie set on ( `subscr_modify` ), a Subscription Modification.";
142
-
143
- if($processing && ($code = $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["modification_tracking_codes"]) && is_array($cv = preg_split("/\|/", $paypal["custom"])))
144
- {
145
- if(($code = preg_replace("/%%cv([0-9]+)%%/ei", 'trim(@$cv[$1])', $code)) && ($code = preg_replace("/%%subscr_id%%/i", c_ws_plugin__s2member_utils_strings::esc_refs($paypal["subscr_id"]), $code)))
146
- if(($code = preg_replace("/%%subscr_baid%%/i", c_ws_plugin__s2member_utils_strings::esc_refs($paypal["subscr_baid"]), $code)) && ($code = preg_replace("/%%subscr_cid%%/i", c_ws_plugin__s2member_utils_strings::esc_refs($paypal["subscr_cid"]), $code)))
147
- if(($code = preg_replace("/%%initial%%/i", c_ws_plugin__s2member_utils_strings::esc_refs($paypal["initial"]), $code)) && ($code = preg_replace("/%%regular%%/i", c_ws_plugin__s2member_utils_strings::esc_refs($paypal["regular"]), $code)) && ($code = preg_replace("/%%recurring%%/i", c_ws_plugin__s2member_utils_strings::esc_refs($paypal["recurring"]), $code)))
148
- if(($code = preg_replace("/%%initial_term%%/i", c_ws_plugin__s2member_utils_strings::esc_refs($paypal["initial_term"]), $code)) && ($code = preg_replace("/%%regular_term%%/i", c_ws_plugin__s2member_utils_strings::esc_refs($paypal["regular_term"]), $code)))
149
- if(($code = preg_replace("/%%item_number%%/i", c_ws_plugin__s2member_utils_strings::esc_refs($paypal["item_number"]), $code)) && ($code = preg_replace("/%%item_name%%/i", c_ws_plugin__s2member_utils_strings::esc_refs($paypal["item_name"]), $code)))
150
- if(($code = preg_replace("/%%first_name%%/i", c_ws_plugin__s2member_utils_strings::esc_refs($paypal["first_name"]), $code)) && ($code = preg_replace("/%%last_name%%/i", c_ws_plugin__s2member_utils_strings::esc_refs($paypal["last_name"]), $code)))
151
- if(($code = preg_replace("/%%full_name%%/i", c_ws_plugin__s2member_utils_strings::esc_refs(trim($paypal["first_name"]." ".$paypal["last_name"])), $code)))
152
- if(($code = preg_replace("/%%payer_email%%/i", c_ws_plugin__s2member_utils_strings::esc_refs($paypal["payer_email"]), $code)))
153
- {
154
- if(($code = preg_replace("/%%user_first_name%%/i", c_ws_plugin__s2member_utils_strings::esc_refs($user->first_name), $code)) && ($code = preg_replace("/%%user_last_name%%/i", c_ws_plugin__s2member_utils_strings::esc_refs($user->last_name), $code)))
155
- if(($code = preg_replace("/%%user_full_name%%/i", c_ws_plugin__s2member_utils_strings::esc_refs(trim($user->first_name." ".$user->last_name)), $code)))
156
- if(($code = preg_replace("/%%user_email%%/i", c_ws_plugin__s2member_utils_strings::esc_refs($user->user_email), $code)))
157
- if(($code = preg_replace("/%%user_login%%/i", c_ws_plugin__s2member_utils_strings::esc_refs($user->user_login), $code)))
158
- if(($code = preg_replace("/%%user_ip%%/i", c_ws_plugin__s2member_utils_strings::esc_refs($user_reg_ip), $code)))
159
- if(($code = preg_replace("/%%user_id%%/i", c_ws_plugin__s2member_utils_strings::esc_refs($user_id), $code)))
160
- {
161
- if(is_array($fields) && !empty($fields))
162
- foreach /* Custom Registration/Profile Fields. */($fields as $var => $val)
163
- if(!($code = preg_replace("/%%".preg_quote($var, "/")."%%/i", c_ws_plugin__s2member_utils_strings::esc_refs(maybe_serialize($val)), $code)))
164
- break;
165
-
166
- if(($code = trim(preg_replace("/%%(.+?)%%/i", "", $code))) /* This gets stored into a Transient Queue. */)
167
- {
168
- $paypal["s2member_log"][] = "Storing Modification Tracking Codes into a Transient Queue. These will be processed on-site.";
169
- set_transient("s2m_".md5("s2member_transient_modification_tracking_codes_".$paypal["subscr_id"]), $code, 43200);
170
- }
171
- }
172
- }
173
- }
174
- foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;
175
- do_action("ws_plugin__s2member_during_paypal_return_during_subscr_modify", get_defined_vars());
176
- unset($__refs, $__v);
177
-
178
- if(($redirection_url_after_modification = apply_filters("ws_plugin__s2member_redirection_url_after_modification", false, get_defined_vars())))
179
- {
180
- $paypal["s2member_log"][] = "Redirecting this Member to a custom URL after modification: ".$redirection_url_after_modification;
181
-
182
- wp_redirect($redirection_url_after_modification);
183
- }
184
- else // Else, use standard/default handling in this scenario. Have the Customer log in again.
185
- {
186
- $paypal["s2member_log"][] = "Redirecting Customer to the Login Page (after displaying a quick thank-you message). They need to log back in.";
187
-
188
- echo c_ws_plugin__s2member_return_templates::return_template($paypal["subscr_gateway"],
189
- '<strong>'._x("Thank you! You've been updated to:", "s2member-front", "s2member").'<br /><em>'.esc_html($paypal["item_name"]).'</em></strong>',
190
- _x("Please Log Back In (Click Here)", "s2member-front", "s2member"), wp_login_url());
191
- }
192
- }
193
- else // Else, unable to modify Subscription. The existing User ID is associated with an Administrator. Stopping here.
194
- {
195
- $paypal["s2member_log"][] = "Unable to modify Subscription. The existing User ID is associated with an Administrator. Stopping here. Otherwise, an Administrator could lose access. Please make sure that you are NOT logged in as an Administrator while testing.";
196
-
197
- $paypal["s2member_log"][] = "Redirecting Customer to the Home Page (after displaying an error message).";
198
-
199
- echo c_ws_plugin__s2member_return_templates::return_template($paypal["subscr_gateway"],
200
- _x('<strong>ERROR:</strong> Unable to modify Subscription.<br />Please contact Support for assistance.<br /><br />The existing User ID is associated with an Administrator. Stopping here. Otherwise, an Administrator could lose access. Please make sure that you are NOT logged in as an Administrator while testing.', "s2member-front", "s2member"),
201
- _x("Back To Home Page", "s2member-front", "s2member"), home_url("/"));
202
- }
203
- }
204
- else // Unable to modify Subscription. Could not get the existing User ID from the DB.
205
- {
206
- $paypal["s2member_log"][] = "Unable to modify Subscription. Could not get the existing User ID from the DB.";
207
-
208
- $paypal["s2member_log"][] = "Redirecting Customer to the Home Page (after displaying an error message).";
209
-
210
- echo c_ws_plugin__s2member_return_templates::return_template($paypal["subscr_gateway"],
211
- _x('<strong>ERROR:</strong> Unable to modify Subscription.<br />Please contact Support for assistance.<br /><br />Could not get the existing User ID from the DB.', "s2member-front", "s2member"),
212
- _x("Back To Home Page", "s2member-front", "s2member"), home_url("/"));
213
- }
214
- }
215
- else // Page Expired. Duplicate Return-Data.
216
- {
217
- $paypal["s2member_log"][] = "Page Expired. Duplicate Return-Data.";
218
- $paypal["s2member_log"][] = "s2Member `txn_type` identified as `subscr_modify`.";
219
- $paypal['s2member_log'][] = 'Page Expired. Instructing customer to check their email for further details about how to obtain access to what they purchased.';
220
-
221
- echo c_ws_plugin__s2member_return_templates::return_template($paypal['subscr_gateway'],
222
- '<strong>'._x('Thank you! Please check your email for further details regarding your purchase.', 's2member-front', 's2member').'</strong>',
223
- _x('Return to Home Page', 's2member-front', 's2member'), home_url("/"));
224
- }
225
- foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;
226
- do_action("ws_plugin__s2member_during_paypal_return_after_subscr_modify", get_defined_vars());
227
- unset($__refs, $__v);
228
 
229
- return apply_filters("c_ws_plugin__s2member_paypal_return_in_subscr_modify_w_level", $paypal, get_defined_vars());
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
230
  }
231
- else return apply_filters("c_ws_plugin__s2member_paypal_return_in_subscr_modify_w_level", false, get_defined_vars());
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
232
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
233
  }
234
- }
 
 
 
1
  <?php
2
  /**
3
+ * s2Member's PayPal Auto-Return/PDT handler (inner processing routine).
4
+ *
5
+ * Copyright: © 2009-2011
6
+ * {@link http://www.websharks-inc.com/ WebSharks, Inc.}
7
+ * (coded in the USA)
8
+ *
9
+ * Released under the terms of the GNU General Public License.
10
+ * You should have received a copy of the GNU General Public License,
11
+ * along with this software. In the main directory, see: /licensing/
12
+ * If not, see: {@link http://www.gnu.org/licenses/}.
13
+ *
14
+ * @package s2Member\PayPal
15
+ * @since 110720
16
+ */
17
+ if(realpath(__FILE__) === realpath($_SERVER['SCRIPT_FILENAME']))
18
+ exit('Do not access this file directly.');
19
+
20
+ if(!class_exists('c_ws_plugin__s2member_paypal_return_in_subscr_modify_w_level'))
21
+ {
22
+ /**
23
+ * s2Member's PayPal Auto-Return/PDT handler (inner processing routine).
24
+ *
25
+ * @package s2Member\PayPal
26
+ * @since 110720
27
+ */
28
+ class c_ws_plugin__s2member_paypal_return_in_subscr_modify_w_level
29
  {
30
  /**
31
+ * s2Member's PayPal Auto-Return/PDT handler (inner processing routine).
32
+ *
33
+ * @package s2Member\PayPal
34
+ * @since 110720
35
+ *
36
+ * @param array $vars Required. An array of defined variables passed by {@link s2Member\PayPal\c_ws_plugin__s2member_paypal_return_in::paypal_return()}.
37
+ *
38
+ * @return array|bool The original ``$paypal`` array passed in (extracted) from ``$vars``, or false when conditions do NOT apply.
39
+ */
40
+ public static function cp($vars = array() /* Conditional phase for ``c_ws_plugin__s2member_paypal_notify_in::paypal_notify()``. */)
41
+ {
42
+ extract($vars, EXTR_OVERWRITE | EXTR_REFS /* Extract all vars passed in from: ``c_ws_plugin__s2member_paypal_notify_in::paypal_notify()``. */);
43
+
44
+ if((!empty($paypal['txn_type']) && preg_match('/^subscr_modify$/i', $paypal['txn_type']))
45
+ && (!empty($paypal['item_number']) && preg_match($GLOBALS['WS_PLUGIN__']['s2member']['c']['membership_item_number_w_level_regex'], $paypal['item_number']))
46
+ && (!empty($paypal['subscr_id'])) && (!empty($paypal['subscr_baid']) || ($paypal['subscr_baid'] = $paypal['subscr_id']))
47
+ && (!empty($paypal['subscr_cid']) || ($paypal['subscr_cid'] = $paypal['subscr_id']))
48
+ )
49
  {
50
+ foreach(array_keys(get_defined_vars()) as $__v) $__refs[$__v] =& $$__v;
51
+ do_action('ws_plugin__s2member_during_paypal_return_before_subscr_modify', get_defined_vars());
52
+ unset($__refs, $__v);
53
+
54
+ if(!get_transient($transient_rtn = 's2m_rtn_'.md5('s2member_transient_'.$_paypal_s)) && set_transient($transient_rtn, time(), 31556926 * 10))
55
+ {
56
+ $paypal['s2member_log'][] = 's2Member `txn_type` identified as ( `subscr_modify` ), a Subscription Modification.';
57
+
58
+ list($paypal['level'], $paypal['ccaps']/*, $paypal['eotper'] */) = preg_split('/\:/', $paypal['item_number'], 2);
59
+
60
+ $paypal['ip'] = (preg_match('/ip address/i', $paypal['option_name2']) && $paypal['option_selection2']) ? $paypal['option_selection2'] : '';
61
+ $paypal['ip'] = (!$paypal['ip'] && preg_match('/^[a-z0-9]+~[0-9\.]+$/i', $paypal['invoice'])) ? preg_replace('/^[a-z0-9]+~/i', '', $paypal['invoice']) : $paypal['ip'];
62
+ $paypal['ip'] = (!$paypal['ip'] && $_SERVER['REMOTE_ADDR']) ? $_SERVER['REMOTE_ADDR'] : $paypal['ip'];
63
+
64
+ $paypal['period1'] = (preg_match('/^[1-9]/', $paypal['period1'])) ? $paypal['period1'] : '0 D'; // Defaults to '0 D' (zero days).
65
+ $paypal['mc_amount1'] = (strlen($paypal['mc_amount1']) && $paypal['mc_amount1'] > 0) ? $paypal['mc_amount1'] : '0.00';
66
+
67
+ if(preg_match('/^web_accept$/i', $paypal['txn_type']) /* Conversions for Lifetime & Fixed-Term sales. */)
68
  {
69
+ $paypal['period3'] = !empty($paypal['eotper']) ? $paypal['eotper'] : '1 L'; // 1 Lifetime.
70
+ $paypal['mc_amount3'] = $paypal['mc_gross']; // The 'Buy Now' amount is the full gross.
71
+ }
72
+ $paypal['initial_term'] = (preg_match('/^[1-9]/', $paypal['period1'])) ? $paypal['period1'] : '0 D'; // Defaults to '0 D' (zero days).
73
+ $paypal['initial'] = (strlen($paypal['mc_amount1']) && preg_match('/^[1-9]/', $paypal['period1'])) ? $paypal['mc_amount1'] : $paypal['mc_amount3'];
74
+ $paypal['regular'] = $paypal['mc_amount3']; // This is the Regular Payment Amount that is charged to the Customer. Always required by PayPal.
75
+ $paypal['regular_term'] = $paypal['period3']; // This is just set to keep a standard; this way both initial_term & regular_term are available.
76
+ $paypal['recurring'] = ($paypal['recurring']) ? $paypal['mc_amount3'] : '0'; // If non-recurring, this should be zero, otherwise Regular.
77
+ $paypal['currency'] = strtoupper($paypal['mc_currency']); // Normalize input currency.
78
+ $paypal['currency_symbol'] = c_ws_plugin__s2member_utils_cur::symbol($paypal['currency']);
79
+
80
+ $ipn_signup_vars = $paypal; // Copy of PayPal vars; used as IPN signup vars.
81
+ unset($ipn_signup_vars['s2member_log']); // Create array of wouldbe IPN signup vars w/o s2member_log.
82
+
83
+ if(($user_id = c_ws_plugin__s2member_utils_users::get_user_id_with($paypal['subscr_id'])) && is_object($user = new WP_User($user_id)) && $user->ID)
84
+ {
85
+ if(!$user->has_cap('administrator') /* Do NOT process this routine on Administrators. */)
86
+ {
87
+ $processing = $modifying = $during = TRUE; // Yes, we ARE processing this.
88
+
89
+ foreach(array_keys(get_defined_vars()) as $__v) $__refs[$__v] =& $$__v;
90
+ do_action('ws_plugin__s2member_during_paypal_return_during_before_subscr_modify', get_defined_vars());
91
+ do_action('ws_plugin__s2member_during_collective_mods', $user_id, get_defined_vars(), 'rtn-upgrade-downgrade', 'modification', 's2member_level'.$paypal['level']);
92
+ unset($__refs, $__v);
93
+
94
+ $fields = get_user_option('s2member_custom_fields', $user_id); // These will be needed in the routines below.
95
+ $user_reg_ip = get_user_option('s2member_registration_ip', $user_id); // Original IP during Registration.
96
+ $user_reg_ip = $paypal['ip'] = ($user_reg_ip) ? $user_reg_ip : $paypal['ip']; // Now merge conditionally.
97
 
98
+ if(is_multisite() && !is_user_member_of_blog($user_id) /* Must have a Role on this Blog. */)
 
 
 
99
  {
100
+ add_existing_user_to_blog(array('user_id' => $user_id, 'role' => 's2member_level'.$paypal['level']));
101
+ $user = new WP_User($user_id); // Now update the $user object we're using.
102
+ }
103
+ $current_role = c_ws_plugin__s2member_user_access::user_access_role($user);
104
+
105
+ if($current_role !== 's2member_level'.$paypal['level'] /* Only if we need to. */)
106
+ $user->set_role('s2member_level'.$paypal['level']); // Upgrade/downgrade.
107
+
108
+ if($paypal['ccaps'] && preg_match('/^-all/', str_replace('+', '', $paypal['ccaps'])))
109
+ foreach($user->allcaps as $cap => $cap_enabled)
110
+ if(preg_match('/^access_s2member_ccap_/', $cap))
111
+ $user->remove_cap($ccap = $cap);
112
+
113
+ if($paypal['ccaps'] && preg_replace('/^-all['."\r\n\t".'\s;,]*/', '', str_replace('+', '', $paypal['ccaps'])))
114
+ foreach(preg_split('/['."\r\n\t".'\s;,]+/', preg_replace('/^-all['."\r\n\t".'\s;,]*/', '', str_replace('+', '', $paypal['ccaps']))) as $ccap)
115
+ if(strlen($ccap = trim(strtolower(preg_replace('/[^a-z_0-9]/i', '', $ccap)))))
116
+ $user->add_cap('access_s2member_ccap_'.$ccap);
117
+
118
+ update_user_option($user_id, 's2member_subscr_gateway', $paypal['subscr_gateway']);
119
+ update_user_option($user_id, 's2member_subscr_id', $paypal['subscr_id']);
120
+ update_user_option($user_id, 's2member_subscr_baid', $paypal['subscr_baid']);
121
+ update_user_option($user_id, 's2member_subscr_cid', $paypal['subscr_cid']);
122
+
123
+ update_user_option($user_id, 's2member_custom', $paypal['custom']);
124
+
125
+ if(!get_user_option('s2member_registration_ip', $user_id))
126
+ update_user_option($user_id, 's2member_registration_ip', $paypal['ip']);
127
+
128
+ update_user_option($user_id, 's2member_ipn_signup_vars', $ipn_signup_vars);
129
+
130
+ delete_user_option($user_id, 's2member_file_download_access_log');
131
+
132
+ delete_user_option($user_id, 's2member_auto_eot_time');
133
+
134
+ $pr_times = get_user_option('s2member_paid_registration_times', $user_id);
135
+ $pr_times['level'] = (!$pr_times['level']) ? time() : $pr_times['level']; // Preserve existing.
136
+ $pr_times['level'.$paypal['level']] = (!$pr_times['level'.$paypal['level']]) ? time() : $pr_times['level'.$paypal['level']];
137
+ update_user_option($user_id, 's2member_paid_registration_times', $pr_times);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
138
 
139
+ c_ws_plugin__s2member_user_notes::clear_user_note_lines($user_id, '/^Demoted by s2Member\:/');
140
+ c_ws_plugin__s2member_user_notes::clear_user_note_lines($user_id, '/^Paid Subscr\. ID @ time of demotion\:/');
141
+
142
+ $paypal['s2member_log'][] = 's2Member Level/Capabilities updated on ( `subscr_modify` ), a Subscription Modification.';
143
+
144
+ setcookie('s2member_tracking', ($s2member_tracking = c_ws_plugin__s2member_utils_encryption::encrypt($paypal['subscr_id'])), time() + 31556926, COOKIEPATH, COOKIE_DOMAIN).setcookie('s2member_tracking', $s2member_tracking, time() + 31556926, SITECOOKIEPATH, COOKIE_DOMAIN).($_COOKIE['s2member_tracking'] = $s2member_tracking);
145
+
146
+ $paypal['s2member_log'][] = 'Transient Tracking Cookie set on ( `subscr_modify` ), a Subscription Modification.';
147
+
148
+ if($processing && ($code = $GLOBALS['WS_PLUGIN__']['s2member']['o']['modification_tracking_codes']) && is_array($cv = preg_split('/\|/', $paypal['custom'])))
149
+ {
150
+ if(($code = preg_replace('/%%cv([0-9]+)%%/ei', 'trim(@$cv[$1])', $code)) && ($code = preg_replace('/%%subscr_id%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['subscr_id']), $code)))
151
+ if(($code = preg_replace('/%%subscr_baid%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['subscr_baid']), $code)) && ($code = preg_replace('/%%subscr_cid%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['subscr_cid']), $code)))
152
+ if(($code = preg_replace('/%%currency%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['currency']), $code)) && ($code = preg_replace('/%%currency_symbol%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['currency_symbol']), $code)))
153
+ if(($code = preg_replace('/%%initial%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['initial']), $code)) && ($code = preg_replace('/%%regular%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['regular']), $code)) && ($code = preg_replace('/%%recurring%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['recurring']), $code)))
154
+ if(($code = preg_replace('/%%initial_term%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['initial_term']), $code)) && ($code = preg_replace('/%%regular_term%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['regular_term']), $code)))
155
+ if(($code = preg_replace('/%%item_number%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['item_number']), $code)) && ($code = preg_replace('/%%item_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['item_name']), $code)))
156
+ if(($code = preg_replace('/%%first_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['first_name']), $code)) && ($code = preg_replace('/%%last_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['last_name']), $code)))
157
+ if(($code = preg_replace('/%%full_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(trim($paypal['first_name'].' '.$paypal['last_name'])), $code)))
158
+ if(($code = preg_replace('/%%payer_email%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['payer_email']), $code)))
159
+ {
160
+ if(($code = preg_replace('/%%user_first_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($user->first_name), $code)) && ($code = preg_replace('/%%user_last_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($user->last_name), $code)))
161
+ if(($code = preg_replace('/%%user_full_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(trim($user->first_name.' '.$user->last_name)), $code)))
162
+ if(($code = preg_replace('/%%user_email%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($user->user_email), $code)))
163
+ if(($code = preg_replace('/%%user_login%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($user->user_login), $code)))
164
+ if(($code = preg_replace('/%%user_ip%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($user_reg_ip), $code)))
165
+ if(($code = preg_replace('/%%user_id%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($user_id), $code)))
166
+ {
167
+ if(is_array($fields) && !empty($fields))
168
+ foreach($fields as $var => $val /* Custom Registration/Profile Fields. */)
169
+ if(!($code = preg_replace('/%%'.preg_quote($var, '/').'%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(maybe_serialize($val)), $code)))
170
+ break;
171
+
172
+ if(($code = trim(preg_replace('/%%(.+?)%%/i', '', $code))) /* This gets stored into a Transient Queue. */)
173
+ {
174
+ $paypal['s2member_log'][] = 'Storing Modification Tracking Codes into a Transient Queue. These will be processed on-site.';
175
+ set_transient('s2m_'.md5('s2member_transient_modification_tracking_codes_'.$paypal['subscr_id']), $code, 43200);
176
+ }
177
+ }
178
+ }
179
+ }
180
+ foreach(array_keys(get_defined_vars()) as $__v) $__refs[$__v] =& $$__v;
181
+ do_action('ws_plugin__s2member_during_paypal_return_during_subscr_modify', get_defined_vars());
182
+ unset($__refs, $__v);
183
+
184
+ if(($redirection_url_after_modification = apply_filters('ws_plugin__s2member_redirection_url_after_modification', FALSE, get_defined_vars())))
185
+ {
186
+ $paypal['s2member_log'][] = 'Redirecting this Member to a custom URL after modification: '.$redirection_url_after_modification;
187
+
188
+ wp_redirect($redirection_url_after_modification);
189
+ }
190
+ else // Else, use standard/default handling in this scenario. Have the Customer log in again.
191
+ {
192
+ $paypal['s2member_log'][] = 'Redirecting Customer to the Login Page (after displaying a quick thank-you message). They need to log back in.';
193
+
194
+ echo c_ws_plugin__s2member_return_templates::return_template($paypal['subscr_gateway'],
195
+ '<strong>'._x('Thank you! You\'ve been updated to:', 's2member-front', 's2member').'<br /><em>'.esc_html($paypal['item_name']).'</em></strong>',
196
+ _x('Please Log Back In (Click Here)', 's2member-front', 's2member'), wp_login_url());
197
  }
198
+ }
199
+ else // Else, unable to modify Subscription. The existing User ID is associated with an Administrator. Stopping here.
200
+ {
201
+ $paypal['s2member_log'][] = 'Unable to modify Subscription. The existing User ID is associated with an Administrator. Stopping here. Otherwise, an Administrator could lose access. Please make sure that you are NOT logged in as an Administrator while testing.';
202
+
203
+ $paypal['s2member_log'][] = 'Redirecting Customer to the Home Page (after displaying an error message).';
204
+
205
+ echo c_ws_plugin__s2member_return_templates::return_template($paypal['subscr_gateway'],
206
+ _x('<strong>ERROR:</strong> Unable to modify Subscription.<br />Please contact Support for assistance.<br /><br />The existing User ID is associated with an Administrator. Stopping here. Otherwise, an Administrator could lose access. Please make sure that you are NOT logged in as an Administrator while testing.', 's2member-front', 's2member'),
207
+ _x('Back To Home Page', 's2member-front', 's2member'), home_url('/'));
208
+ }
209
+ }
210
+ else // Unable to modify Subscription. Could not get the existing User ID from the DB.
211
+ {
212
+ $paypal['s2member_log'][] = 'Unable to modify Subscription. Could not get the existing User ID from the DB.';
213
+
214
+ $paypal['s2member_log'][] = 'Redirecting Customer to the Home Page (after displaying an error message).';
215
+
216
+ echo c_ws_plugin__s2member_return_templates::return_template($paypal['subscr_gateway'],
217
+ _x('<strong>ERROR:</strong> Unable to modify Subscription.<br />Please contact Support for assistance.<br /><br />Could not get the existing User ID from the DB.', 's2member-front', 's2member'),
218
+ _x('Back To Home Page', 's2member-front', 's2member'), home_url('/'));
219
  }
220
+ }
221
+ else // Page Expired. Duplicate Return-Data.
222
+ {
223
+ $paypal['s2member_log'][] = 'Page Expired. Duplicate Return-Data.';
224
+ $paypal['s2member_log'][] = 's2Member `txn_type` identified as `subscr_modify`.';
225
+ $paypal['s2member_log'][] = 'Page Expired. Instructing customer to check their email for further details about how to obtain access to what they purchased.';
226
+
227
+ echo c_ws_plugin__s2member_return_templates::return_template($paypal['subscr_gateway'],
228
+ '<strong>'._x('Thank you! Please check your email for further details regarding your purchase.', 's2member-front', 's2member').'</strong>',
229
+ _x('Return to Home Page', 's2member-front', 's2member'), home_url('/'));
230
+ }
231
+ foreach(array_keys(get_defined_vars()) as $__v) $__refs[$__v] =& $$__v;
232
+ do_action('ws_plugin__s2member_during_paypal_return_after_subscr_modify', get_defined_vars());
233
+ unset($__refs, $__v);
234
+
235
+ return apply_filters('c_ws_plugin__s2member_paypal_return_in_subscr_modify_w_level', $paypal, get_defined_vars());
236
  }
237
+ else return apply_filters('c_ws_plugin__s2member_paypal_return_in_subscr_modify_w_level', FALSE, get_defined_vars());
238
+ }
239
+ }
240
+ }
includes/classes/paypal-return-in-subscr-or-wa-w-level.inc.php CHANGED
@@ -79,13 +79,15 @@ if(!class_exists('c_ws_plugin__s2member_paypal_return_in_subscr_or_wa_w_level'))
79
 
80
  $paypal['recurring'] = ($tra['rr'] === '1') ? '1' : '0';
81
 
82
- $paypal['initial_term'] = (preg_match('/^[1-9]/', $paypal['period1'])) ? $paypal['period1'] : '0 D'; // Defaults to '0 D' (zero days).
83
- $paypal['initial'] = (strlen($paypal['mc_amount1']) && preg_match('/^[1-9]/', $paypal['period1'])) ? $paypal['mc_amount1'] : $paypal['mc_amount3'];
84
- $paypal['regular'] = $paypal['mc_amount3']; // This is the Regular Payment Amount that is charged to the Customer. Always required by PayPal.
85
- $paypal['regular_term'] = $paypal['period3']; // This is just set to keep a standard; this way both initial_term & regular_term are available.
86
- $paypal['recurring'] = ($paypal['recurring']) ? $paypal['mc_amount3'] : '0'; // If non-recurring, this should be zero, otherwise Regular.
87
-
88
- $ipn_signup_vars = $paypal;
 
 
89
  unset($ipn_signup_vars['s2member_log']); // Create array of wouldbe IPN signup vars w/o s2member_log.
90
  }
91
  else if(preg_match('/^(web_accept|subscr_signup)$/i', $paypal['txn_type']))
@@ -100,13 +102,15 @@ if(!class_exists('c_ws_plugin__s2member_paypal_return_in_subscr_or_wa_w_level'))
100
  $paypal['period3'] = ($paypal['eotper']) ? $paypal['eotper'] : '1 L'; // 1 Lifetime.
101
  $paypal['mc_amount3'] = $paypal['mc_gross']; // The 'Buy Now' amount is the full gross.
102
  }
103
- $paypal['initial_term'] = (preg_match('/^[1-9]/', $paypal['period1'])) ? $paypal['period1'] : '0 D'; // Defaults to '0 D' (zero days).
104
- $paypal['initial'] = (strlen($paypal['mc_amount1']) && preg_match('/^[1-9]/', $paypal['period1'])) ? $paypal['mc_amount1'] : $paypal['mc_amount3'];
105
- $paypal['regular'] = $paypal['mc_amount3']; // This is the Regular Payment Amount that is charged to the Customer. Always required by PayPal.
106
- $paypal['regular_term'] = $paypal['period3']; // This is just set to keep a standard; this way both initial_term & regular_term are available.
107
- $paypal['recurring'] = ($paypal['recurring']) ? $paypal['mc_amount3'] : '0'; // If non-recurring, this should be zero, otherwise Regular.
108
-
109
- $ipn_signup_vars = $paypal;
 
 
110
  unset($ipn_signup_vars['s2member_log']); // Create array of wouldbe IPN signup vars w/o s2member_log.
111
  }
112
  else $tracking_properties = FALSE; // Not possible.
@@ -199,32 +203,33 @@ if(!class_exists('c_ws_plugin__s2member_paypal_return_in_subscr_or_wa_w_level'))
199
  {
200
  if(($code = preg_replace('/%%cv([0-9]+)%%/ei', 'trim(@$cv[$1])', $code)) && ($code = preg_replace('/%%subscr_id%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['subscr_id']), $code)))
201
  if(($code = preg_replace('/%%subscr_baid%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['subscr_baid']), $code)) && ($code = preg_replace('/%%subscr_cid%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['subscr_cid']), $code)))
202
- if(($code = preg_replace('/%%initial%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['initial']), $code)) && ($code = preg_replace('/%%regular%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['regular']), $code)) && ($code = preg_replace('/%%recurring%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['recurring']), $code)))
203
- if(($code = preg_replace('/%%initial_term%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['initial_term']), $code)) && ($code = preg_replace('/%%regular_term%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['regular_term']), $code)))
204
- if(($code = preg_replace('/%%item_number%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['item_number']), $code)) && ($code = preg_replace('/%%item_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['item_name']), $code)))
205
- if(($code = preg_replace('/%%first_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['first_name']), $code)) && ($code = preg_replace('/%%last_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['last_name']), $code)))
206
- if(($code = preg_replace('/%%full_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(trim($paypal['first_name'].' '.$paypal['last_name'])), $code)))
207
- if(($code = preg_replace('/%%payer_email%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['payer_email']), $code)))
208
- {
209
- if(($code = preg_replace('/%%user_first_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($user->first_name), $code)) && ($code = preg_replace('/%%user_last_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($user->last_name), $code)))
210
- if(($code = preg_replace('/%%user_full_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(trim($user->first_name.' '.$user->last_name)), $code)))
211
- if(($code = preg_replace('/%%user_email%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($user->user_email), $code)))
212
- if(($code = preg_replace('/%%user_login%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($user->user_login), $code)))
213
- if(($code = preg_replace('/%%user_ip%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($user_reg_ip), $code)))
214
- if(($code = preg_replace('/%%user_id%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($user_id), $code)))
215
- {
216
- if(is_array($fields) && !empty($fields))
217
- foreach($fields as $var => $val) // Custom Registration/Profile Fields.
218
- if(!($code = preg_replace('/%%'.preg_quote($var, '/').'%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(maybe_serialize($val)), $code)))
219
- break;
220
-
221
- if(($code = trim(preg_replace('/%%(.+?)%%/i', '', $code))) /* This gets stored into a Transient Queue. */)
222
  {
223
- $paypal['s2member_log'][] = 'Storing Modification Tracking Codes into a Transient Queue. These will be processed on-site.';
224
- set_transient('s2m_'.md5('s2member_transient_modification_tracking_codes_'.$paypal['subscr_id']), $code, 43200);
 
 
 
 
 
 
 
 
225
  }
226
- }
227
- }
228
  }
229
  foreach(array_keys(get_defined_vars()) as $__v) $__refs[$__v] =& $$__v;
230
  do_action('ws_plugin__s2member_during_paypal_return_during_subscr_signup_w_update_vars', get_defined_vars());
@@ -298,19 +303,20 @@ if(!class_exists('c_ws_plugin__s2member_paypal_return_in_subscr_or_wa_w_level'))
298
  {
299
  if(($code = preg_replace('/%%cv([0-9]+)%%/ei', 'trim(@$cv[$1])', $code)) && ($code = preg_replace('/%%subscr_id%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['subscr_id']), $code)))
300
  if(($code = preg_replace('/%%subscr_baid%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['subscr_baid']), $code)) && ($code = preg_replace('/%%subscr_cid%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['subscr_cid']), $code)))
301
- if(($code = preg_replace('/%%initial%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['initial']), $code)) && ($code = preg_replace('/%%regular%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['regular']), $code)) && ($code = preg_replace('/%%recurring%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['recurring']), $code)))
302
- if(($code = preg_replace('/%%initial_term%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['initial_term']), $code)) && ($code = preg_replace('/%%regular_term%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['regular_term']), $code)))
303
- if(($code = preg_replace('/%%item_number%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['item_number']), $code)) && ($code = preg_replace('/%%item_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['item_name']), $code)))
304
- if(($code = preg_replace('/%%first_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['first_name']), $code)) && ($code = preg_replace('/%%last_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['last_name']), $code)))
305
- if(($code = preg_replace('/%%full_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(trim($paypal['first_name'].' '.$paypal['last_name'])), $code)))
306
- if(($code = preg_replace('/%%payer_email%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['payer_email']), $code)))
307
- if(($code = preg_replace('/%%user_ip%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['ip']), $code)))
308
-
309
- if(($code = trim(preg_replace('/%%(.+?)%%/i', '', $code))) /* This gets stored into a Transient Queue. */)
310
- {
311
- $paypal['s2member_log'][] = 'Storing Signup Tracking Codes into a Transient Queue. These will be processed on-site.';
312
- set_transient('s2m_'.md5('s2member_transient_signup_tracking_codes_'.$paypal['subscr_id']), $code, 43200);
313
- }
 
314
  }
315
  foreach(array_keys(get_defined_vars()) as $__v) $__refs[$__v] =& $$__v;
316
  do_action('ws_plugin__s2member_during_paypal_return_during_subscr_signup_wo_update_vars', get_defined_vars());
79
 
80
  $paypal['recurring'] = ($tra['rr'] === '1') ? '1' : '0';
81
 
82
+ $paypal['initial_term'] = (preg_match('/^[1-9]/', $paypal['period1'])) ? $paypal['period1'] : '0 D'; // Defaults to '0 D' (zero days).
83
+ $paypal['initial'] = (strlen($paypal['mc_amount1']) && preg_match('/^[1-9]/', $paypal['period1'])) ? $paypal['mc_amount1'] : $paypal['mc_amount3'];
84
+ $paypal['regular'] = $paypal['mc_amount3']; // This is the Regular Payment Amount that is charged to the Customer. Always required by PayPal.
85
+ $paypal['regular_term'] = $paypal['period3']; // This is just set to keep a standard; this way both initial_term & regular_term are available.
86
+ $paypal['recurring'] = ($paypal['recurring']) ? $paypal['mc_amount3'] : '0'; // If non-recurring, this should be zero, otherwise Regular.
87
+ $paypal['currency'] = strtoupper($paypal['mc_currency']); // Normalize input currency.
88
+ $paypal['currency_symbol'] = c_ws_plugin__s2member_utils_cur::symbol($paypal['currency']);
89
+
90
+ $ipn_signup_vars = $paypal; // Copy of PayPal vars; used as IPN signup vars.
91
  unset($ipn_signup_vars['s2member_log']); // Create array of wouldbe IPN signup vars w/o s2member_log.
92
  }
93
  else if(preg_match('/^(web_accept|subscr_signup)$/i', $paypal['txn_type']))
102
  $paypal['period3'] = ($paypal['eotper']) ? $paypal['eotper'] : '1 L'; // 1 Lifetime.
103
  $paypal['mc_amount3'] = $paypal['mc_gross']; // The 'Buy Now' amount is the full gross.
104
  }
105
+ $paypal['initial_term'] = (preg_match('/^[1-9]/', $paypal['period1'])) ? $paypal['period1'] : '0 D'; // Defaults to '0 D' (zero days).
106
+ $paypal['initial'] = (strlen($paypal['mc_amount1']) && preg_match('/^[1-9]/', $paypal['period1'])) ? $paypal['mc_amount1'] : $paypal['mc_amount3'];
107
+ $paypal['regular'] = $paypal['mc_amount3']; // This is the Regular Payment Amount that is charged to the Customer. Always required by PayPal.
108
+ $paypal['regular_term'] = $paypal['period3']; // This is just set to keep a standard; this way both initial_term & regular_term are available.
109
+ $paypal['recurring'] = ($paypal['recurring']) ? $paypal['mc_amount3'] : '0'; // If non-recurring, this should be zero, otherwise Regular.
110
+ $paypal['currency'] = strtoupper($paypal['mc_currency']); // Normalize input currency.
111
+ $paypal['currency_symbol'] = c_ws_plugin__s2member_utils_cur::symbol($paypal['currency']);
112
+
113
+ $ipn_signup_vars = $paypal; // Copy of PayPal vars; used as IPN signup vars.
114
  unset($ipn_signup_vars['s2member_log']); // Create array of wouldbe IPN signup vars w/o s2member_log.
115
  }
116
  else $tracking_properties = FALSE; // Not possible.
203
  {
204
  if(($code = preg_replace('/%%cv([0-9]+)%%/ei', 'trim(@$cv[$1])', $code)) && ($code = preg_replace('/%%subscr_id%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['subscr_id']), $code)))
205
  if(($code = preg_replace('/%%subscr_baid%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['subscr_baid']), $code)) && ($code = preg_replace('/%%subscr_cid%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['subscr_cid']), $code)))
206
+ if(($code = preg_replace('/%%currency%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['currency']), $code)) && ($code = preg_replace('/%%currency_symbol%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['currency_symbol']), $code)))
207
+ if(($code = preg_replace('/%%initial%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['initial']), $code)) && ($code = preg_replace('/%%regular%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['regular']), $code)) && ($code = preg_replace('/%%recurring%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['recurring']), $code)))
208
+ if(($code = preg_replace('/%%initial_term%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['initial_term']), $code)) && ($code = preg_replace('/%%regular_term%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['regular_term']), $code)))
209
+ if(($code = preg_replace('/%%item_number%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['item_number']), $code)) && ($code = preg_replace('/%%item_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['item_name']), $code)))
210
+ if(($code = preg_replace('/%%first_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['first_name']), $code)) && ($code = preg_replace('/%%last_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['last_name']), $code)))
211
+ if(($code = preg_replace('/%%full_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(trim($paypal['first_name'].' '.$paypal['last_name'])), $code)))
212
+ if(($code = preg_replace('/%%payer_email%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['payer_email']), $code)))
213
+ {
214
+ if(($code = preg_replace('/%%user_first_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($user->first_name), $code)) && ($code = preg_replace('/%%user_last_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($user->last_name), $code)))
215
+ if(($code = preg_replace('/%%user_full_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(trim($user->first_name.' '.$user->last_name)), $code)))
216
+ if(($code = preg_replace('/%%user_email%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($user->user_email), $code)))
217
+ if(($code = preg_replace('/%%user_login%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($user->user_login), $code)))
218
+ if(($code = preg_replace('/%%user_ip%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($user_reg_ip), $code)))
219
+ if(($code = preg_replace('/%%user_id%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($user_id), $code)))
 
 
 
 
 
 
220
  {
221
+ if(is_array($fields) && !empty($fields))
222
+ foreach($fields as $var => $val) // Custom Registration/Profile Fields.
223
+ if(!($code = preg_replace('/%%'.preg_quote($var, '/').'%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(maybe_serialize($val)), $code)))
224
+ break;
225
+
226
+ if(($code = trim(preg_replace('/%%(.+?)%%/i', '', $code))) /* This gets stored into a Transient Queue. */)
227
+ {
228
+ $paypal['s2member_log'][] = 'Storing Modification Tracking Codes into a Transient Queue. These will be processed on-site.';
229
+ set_transient('s2m_'.md5('s2member_transient_modification_tracking_codes_'.$paypal['subscr_id']), $code, 43200);
230
+ }
231
  }
232
+ }
 
233
  }
234
  foreach(array_keys(get_defined_vars()) as $__v) $__refs[$__v] =& $$__v;
235
  do_action('ws_plugin__s2member_during_paypal_return_during_subscr_signup_w_update_vars', get_defined_vars());
303
  {
304
  if(($code = preg_replace('/%%cv([0-9]+)%%/ei', 'trim(@$cv[$1])', $code)) && ($code = preg_replace('/%%subscr_id%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['subscr_id']), $code)))
305
  if(($code = preg_replace('/%%subscr_baid%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['subscr_baid']), $code)) && ($code = preg_replace('/%%subscr_cid%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['subscr_cid']), $code)))
306
+ if(($code = preg_replace('/%%currency%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['currency']), $code)) && ($code = preg_replace('/%%currency_symbol%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['currency_symbol']), $code)))
307
+ if(($code = preg_replace('/%%initial%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['initial']), $code)) && ($code = preg_replace('/%%regular%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['regular']), $code)) && ($code = preg_replace('/%%recurring%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['recurring']), $code)))
308
+ if(($code = preg_replace('/%%initial_term%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['initial_term']), $code)) && ($code = preg_replace('/%%regular_term%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['regular_term']), $code)))
309
+ if(($code = preg_replace('/%%item_number%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['item_number']), $code)) && ($code = preg_replace('/%%item_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['item_name']), $code)))
310
+ if(($code = preg_replace('/%%first_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['first_name']), $code)) && ($code = preg_replace('/%%last_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['last_name']), $code)))
311
+ if(($code = preg_replace('/%%full_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(trim($paypal['first_name'].' '.$paypal['last_name'])), $code)))
312
+ if(($code = preg_replace('/%%payer_email%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['payer_email']), $code)))
313
+ if(($code = preg_replace('/%%user_ip%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['ip']), $code)))
314
+
315
+ if(($code = trim(preg_replace('/%%(.+?)%%/i', '', $code))) /* This gets stored into a Transient Queue. */)
316
+ {
317
+ $paypal['s2member_log'][] = 'Storing Signup Tracking Codes into a Transient Queue. These will be processed on-site.';
318
+ set_transient('s2m_'.md5('s2member_transient_signup_tracking_codes_'.$paypal['subscr_id']), $code, 43200);
319
+ }
320
  }
321
  foreach(array_keys(get_defined_vars()) as $__v) $__refs[$__v] =& $$__v;
322
  do_action('ws_plugin__s2member_during_paypal_return_during_subscr_signup_wo_update_vars', get_defined_vars());
includes/classes/paypal-return-in-wa-ccaps-wo-level.inc.php CHANGED
@@ -1,201 +1,207 @@
1
  <?php
2
  /**
3
- * s2Member's PayPal Auto-Return/PDT handler (inner processing routine).
4
- *
5
- * Copyright: © 2009-2011
6
- * {@link http://www.websharks-inc.com/ WebSharks, Inc.}
7
- * (coded in the USA)
8
- *
9
- * Released under the terms of the GNU General Public License.
10
- * You should have received a copy of the GNU General Public License,
11
- * along with this software. In the main directory, see: /licensing/
12
- * If not, see: {@link http://www.gnu.org/licenses/}.
13
- *
14
- * @package s2Member\PayPal
15
- * @since 110720
16
- */
17
- if (realpath (__FILE__) === realpath ($_SERVER["SCRIPT_FILENAME"]))
18
- exit("Do not access this file directly.");
19
-
20
- if (!class_exists ("c_ws_plugin__s2member_paypal_return_in_wa_ccaps_wo_level"))
 
 
 
 
 
 
 
 
21
  {
22
  /**
23
- * s2Member's PayPal Auto-Return/PDT handler (inner processing routine).
24
- *
25
- * @package s2Member\PayPal
26
- * @since 110720
27
- */
28
- class c_ws_plugin__s2member_paypal_return_in_wa_ccaps_wo_level
 
 
 
 
 
 
 
 
 
 
 
 
 
 
29
  {
30
- /**
31
- * s2Member's PayPal Auto-Return/PDT handler (inner processing routine).
32
- *
33
- * @package s2Member\PayPal
34
- * @since 110720
35
- *
36
- * @param array $vars Required. An array of defined variables passed by {@link s2Member\PayPal\c_ws_plugin__s2member_paypal_return_in::paypal_return()}.
37
- * @return array|bool The original ``$paypal`` array passed in (extracted) from ``$vars``, or false when conditions do NOT apply.
38
- */
39
- public static function /* Conditional phase for ``c_ws_plugin__s2member_paypal_notify_in::paypal_notify()``. */ cp ($vars = array())
 
 
 
 
 
 
 
 
40
  {
41
- extract /* Extract all vars passed in from: ``c_ws_plugin__s2member_paypal_notify_in::paypal_notify()``. */($vars, EXTR_OVERWRITE | EXTR_REFS);
42
-
43
- if ((!empty($paypal["txn_type"]) && preg_match ("/^web_accept$/i", $paypal["txn_type"]))
44
- && (!empty($paypal["item_number"]) && preg_match ($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["membership_item_number_wo_level_regex"], $paypal["item_number"]))
45
- && (empty($paypal["payment_status"]) || empty($payment_status_issues) || !preg_match ($payment_status_issues, $paypal["payment_status"]))
46
- && (!empty($paypal["txn_id"])) && (!empty($paypal["payer_email"]))
47
- && (!empty($paypal["txn_baid"]) || ($paypal["txn_baid"] = $paypal["txn_id"]))
48
- && (!empty($paypal["txn_cid"]) || ($paypal["txn_cid"] = $paypal["txn_id"])))
49
  {
50
- foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;
51
- do_action("ws_plugin__s2member_during_paypal_return_before_new_ccaps", get_defined_vars ());
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
52
  unset($__refs, $__v);
53
 
54
- if (!get_transient ($transient_rtn = "s2m_rtn_" . md5 ("s2member_transient_" . $_paypal_s)) && set_transient ($transient_rtn, time (), 31556926 * 10))
55
- {
56
- $paypal["s2member_log"][] = "s2Member `txn_type` identified as ( `web_accept` ) w/ update vars for Capabilities w/o Level.";
57
-
58
- list ($paypal["level"], $paypal["ccaps"], $paypal["eotper"]) = preg_split ("/\:/", $paypal["item_number"], 3);
59
-
60
- $paypal["ip"] = (preg_match ("/ip address/i", $paypal["option_name2"]) && $paypal["option_selection2"]) ? $paypal["option_selection2"] : "";
61
- $paypal["ip"] = (!$paypal["ip"] && preg_match ("/^[a-z0-9]+~[0-9\.]+$/i", $paypal["invoice"])) ? preg_replace ("/^[a-z0-9]+~/i", "", $paypal["invoice"]) : $paypal["ip"];
62
- $paypal["ip"] = (!$paypal["ip"] && $_SERVER["REMOTE_ADDR"]) ? $_SERVER["REMOTE_ADDR"] : $paypal["ip"];
63
-
64
- if /* Must have this information for Capability additions. */ (preg_match ("/(referenc|associat|updat|upgrad)/i", $paypal["option_name1"]) && $paypal["option_selection1"])
65
- {
66
- if (($user_id = c_ws_plugin__s2member_utils_users::get_user_id_with ($paypal["txn_id"], $paypal["option_selection1"])) && is_object ($user = new WP_User ($user_id)) && $user->ID)
67
- {
68
- if /* Do NOT process this routine on Administrators. */ (!$user->has_cap ("administrator"))
69
- {
70
- $processing = $during = /* Yes, we ARE processing this. */ true;
71
-
72
- $fields = /* These will be needed in the routines below. */ get_user_option ("s2member_custom_fields", $user_id);
73
- $user_reg_ip = /* Original IP during Registration. */ get_user_option ("s2member_registration_ip", $user_id);
74
- $user_reg_ip = $paypal["ip"] = /* Now merge conditionally. */ ($user_reg_ip) ? $user_reg_ip : $paypal["ip"];
75
-
76
- if (is_multisite () && !is_user_member_of_blog ($user_id) /* Must have a Role on this Blog. */)
77
- {
78
- add_existing_user_to_blog(array("user_id" => $user_id, "role" => get_option ("default_role")));
79
- $user = new WP_User ($user_id);
80
- }
81
- if ($paypal["ccaps"] && preg_match ("/^-all/", str_replace ("+", "", $paypal["ccaps"])))
82
- foreach ($user->allcaps as $cap => $cap_enabled)
83
- if (preg_match ("/^access_s2member_ccap_/", $cap))
84
- $user->remove_cap ($ccap = $cap);
85
-
86
- if ($paypal["ccaps"] && preg_replace ("/^-all[\r\n\t\s;,]*/", "", str_replace ("+", "", $paypal["ccaps"])))
87
- foreach (preg_split ("/[\r\n\t\s;,]+/", preg_replace ("/^-all[\r\n\t\s;,]*/", "", str_replace ("+", "", $paypal["ccaps"]))) as $ccap)
88
- if (strlen ($ccap = trim (strtolower (preg_replace ("/[^a-z_0-9]/i", "", $ccap)))))
89
- $user->add_cap ("access_s2member_ccap_" . $ccap);
90
-
91
- if (!get_user_option ("s2member_registration_ip", $user_id))
92
- update_user_option ($user_id, "s2member_registration_ip", $paypal["ip"]);
93
-
94
- $paypal["s2member_log"][] = "s2Member Custom Capabilities updated w/ advanced update routines.";
95
-
96
- setcookie ("s2member_tracking", ($s2member_tracking = c_ws_plugin__s2member_utils_encryption::encrypt ($paypal["txn_id"])), time () + 31556926, COOKIEPATH, COOKIE_DOMAIN) . setcookie ("s2member_tracking", $s2member_tracking, time () + 31556926, SITECOOKIEPATH, COOKIE_DOMAIN) . ($_COOKIE["s2member_tracking"] = $s2member_tracking);
97
-
98
- $paypal["s2member_log"][] = "Transient Tracking Cookie set on ( `web_accept` ) w/ update vars for Capabilities w/o Level.";
99
-
100
- if ($processing && ($code = $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["ccap_tracking_codes"]) && is_array($cv = preg_split ("/\|/", $paypal["custom"])))
101
- {
102
- if (($code = preg_replace ("/%%cv([0-9]+)%%/ei", 'trim(@$cv[$1])', $code)) && ($code = preg_replace ("/%%(?:subscr|txn)_id%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($paypal["txn_id"]), $code)))
103
- if (($code = preg_replace ("/%%(?:subscr|txn)_baid%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($paypal["txn_baid"]), $code)) && ($code = preg_replace ("/%%(?:subscr|txn)_cid%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($paypal["txn_cid"]), $code)))
104
- if (($code = preg_replace ("/%%amount%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($paypal["mc_gross"]), $code)) && ($code = preg_replace ("/%%txn_id%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($paypal["txn_id"]), $code)))
105
- if (($code = preg_replace ("/%%item_number%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($paypal["item_number"]), $code)) && ($code = preg_replace ("/%%item_name%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($paypal["item_name"]), $code)))
106
- if (($code = preg_replace ("/%%first_name%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($paypal["first_name"]), $code)) && ($code = preg_replace ("/%%last_name%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($paypal["last_name"]), $code)))
107
- if (($code = preg_replace ("/%%full_name%%/i", c_ws_plugin__s2member_utils_strings::esc_refs (trim ($paypal["first_name"] . " " . $paypal["last_name"])), $code)))
108
- if (($code = preg_replace ("/%%payer_email%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($paypal["payer_email"]), $code)))
109
- {
110
- if (($code = preg_replace ("/%%user_first_name%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($user->first_name), $code)) && ($code = preg_replace ("/%%user_last_name%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($user->last_name), $code)))
111
- if (($code = preg_replace ("/%%user_full_name%%/i", c_ws_plugin__s2member_utils_strings::esc_refs (trim ($user->first_name . " " . $user->last_name)), $code)))
112
- if (($code = preg_replace ("/%%user_email%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($user->user_email), $code)))
113
- if (($code = preg_replace ("/%%user_login%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($user->user_login), $code)))
114
- if (($code = preg_replace ("/%%user_ip%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($user_reg_ip), $code)))
115
- if (($code = preg_replace ("/%%user_id%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($user_id), $code)))
116
- {
117
- if (is_array($fields) && !empty($fields))
118
- foreach /* Custom Registration/Profile Fields. */ ($fields as $var => $val)
119
- if (!($code = preg_replace ("/%%" . preg_quote ($var, "/") . "%%/i", c_ws_plugin__s2member_utils_strings::esc_refs (maybe_serialize ($val)), $code)))
120
- break;
121
-
122
- if (($code = trim (preg_replace ("/%%(.+?)%%/i", "", $code))) /* This gets stored into a Transient Queue. */)
123
- {
124
- $paypal["s2member_log"][] = "Storing Payment Tracking Codes into a Transient Queue. These will be processed on-site.";
125
- set_transient ("s2m_" . md5 ("s2member_transient_ccap_tracking_codes_" . $paypal["txn_id"]), $code, 43200);
126
- }
127
- }
128
- }
129
- }
130
- foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;
131
- do_action("ws_plugin__s2member_during_paypal_return_during_new_ccaps", get_defined_vars ());
132
- unset($__refs, $__v);
133
-
134
- if (($redirection_url_after_capabilities = apply_filters("ws_plugin__s2member_redirection_url_after_capabilities", false, get_defined_vars ())))
135
- {
136
- $paypal["s2member_log"][] = "Redirecting Customer to a custom URL after Capabilities: " . $redirection_url_after_capabilities;
137
-
138
- wp_redirect($redirection_url_after_capabilities);
139
- }
140
- else // Else, use standard/default handling in this scenario. Have the Customer log in again.
141
- {
142
- $paypal["s2member_log"][] = "Redirecting Customer to the Login Page (after displaying a quick thank-you message). They need to log back in.";
143
-
144
- echo c_ws_plugin__s2member_return_templates::return_template ($paypal["subscr_gateway"],
145
- '<strong>' . _x ("Thank you! You now have access to:", "s2member-front", "s2member") . '<br /><em>' . esc_html ($paypal["item_name"]) . '</em></strong>',
146
- _x ("Please Log Back In (Click Here)", "s2member-front", "s2member"), wp_login_url ());
147
- }
148
- }
149
- else // Unable to add new Capabilities. The existing User ID is associated with an Administrator. Stopping here.
150
- {
151
- $paypal["s2member_log"][] = "Unable to add new Capabilities. The existing User ID is associated with an Administrator. Stopping here. Otherwise, an Administrator could lose access. Please make sure that you are NOT logged in as an Administrator while testing.";
152
-
153
- $paypal["s2member_log"][] = "Redirecting Customer to the Home Page (after displaying an error message).";
154
-
155
- echo c_ws_plugin__s2member_return_templates::return_template ($paypal["subscr_gateway"],
156
- _x ('<strong>ERROR:</strong> Unable to add new Capabilities.<br />Please contact Support for assistance.<br /><br />The existing User ID is associated with an Administrator. Stopping here. Otherwise, an Administrator could lose access. Please make sure that you are NOT logged in as an Administrator while testing.', "s2member-front", "s2member"),
157
- _x ("Back To Home Page", "s2member-front", "s2member"), home_url ("/"));
158
- }
159
- }
160
- else // Unable to add new Capabilities. Could not get the existing User ID from the DB.
161
- {
162
- $paypal["s2member_log"][] = "Unable to add new Capabilities. Could not get the existing User ID from the DB.";
163
-
164
- $paypal["s2member_log"][] = "Redirecting Customer to the Home Page (after displaying an error message).";
165
-
166
- echo c_ws_plugin__s2member_return_templates::return_template ($paypal["subscr_gateway"],
167
- _x ('<strong>ERROR:</strong> Unable to add new Capabilities.<br />Please contact Support for assistance.<br /><br />Could not get the existing User ID from the DB.', "s2member-front", "s2member"),
168
- _x ("Back To Home Page", "s2member-front", "s2member"), home_url ("/"));
169
- }
170
- }
171
- else // Unable to add new Capabilities. Missing User/Member details.
172
- {
173
- $paypal["s2member_log"][] = "Unable to add new Capabilities. Missing User/Member details. Please check the `on0` and `os0` variables in your Button Code.";
174
-
175
- $paypal["s2member_log"][] = "Redirecting Customer to the Home Page (after displaying an error message).";
176
-
177
- echo c_ws_plugin__s2member_return_templates::return_template ($paypal["subscr_gateway"],
178
- _x ('<strong>ERROR:</strong> Unable to add new Capabilities.<br />Please contact Support for assistance.<br /><br />Missing User/Member details.', "s2member-front", "s2member"),
179
- _x ("Back To Home Page", "s2member-front", "s2member"), home_url ("/"));
180
- }
181
- }
182
- else // Page Expired. Duplicate Return-Data.
183
- {
184
- $paypal["s2member_log"][] = "Page Expired. Duplicate Return-Data.";
185
- $paypal["s2member_log"][] = "s2Member `txn_type` identified as ( `web_accept` ) w/ update vars for Capabilities w/o Level.";
186
- $paypal['s2member_log'][] = 'Page Expired. Instructing customer to check their email for further details about how to obtain access to what they purchased.';
187
-
188
- echo c_ws_plugin__s2member_return_templates::return_template($paypal['subscr_gateway'],
189
- '<strong>'._x('Thank you! Please check your email for further details regarding your purchase.', 's2member-front', 's2member').'</strong>',
190
- _x('Return to Home Page', 's2member-front', 's2member'), home_url("/"));
191
- }
192
- foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;
193
- do_action("ws_plugin__s2member_during_paypal_return_after_new_ccaps", get_defined_vars ());
194
- unset($__refs, $__v);
195
 
196
- return apply_filters("c_ws_plugin__s2member_paypal_return_in_wa_ccaps_wo_level", $paypal, get_defined_vars ());
 
 
197
  }
198
- else return apply_filters("c_ws_plugin__s2member_paypal_return_in_wa_ccaps_wo_level", false, get_defined_vars ());
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
199
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
200
  }
201
- }
 
 
 
1
  <?php
2
  /**
3
+ * s2Member's PayPal Auto-Return/PDT handler (inner processing routine).
4
+ *
5
+ * Copyright: © 2009-2011
6
+ * {@link http://www.websharks-inc.com/ WebSharks, Inc.}
7
+ * (coded in the USA)
8
+ *
9
+ * Released under the terms of the GNU General Public License.
10
+ * You should have received a copy of the GNU General Public License,
11
+ * along with this software. In the main directory, see: /licensing/
12
+ * If not, see: {@link http://www.gnu.org/licenses/}.
13
+ *
14
+ * @package s2Member\PayPal
15
+ * @since 110720
16
+ */
17
+ if(realpath(__FILE__) === realpath($_SERVER['SCRIPT_FILENAME']))
18
+ exit('Do not access this file directly.');
19
+
20
+ if(!class_exists('c_ws_plugin__s2member_paypal_return_in_wa_ccaps_wo_level'))
21
+ {
22
+ /**
23
+ * s2Member's PayPal Auto-Return/PDT handler (inner processing routine).
24
+ *
25
+ * @package s2Member\PayPal
26
+ * @since 110720
27
+ */
28
+ class c_ws_plugin__s2member_paypal_return_in_wa_ccaps_wo_level
29
  {
30
  /**
31
+ * s2Member's PayPal Auto-Return/PDT handler (inner processing routine).
32
+ *
33
+ * @package s2Member\PayPal
34
+ * @since 110720
35
+ *
36
+ * @param array $vars Required. An array of defined variables passed by {@link s2Member\PayPal\c_ws_plugin__s2member_paypal_return_in::paypal_return()}.
37
+ *
38
+ * @return array|bool The original ``$paypal`` array passed in (extracted) from ``$vars``, or false when conditions do NOT apply.
39
+ */
40
+ public static function cp($vars = array() /* Conditional phase for ``c_ws_plugin__s2member_paypal_notify_in::paypal_notify()``. */)
41
+ {
42
+ extract($vars, EXTR_OVERWRITE | EXTR_REFS /* Extract all vars passed in from: ``c_ws_plugin__s2member_paypal_notify_in::paypal_notify()``. */);
43
+
44
+ if((!empty($paypal['txn_type']) && preg_match('/^web_accept$/i', $paypal['txn_type']))
45
+ && (!empty($paypal['item_number']) && preg_match($GLOBALS['WS_PLUGIN__']['s2member']['c']['membership_item_number_wo_level_regex'], $paypal['item_number']))
46
+ && (empty($paypal['payment_status']) || empty($payment_status_issues) || !preg_match($payment_status_issues, $paypal['payment_status']))
47
+ && (!empty($paypal['txn_id'])) && (!empty($paypal['payer_email']))
48
+ && (!empty($paypal['txn_baid']) || ($paypal['txn_baid'] = $paypal['txn_id']))
49
+ && (!empty($paypal['txn_cid']) || ($paypal['txn_cid'] = $paypal['txn_id']))
50
+ )
51
  {
52
+ foreach(array_keys(get_defined_vars()) as $__v) $__refs[$__v] =& $$__v;
53
+ do_action('ws_plugin__s2member_during_paypal_return_before_new_ccaps', get_defined_vars());
54
+ unset($__refs, $__v);
55
+
56
+ if(!get_transient($transient_rtn = 's2m_rtn_'.md5('s2member_transient_'.$_paypal_s)) && set_transient($transient_rtn, time(), 31556926 * 10))
57
+ {
58
+ $paypal['s2member_log'][] = 's2Member `txn_type` identified as ( `web_accept` ) w/ update vars for Capabilities w/o Level.';
59
+
60
+ list ($paypal['level'], $paypal['ccaps'], $paypal['eotper']) = preg_split('/\:/', $paypal['item_number'], 3);
61
+
62
+ $paypal['ip'] = (preg_match('/ip address/i', $paypal['option_name2']) && $paypal['option_selection2']) ? $paypal['option_selection2'] : '';
63
+ $paypal['ip'] = (!$paypal['ip'] && preg_match('/^[a-z0-9]+~[0-9\.]+$/i', $paypal['invoice'])) ? preg_replace('/^[a-z0-9]+~/i', '', $paypal['invoice']) : $paypal['ip'];
64
+ $paypal['ip'] = (!$paypal['ip'] && $_SERVER['REMOTE_ADDR']) ? $_SERVER['REMOTE_ADDR'] : $paypal['ip'];
65
+
66
+ $paypal['currency'] = strtoupper($paypal['mc_currency']); // Normalize input currency.
67
+ $paypal['currency_symbol'] = c_ws_plugin__s2member_utils_cur::symbol($paypal['currency']);
68
+
69
+ if(preg_match('/(referenc|associat|updat|upgrad)/i', $paypal['option_name1']) && $paypal['option_selection1'] /* Must have this information for Capability additions. */)
70
  {
71
+ if(($user_id = c_ws_plugin__s2member_utils_users::get_user_id_with($paypal['txn_id'], $paypal['option_selection1'])) && is_object($user = new WP_User ($user_id)) && $user->ID)
72
+ {
73
+ if(!$user->has_cap('administrator') /* Do NOT process this routine on Administrators. */)
 
 
 
 
 
74
  {
75
+ $processing = $during = TRUE; // Yes, we ARE processing this.
76
+
77
+ $fields = get_user_option('s2member_custom_fields', $user_id); // These will be needed in the routines below.
78
+ $user_reg_ip = get_user_option('s2member_registration_ip', $user_id); // Original IP during Registration.
79
+ $user_reg_ip = $paypal['ip'] = ($user_reg_ip) ? $user_reg_ip : $paypal['ip']; // Now merge conditionally.
80
+
81
+ if(is_multisite() && !is_user_member_of_blog($user_id) /* Must have a Role on this Blog. */)
82
+ {
83
+ add_existing_user_to_blog(array('user_id' => $user_id, 'role' => get_option('default_role')));
84
+ $user = new WP_User ($user_id);
85
+ }
86
+ if($paypal['ccaps'] && preg_match('/^-all/', str_replace('+', '', $paypal['ccaps'])))
87
+ foreach($user->allcaps as $cap => $cap_enabled)
88
+ if(preg_match('/^access_s2member_ccap_/', $cap))
89
+ $user->remove_cap($ccap = $cap);
90
+
91
+ if($paypal['ccaps'] && preg_replace('/^-all['."\r\n\t".'\s;,]*/', '', str_replace('+', '', $paypal['ccaps'])))
92
+ foreach(preg_split('/['."\r\n\t".'\s;,]+/', preg_replace('/^-all['."\r\n\t".'\s;,]*/', '', str_replace('+', '', $paypal['ccaps']))) as $ccap)
93
+ if(strlen($ccap = trim(strtolower(preg_replace('/[^a-z_0-9]/i', '', $ccap)))))
94
+ $user->add_cap('access_s2member_ccap_'.$ccap);
95
+
96
+ if(!get_user_option('s2member_registration_ip', $user_id))
97
+ update_user_option($user_id, 's2member_registration_ip', $paypal['ip']);
98
+
99
+ $paypal['s2member_log'][] = 's2Member Custom Capabilities updated w/ advanced update routines.';
100
+
101
+ setcookie('s2member_tracking', ($s2member_tracking = c_ws_plugin__s2member_utils_encryption::encrypt($paypal['txn_id'])), time() + 31556926, COOKIEPATH, COOKIE_DOMAIN).setcookie('s2member_tracking', $s2member_tracking, time() + 31556926, SITECOOKIEPATH, COOKIE_DOMAIN).($_COOKIE['s2member_tracking'] = $s2member_tracking);
102
+
103
+ $paypal['s2member_log'][] = 'Transient Tracking Cookie set on ( `web_accept` ) w/ update vars for Capabilities w/o Level.';
104
+
105
+ if($processing && ($code = $GLOBALS['WS_PLUGIN__']['s2member']['o']['ccap_tracking_codes']) && is_array($cv = preg_split('/\|/', $paypal['custom'])))
106
+ {
107
+ if(($code = preg_replace('/%%cv([0-9]+)%%/ei', 'trim(@$cv[$1])', $code)) && ($code = preg_replace('/%%(?:subscr|txn)_id%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['txn_id']), $code)))
108
+ if(($code = preg_replace('/%%(?:subscr|txn)_baid%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['txn_baid']), $code)) && ($code = preg_replace('/%%(?:subscr|txn)_cid%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['txn_cid']), $code)))
109
+ if(($code = preg_replace('/%%currency%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['currency']), $code)) && ($code = preg_replace('/%%currency_symbol%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['currency_symbol']), $code)))
110
+ if(($code = preg_replace('/%%amount%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['mc_gross']), $code)) && ($code = preg_replace('/%%txn_id%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['txn_id']), $code)))
111
+ if(($code = preg_replace('/%%item_number%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['item_number']), $code)) && ($code = preg_replace('/%%item_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['item_name']), $code)))
112
+ if(($code = preg_replace('/%%first_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['first_name']), $code)) && ($code = preg_replace('/%%last_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['last_name']), $code)))
113
+ if(($code = preg_replace('/%%full_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(trim($paypal['first_name'].' '.$paypal['last_name'])), $code)))
114
+ if(($code = preg_replace('/%%payer_email%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['payer_email']), $code)))
115
+ {
116
+ if(($code = preg_replace('/%%user_first_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($user->first_name), $code)) && ($code = preg_replace('/%%user_last_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($user->last_name), $code)))
117
+ if(($code = preg_replace('/%%user_full_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(trim($user->first_name.' '.$user->last_name)), $code)))
118
+ if(($code = preg_replace('/%%user_email%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($user->user_email), $code)))
119
+ if(($code = preg_replace('/%%user_login%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($user->user_login), $code)))
120
+ if(($code = preg_replace('/%%user_ip%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($user_reg_ip), $code)))
121
+ if(($code = preg_replace('/%%user_id%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($user_id), $code)))
122
+ {
123
+ if(is_array($fields) && !empty($fields))
124
+ foreach($fields as $var => $val /* Custom Registration/Profile Fields. */)
125
+ if(!($code = preg_replace('/%%'.preg_quote($var, '/').'%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(maybe_serialize($val)), $code)))
126
+ break;
127
+
128
+ if(($code = trim(preg_replace('/%%(.+?)%%/i', '', $code))) /* This gets stored into a Transient Queue. */)
129
+ {
130
+ $paypal['s2member_log'][] = 'Storing Payment Tracking Codes into a Transient Queue. These will be processed on-site.';
131
+ set_transient('s2m_'.md5('s2member_transient_ccap_tracking_codes_'.$paypal['txn_id']), $code, 43200);
132
+ }
133
+ }
134
+ }
135
+ }
136
+ foreach(array_keys(get_defined_vars()) as $__v) $__refs[$__v] =& $$__v;
137
+ do_action('ws_plugin__s2member_during_paypal_return_during_new_ccaps', get_defined_vars());
138
  unset($__refs, $__v);
139
 
140
+ if(($redirection_url_after_capabilities = apply_filters('ws_plugin__s2member_redirection_url_after_capabilities', FALSE, get_defined_vars())))
141
+ {
142
+ $paypal['s2member_log'][] = 'Redirecting Customer to a custom URL after Capabilities: '.$redirection_url_after_capabilities;
143
+
144
+ wp_redirect($redirection_url_after_capabilities);
145
+ }
146
+ else // Else, use standard/default handling in this scenario. Have the Customer log in again.
147
+ {
148
+ $paypal['s2member_log'][] = 'Redirecting Customer to the Login Page (after displaying a quick thank-you message). They need to log back in.';
149
+
150
+ echo c_ws_plugin__s2member_return_templates::return_template($paypal['subscr_gateway'],
151
+ '<strong>'._x('Thank you! You now have access to:', 's2member-front', 's2member').'<br /><em>'.esc_html($paypal['item_name']).'</em></strong>',
152
+ _x('Please Log Back In (Click Here)', 's2member-front', 's2member'), wp_login_url());
153
+ }
154
+ }
155
+ else // Unable to add new Capabilities. The existing User ID is associated with an Administrator. Stopping here.
156
+ {
157
+ $paypal['s2member_log'][] = 'Unable to add new Capabilities. The existing User ID is associated with an Administrator. Stopping here. Otherwise, an Administrator could lose access. Please make sure that you are NOT logged in as an Administrator while testing.';
158
+
159
+ $paypal['s2member_log'][] = 'Redirecting Customer to the Home Page (after displaying an error message).';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
160
 
161
+ echo c_ws_plugin__s2member_return_templates::return_template($paypal['subscr_gateway'],
162
+ _x('<strong>ERROR:</strong> Unable to add new Capabilities.<br />Please contact Support for assistance.<br /><br />The existing User ID is associated with an Administrator. Stopping here. Otherwise, an Administrator could lose access. Please make sure that you are NOT logged in as an Administrator while testing.', 's2member-front', 's2member'),
163
+ _x('Back To Home Page', 's2member-front', 's2member'), home_url('/'));
164
  }
165
+ }
166
+ else // Unable to add new Capabilities. Could not get the existing User ID from the DB.
167
+ {
168
+ $paypal['s2member_log'][] = 'Unable to add new Capabilities. Could not get the existing User ID from the DB.';
169
+
170
+ $paypal['s2member_log'][] = 'Redirecting Customer to the Home Page (after displaying an error message).';
171
+
172
+ echo c_ws_plugin__s2member_return_templates::return_template($paypal['subscr_gateway'],
173
+ _x('<strong>ERROR:</strong> Unable to add new Capabilities.<br />Please contact Support for assistance.<br /><br />Could not get the existing User ID from the DB.', 's2member-front', 's2member'),
174
+ _x('Back To Home Page', 's2member-front', 's2member'), home_url('/'));
175
+ }
176
+ }
177
+ else // Unable to add new Capabilities. Missing User/Member details.
178
+ {
179
+ $paypal['s2member_log'][] = 'Unable to add new Capabilities. Missing User/Member details. Please check the `on0` and `os0` variables in your Button Code.';
180
+
181
+ $paypal['s2member_log'][] = 'Redirecting Customer to the Home Page (after displaying an error message).';
182
+
183
+ echo c_ws_plugin__s2member_return_templates::return_template($paypal['subscr_gateway'],
184
+ _x('<strong>ERROR:</strong> Unable to add new Capabilities.<br />Please contact Support for assistance.<br /><br />Missing User/Member details.', 's2member-front', 's2member'),
185
+ _x('Back To Home Page', 's2member-front', 's2member'), home_url('/'));
186
  }
187
+ }
188
+ else // Page Expired. Duplicate Return-Data.
189
+ {
190
+ $paypal['s2member_log'][] = 'Page Expired. Duplicate Return-Data.';
191
+ $paypal['s2member_log'][] = 's2Member `txn_type` identified as ( `web_accept` ) w/ update vars for Capabilities w/o Level.';
192
+ $paypal['s2member_log'][] = 'Page Expired. Instructing customer to check their email for further details about how to obtain access to what they purchased.';
193
+
194
+ echo c_ws_plugin__s2member_return_templates::return_template($paypal['subscr_gateway'],
195
+ '<strong>'._x('Thank you! Please check your email for further details regarding your purchase.', 's2member-front', 's2member').'</strong>',
196
+ _x('Return to Home Page', 's2member-front', 's2member'), home_url('/'));
197
+ }
198
+ foreach(array_keys(get_defined_vars()) as $__v) $__refs[$__v] =& $$__v;
199
+ do_action('ws_plugin__s2member_during_paypal_return_after_new_ccaps', get_defined_vars());
200
+ unset($__refs, $__v);
201
+
202
+ return apply_filters('c_ws_plugin__s2member_paypal_return_in_wa_ccaps_wo_level', $paypal, get_defined_vars());
203
  }
204
+ else return apply_filters('c_ws_plugin__s2member_paypal_return_in_wa_ccaps_wo_level', FALSE, get_defined_vars());
205
+ }
206
+ }
207
+ }
includes/classes/paypal-return-in-web-accept-sp.inc.php CHANGED
@@ -1,142 +1,148 @@
1
  <?php
2
  /**
3
- * s2Member's PayPal Auto-Return/PDT handler (inner processing routine).
4
- *
5
- * Copyright: © 2009-2011
6
- * {@link http://www.websharks-inc.com/ WebSharks, Inc.}
7
- * (coded in the USA)
8
- *
9
- * Released under the terms of the GNU General Public License.
10
- * You should have received a copy of the GNU General Public License,
11
- * along with this software. In the main directory, see: /licensing/
12
- * If not, see: {@link http://www.gnu.org/licenses/}.
13
- *
14
- * @package s2Member\PayPal
15
- * @since 110720
16
- */
17
- if (realpath (__FILE__) === realpath ($_SERVER["SCRIPT_FILENAME"]))
18
- exit("Do not access this file directly.");
19
-
20
- if (!class_exists ("c_ws_plugin__s2member_paypal_return_in_web_accept_sp"))
 
 
 
 
 
 
 
 
21
  {
22
  /**
23
- * s2Member's PayPal Auto-Return/PDT handler (inner processing routine).
24
- *
25
- * @package s2Member\PayPal
26
- * @since 110720
27
- */
28
- class c_ws_plugin__s2member_paypal_return_in_web_accept_sp
 
 
 
 
 
 
 
 
 
 
 
 
 
29
  {
30
- /**
31
- * s2Member's PayPal Auto-Return/PDT handler (inner processing routine).
32
- *
33
- * @package s2Member\PayPal
34
- * @since 110720
35
- *
36
- * @param array $vars Required. An array of defined variables passed by {@link s2Member\PayPal\c_ws_plugin__s2member_paypal_return_in::paypal_return()}.
37
- * @return array|bool The original ``$paypal`` array passed in (extracted) from ``$vars``, or false when conditions do NOT apply.
38
- */
39
- public static function /* Conditional phase for ``c_ws_plugin__s2member_paypal_notify_in::paypal_notify()``. */ cp ($vars = array())
 
 
 
 
 
 
 
 
40
  {
41
- extract /* Extract all vars passed in from: ``c_ws_plugin__s2member_paypal_notify_in::paypal_notify()``. */($vars, EXTR_OVERWRITE | EXTR_REFS);
42
-
43
- if ((!empty($paypal["txn_type"]) && preg_match ("/^web_accept$/i", $paypal["txn_type"]))
44
- && (!empty($paypal["item_number"]) && preg_match ($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["sp_access_item_number_regex"], $paypal["item_number"]))
45
- && (empty($paypal["payment_status"]) || empty($payment_status_issues) || !preg_match ($payment_status_issues, $paypal["payment_status"]))
46
- && (!empty($paypal["txn_id"])) && (!empty($paypal["txn_baid"]) || ($paypal["txn_baid"] = $paypal["txn_id"]))
47
- && (!empty($paypal["txn_cid"]) || ($paypal["txn_cid"] = $paypal["txn_id"])))
48
- {
49
- foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;
50
- do_action("ws_plugin__s2member_during_paypal_return_before_sp_access", get_defined_vars ());
51
- unset($__refs, $__v);
52
-
53
- if (!get_transient ($transient_rtn = "s2m_rtn_" . md5 ("s2member_transient_" . $_paypal_s)) && set_transient ($transient_rtn, time (), 31556926 * 10))
54
- {
55
- $paypal["s2member_log"][] = "s2Member `txn_type` identified as ( `web_accept` ) for Specific Post/Page Access.";
56
-
57
- list (, $paypal["sp_ids"], $paypal["hours"]) = preg_split ("/\:/", $paypal["item_number"], 3);
58
-
59
- $paypal["ip"] = (preg_match ("/ip address/i", $paypal["option_name2"]) && $paypal["option_selection2"]) ? $paypal["option_selection2"] : "";
60
- $paypal["ip"] = (!$paypal["ip"] && preg_match ("/^[a-z0-9]+~[0-9\.]+$/i", $paypal["invoice"])) ? preg_replace ("/^[a-z0-9]+~/i", "", $paypal["invoice"]) : $paypal["ip"];
61
- $paypal["ip"] = (!$paypal["ip"] && $_SERVER["REMOTE_ADDR"]) ? $_SERVER["REMOTE_ADDR"] : $paypal["ip"];
62
-
63
- if (($sp_access_url = c_ws_plugin__s2member_sp_access::sp_access_link_gen ($paypal["sp_ids"], $paypal["hours"], false)))
64
- {
65
- $processing = $during = /* Yes, we ARE processing this. */ true;
66
-
67
- setcookie ("s2member_sp_tracking", ($s2member_sp_tracking = c_ws_plugin__s2member_utils_encryption::encrypt ($paypal["txn_id"])), time () + 31556926, COOKIEPATH, COOKIE_DOMAIN) . setcookie ("s2member_sp_tracking", $s2member_sp_tracking, time () + 31556926, SITECOOKIEPATH, COOKIE_DOMAIN) . ($_COOKIE["s2member_sp_tracking"] = $s2member_sp_tracking);
68
-
69
- $paypal["s2member_log"][] = "Transient Tracking Cookie set on ( `web_accept` ) for Specific Post/Page Access.";
70
-
71
- if ($processing && ($code = $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["sp_tracking_codes"]) && is_array($cv = preg_split ("/\|/", $paypal["custom"])))
72
- {
73
- if (($code = preg_replace ("/%%cv([0-9]+)%%/ei", 'trim(@$cv[$1])', $code)) && ($code = preg_replace ("/%%amount%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($paypal["mc_gross"]), $code)) && ($code = preg_replace ("/%%txn_id%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($paypal["txn_id"]), $code)))
74
- if (($code = preg_replace ("/%%txn_baid%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($paypal["txn_baid"]), $code)) && ($code = preg_replace ("/%%txn_cid%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($paypal["txn_cid"]), $code)))
75
- if (($code = preg_replace ("/%%item_number%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($paypal["item_number"]), $code)) && ($code = preg_replace ("/%%item_name%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($paypal["item_name"]), $code)))
76
- if (($code = preg_replace ("/%%first_name%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($paypal["first_name"]), $code)) && ($code = preg_replace ("/%%last_name%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($paypal["last_name"]), $code)))
77
- if (($code = preg_replace ("/%%full_name%%/i", c_ws_plugin__s2member_utils_strings::esc_refs (trim ($paypal["first_name"] . " " . $paypal["last_name"])), $code)))
78
- if (($code = preg_replace ("/%%payer_email%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($paypal["payer_email"]), $code)))
79
- if (($code = preg_replace ("/%%user_ip%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($paypal["ip"]), $code)))
80
-
81
- if (($code = trim (preg_replace ("/%%(.+?)%%/i", "", $code)))) // This gets stored into a Transient Queue.
82
- {
83
- $paypal["s2member_log"][] = "Storing Specific Post/Page Tracking Codes into a Transient Queue. These will be processed on-site.";
84
- set_transient ("s2m_" . md5 ("s2member_transient_sp_tracking_codes_" . $paypal["txn_id"]), $code, 43200);
85
- }
86
- }
87
- foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;
88
- do_action("ws_plugin__s2member_during_paypal_return_during_sp_access", get_defined_vars ());
89
- unset($__refs, $__v);
90
-
91
- if (apply_filters("ws_plugin__s2member_immediate_sp_access_redirection", false, get_defined_vars ()))
92
- {
93
- $paypal["s2member_log"][] = "Redirecting Customer immediately to the Specific Post/Page.";
94
-
95
- wp_redirect /* Immediate redirection to Specific Post/Page. */($sp_access_url);
96
- }
97
- else if /* Using a custom success redirection URL? */ ($custom_success_redirection)
98
- {
99
- $paypal["s2member_log"][] = "Redirecting Customer to a custom URL on success: " . $custom_success_redirection;
100
-
101
- wp_redirect($custom_success_redirection);
102
- }
103
- else // Else use the default return URL in this scenario, which is the Specific Post/Page.
104
- {
105
- $paypal["s2member_log"][] = "Redirecting Customer to the Specific Post/Page (after displaying a thank-you message).";
106
-
107
- echo c_ws_plugin__s2member_return_templates::return_template ($paypal["subscr_gateway"],
108
- _x ('<strong>Thank You! Your transaction has been approved.</strong>', "s2member-front", "s2member"),
109
- _x ("Continue (Click Here)", "s2member-front", "s2member"), $sp_access_url);
110
- }
111
- }
112
- else // Otherwise, the ID must have been invalid. Or the Post/Page was deleted.
113
- {
114
- $paypal["s2member_log"][] = "Unable to generate Specific Post/Page Access Link. Does your Leading Post/Page still exist?";
115
-
116
- $paypal["s2member_log"][] = "Redirecting Customer to the Home Page (after displaying an error message).";
117
-
118
- echo c_ws_plugin__s2member_return_templates::return_template ($paypal["subscr_gateway"],
119
- _x ('<strong>ERROR:</strong> Unable to generate Access Link.<br />Please contact Support for assistance.', "s2member-front", "s2member"),
120
- _x ("Back To Home Page", "s2member-front", "s2member"), home_url ("/"));
121
- }
122
- }
123
- else // Page Expired. Duplicate Return-Data.
124
- {
125
- $paypal["s2member_log"][] = "Page Expired. Duplicate Return-Data.";
126
- $paypal["s2member_log"][] = "s2Member `txn_type` identified as ( `web_accept` ) for Specific Post/Page Access.";
127
- $paypal['s2member_log'][] = 'Page Expired. Instructing customer to check their email for further details about how to obtain access to what they purchased.';
128
-
129
- echo c_ws_plugin__s2member_return_templates::return_template($paypal['subscr_gateway'],
130
- '<strong>'._x('Thank you! Please check your email for further details regarding your purchase.', 's2member-front', 's2member').'</strong>',
131
- _x('Return to Home Page', 's2member-front', 's2member'), home_url("/"));
132
- }
133
- foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;
134
- do_action("ws_plugin__s2member_during_paypal_return_after_sp_access", get_defined_vars ());
135
- unset($__refs, $__v);
136
-
137
- return apply_filters("c_ws_plugin__s2member_paypal_return_in_web_accept_sp", $paypal, get_defined_vars ());
138
- }
139
- else return apply_filters("c_ws_plugin__s2member_paypal_return_in_web_accept_sp", false, get_defined_vars ());
140
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
141
  }
142
- }
 
 
 
1
  <?php
2
  /**
3
+ * s2Member's PayPal Auto-Return/PDT handler (inner processing routine).
4
+ *
5
+ * Copyright: © 2009-2011
6
+ * {@link http://www.websharks-inc.com/ WebSharks, Inc.}
7
+ * (coded in the USA)
8
+ *
9
+ * Released under the terms of the GNU General Public License.
10
+ * You should have received a copy of the GNU General Public License,
11
+ * along with this software. In the main directory, see: /licensing/
12
+ * If not, see: {@link http://www.gnu.org/licenses/}.
13
+ *
14
+ * @package s2Member\PayPal
15
+ * @since 110720
16
+ */
17
+ if(realpath(__FILE__) === realpath($_SERVER['SCRIPT_FILENAME']))
18
+ exit('Do not access this file directly.');
19
+
20
+ if(!class_exists('c_ws_plugin__s2member_paypal_return_in_web_accept_sp'))
21
+ {
22
+ /**
23
+ * s2Member's PayPal Auto-Return/PDT handler (inner processing routine).
24
+ *
25
+ * @package s2Member\PayPal
26
+ * @since 110720
27
+ */
28
+ class c_ws_plugin__s2member_paypal_return_in_web_accept_sp
29
  {
30
  /**
31
+ * s2Member's PayPal Auto-Return/PDT handler (inner processing routine).
32
+ *
33
+ * @package s2Member\PayPal
34
+ * @since 110720
35
+ *
36
+ * @param array $vars Required. An array of defined variables passed by {@link s2Member\PayPal\c_ws_plugin__s2member_paypal_return_in::paypal_return()}.
37
+ *
38
+ * @return array|bool The original ``$paypal`` array passed in (extracted) from ``$vars``, or false when conditions do NOT apply.
39
+ */
40
+ public static function cp($vars = array() /* Conditional phase for ``c_ws_plugin__s2member_paypal_notify_in::paypal_notify()``. */)
41
+ {
42
+ extract($vars, EXTR_OVERWRITE | EXTR_REFS /* Extract all vars passed in from: ``c_ws_plugin__s2member_paypal_notify_in::paypal_notify()``. */);
43
+
44
+ if((!empty($paypal['txn_type']) && preg_match('/^web_accept$/i', $paypal['txn_type']))
45
+ && (!empty($paypal['item_number']) && preg_match($GLOBALS['WS_PLUGIN__']['s2member']['c']['sp_access_item_number_regex'], $paypal['item_number']))
46
+ && (empty($paypal['payment_status']) || empty($payment_status_issues) || !preg_match($payment_status_issues, $paypal['payment_status']))
47
+ && (!empty($paypal['txn_id'])) && (!empty($paypal['txn_baid']) || ($paypal['txn_baid'] = $paypal['txn_id']))
48
+ && (!empty($paypal['txn_cid']) || ($paypal['txn_cid'] = $paypal['txn_id']))
49
+ )
50
  {
51
+ foreach(array_keys(get_defined_vars()) as $__v) $__refs[$__v] =& $$__v;
52
+ do_action('ws_plugin__s2member_during_paypal_return_before_sp_access', get_defined_vars());
53
+ unset($__refs, $__v);
54
+
55
+ if(!get_transient($transient_rtn = 's2m_rtn_'.md5('s2member_transient_'.$_paypal_s)) && set_transient($transient_rtn, time(), 31556926 * 10))
56
+ {
57
+ $paypal['s2member_log'][] = 's2Member `txn_type` identified as ( `web_accept` ) for Specific Post/Page Access.';
58
+
59
+ list (, $paypal['sp_ids'], $paypal['hours']) = preg_split('/\:/', $paypal['item_number'], 3);
60
+
61
+ $paypal['ip'] = (preg_match('/ip address/i', $paypal['option_name2']) && $paypal['option_selection2']) ? $paypal['option_selection2'] : '';
62
+ $paypal['ip'] = (!$paypal['ip'] && preg_match('/^[a-z0-9]+~[0-9\.]+$/i', $paypal['invoice'])) ? preg_replace('/^[a-z0-9]+~/i', '', $paypal['invoice']) : $paypal['ip'];
63
+ $paypal['ip'] = (!$paypal['ip'] && $_SERVER['REMOTE_ADDR']) ? $_SERVER['REMOTE_ADDR'] : $paypal['ip'];
64
+
65
+ $paypal['currency'] = strtoupper($paypal['mc_currency']); // Normalize input currency.
66
+ $paypal['currency_symbol'] = c_ws_plugin__s2member_utils_cur::symbol($paypal['currency']);
67
+
68
+ if(($sp_access_url = c_ws_plugin__s2member_sp_access::sp_access_link_gen($paypal['sp_ids'], $paypal['hours'], FALSE)))
69
  {
70
+ $processing = $during = TRUE; // Yes, we ARE processing this.
71
+
72
+ setcookie('s2member_sp_tracking', ($s2member_sp_tracking = c_ws_plugin__s2member_utils_encryption::encrypt($paypal['txn_id'])), time() + 31556926, COOKIEPATH, COOKIE_DOMAIN).setcookie('s2member_sp_tracking', $s2member_sp_tracking, time() + 31556926, SITECOOKIEPATH, COOKIE_DOMAIN).($_COOKIE['s2member_sp_tracking'] = $s2member_sp_tracking);
73
+
74
+ $paypal['s2member_log'][] = 'Transient Tracking Cookie set on ( `web_accept` ) for Specific Post/Page Access.';
75
+
76
+ if($processing && ($code = $GLOBALS['WS_PLUGIN__']['s2member']['o']['sp_tracking_codes']) && is_array($cv = preg_split('/\|/', $paypal['custom'])))
77
+ {
78
+ if(($code = preg_replace('/%%cv([0-9]+)%%/ei', 'trim(@$cv[$1])', $code)) && ($code = preg_replace('/%%amount%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['mc_gross']), $code)) && ($code = preg_replace('/%%txn_id%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['txn_id']), $code)))
79
+ if(($code = preg_replace('/%%txn_baid%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['txn_baid']), $code)) && ($code = preg_replace('/%%txn_cid%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['txn_cid']), $code)))
80
+ if(($code = preg_replace('/%%currency%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['currency']), $code)) && ($code = preg_replace('/%%currency_symbol%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['currency_symbol']), $code)))
81
+ if(($code = preg_replace('/%%item_number%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['item_number']), $code)) && ($code = preg_replace('/%%item_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['item_name']), $code)))
82
+ if(($code = preg_replace('/%%first_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['first_name']), $code)) && ($code = preg_replace('/%%last_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['last_name']), $code)))
83
+ if(($code = preg_replace('/%%full_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(trim($paypal['first_name'].' '.$paypal['last_name'])), $code)))
84
+ if(($code = preg_replace('/%%payer_email%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['payer_email']), $code)))
85
+ if(($code = preg_replace('/%%user_ip%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['ip']), $code)))
86
+
87
+ if(($code = trim(preg_replace('/%%(.+?)%%/i', '', $code)))) // This gets stored into a Transient Queue.
88
+ {
89
+ $paypal['s2member_log'][] = 'Storing Specific Post/Page Tracking Codes into a Transient Queue. These will be processed on-site.';
90
+ set_transient('s2m_'.md5('s2member_transient_sp_tracking_codes_'.$paypal['txn_id']), $code, 43200);
91
+ }
92
+ }
93
+ foreach(array_keys(get_defined_vars()) as $__v) $__refs[$__v] =& $$__v;
94
+ do_action('ws_plugin__s2member_during_paypal_return_during_sp_access', get_defined_vars());
95
+ unset($__refs, $__v);
96
+
97
+ if(apply_filters('ws_plugin__s2member_immediate_sp_access_redirection', FALSE, get_defined_vars()))
98
+ {
99
+ $paypal['s2member_log'][] = 'Redirecting Customer immediately to the Specific Post/Page.';
100
+
101
+ wp_redirect($sp_access_url); // Immediate redirection to Specific Post/Page.
102
+ }
103
+ else if($custom_success_redirection) // Using a custom success redirection URL?
104
+ {
105
+ $paypal['s2member_log'][] = 'Redirecting Customer to a custom URL on success: '.$custom_success_redirection;
106
+
107
+ wp_redirect($custom_success_redirection);
108
+ }
109
+ else // Else use the default return URL in this scenario, which is the Specific Post/Page.
110
+ {
111
+ $paypal['s2member_log'][] = 'Redirecting Customer to the Specific Post/Page (after displaying a thank-you message).';
112
+
113
+ echo c_ws_plugin__s2member_return_templates::return_template($paypal['subscr_gateway'],
114
+ _x('<strong>Thank You! Your transaction has been approved.</strong>', 's2member-front', 's2member'),
115
+ _x('Continue (Click Here)', 's2member-front', 's2member'), $sp_access_url);
116
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
117
  }
118
+ else // Otherwise, the ID must have been invalid. Or the Post/Page was deleted.
119
+ {
120
+ $paypal['s2member_log'][] = 'Unable to generate Specific Post/Page Access Link. Does your Leading Post/Page still exist?';
121
+
122
+ $paypal['s2member_log'][] = 'Redirecting Customer to the Home Page (after displaying an error message).';
123
+
124
+ echo c_ws_plugin__s2member_return_templates::return_template($paypal['subscr_gateway'],
125
+ _x('<strong>ERROR:</strong> Unable to generate Access Link.<br />Please contact Support for assistance.', 's2member-front', 's2member'),
126
+ _x('Back To Home Page', 's2member-front', 's2member'), home_url('/'));
127
+ }
128
+ }
129
+ else // Page Expired. Duplicate Return-Data.
130
+ {
131
+ $paypal['s2member_log'][] = 'Page Expired. Duplicate Return-Data.';
132
+ $paypal['s2member_log'][] = 's2Member `txn_type` identified as ( `web_accept` ) for Specific Post/Page Access.';
133
+ $paypal['s2member_log'][] = 'Page Expired. Instructing customer to check their email for further details about how to obtain access to what they purchased.';
134
+
135
+ echo c_ws_plugin__s2member_return_templates::return_template($paypal['subscr_gateway'],
136
+ '<strong>'._x('Thank you! Please check your email for further details regarding your purchase.', 's2member-front', 's2member').'</strong>',
137
+ _x('Return to Home Page', 's2member-front', 's2member'), home_url('/'));
138
+ }
139
+ foreach(array_keys(get_defined_vars()) as $__v) $__refs[$__v] =& $$__v;
140
+ do_action('ws_plugin__s2member_during_paypal_return_after_sp_access', get_defined_vars());
141
+ unset($__refs, $__v);
142
+
143
+ return apply_filters('c_ws_plugin__s2member_paypal_return_in_web_accept_sp', $paypal, get_defined_vars());
144
  }
145
+ else return apply_filters('c_ws_plugin__s2member_paypal_return_in_web_accept_sp', FALSE, get_defined_vars());
146
+ }
147
+ }
148
+ }
includes/classes/querys.inc.php CHANGED
@@ -123,9 +123,6 @@ if(!class_exists('c_ws_plugin__s2member_querys'))
123
  if(in_array('wp_get_nav_menu_items', ($callers = (isset($callers) ? $callers : c_ws_plugin__s2member_utilities::callers()))))
124
  add_filter('wp_get_nav_menu_items', 'c_ws_plugin__s2member_querys::_query_level_access_navs', 100);
125
 
126
- if($suppressing_filters !== 'n/a' && (in_array('all', $o) || in_array('pages', $o)))
127
- add_filter('wp_list_pages_excludes', 'c_ws_plugin__s2member_querys::_query_level_access_list_pages', 100);
128
-
129
  if((is_user_logged_in() && is_object($user = wp_get_current_user()) && !empty($user->ID) && ($user_id = $user->ID)) || !($user = FALSE))
130
  {
131
  $bbpress_restrictions_enable = apply_filters('ws_plugin__s2member_bbpress_restrictions_enable', TRUE);
@@ -400,6 +397,17 @@ if(!class_exists('c_ws_plugin__s2member_querys'))
400
  */
401
  public static function _query_level_access_list_pages($excludes = array())
402
  {
 
 
 
 
 
 
 
 
 
 
 
403
  for($n = $GLOBALS['WS_PLUGIN__']['s2member']['c']['levels']; $n >= 0; $n--) // Here we need to exclude any Page not available to the current user.
404
  {
405
  if($GLOBALS['WS_PLUGIN__']['s2member']['o']['level'.$n.'_pages'] === 'all' && !current_user_can('access_s2member_level'.$n))
123
  if(in_array('wp_get_nav_menu_items', ($callers = (isset($callers) ? $callers : c_ws_plugin__s2member_utilities::callers()))))
124
  add_filter('wp_get_nav_menu_items', 'c_ws_plugin__s2member_querys::_query_level_access_navs', 100);
125
 
 
 
 
126
  if((is_user_logged_in() && is_object($user = wp_get_current_user()) && !empty($user->ID) && ($user_id = $user->ID)) || !($user = FALSE))
127
  {
128
  $bbpress_restrictions_enable = apply_filters('ws_plugin__s2member_bbpress_restrictions_enable', TRUE);
397
  */
398
  public static function _query_level_access_list_pages($excludes = array())
399
  {
400
+ if(!$GLOBALS['WS_PLUGIN__']['s2member']['o']['filter_wp_query']
401
+ || (!in_array('all', $GLOBALS['WS_PLUGIN__']['s2member']['o']['filter_wp_query'])
402
+ && !in_array('pages', $GLOBALS['WS_PLUGIN__']['s2member']['o']['filter_wp_query']))
403
+ ) return $excludes; // Not applicable.
404
+
405
+ $systematics = array(); // Initialize.
406
+ $systematics[] = $GLOBALS['WS_PLUGIN__']['s2member']['o']['file_download_limit_exceeded_page'];
407
+ if(!is_user_logged_in()) $systematics[] = $GLOBALS['WS_PLUGIN__']['s2member']['o']['login_welcome_page'];
408
+ $systematics = c_ws_plugin__s2member_utils_arrays::force_integers($systematics); // Force integer values here.
409
+ $excludes = array_merge($excludes, $systematics);
410
+
411
  for($n = $GLOBALS['WS_PLUGIN__']['s2member']['c']['levels']; $n >= 0; $n--) // Here we need to exclude any Page not available to the current user.
412
  {
413
  if($GLOBALS['WS_PLUGIN__']['s2member']['o']['level'.$n.'_pages'] === 'all' && !current_user_can('access_s2member_level'.$n))
includes/classes/users-list-in.inc.php CHANGED
@@ -291,7 +291,7 @@ if(!class_exists("c_ws_plugin__s2member_users_list_in"))
291
 
292
  echo '<tr>'."\n";
293
  echo '<th><label for="ws-plugin--s2member-profile-'.esc_attr($field_id_class).'">'.((preg_match("/^(checkbox|pre_checkbox)$/", $field["type"])) ? ucwords(preg_replace("/_/", " ", $field_var)) : $field["label"]).':</label></th>'."\n";
294
- echo '<td>'.c_ws_plugin__s2member_custom_reg_fields::custom_field_gen(__FUNCTION__, $field, "ws_plugin__s2member_profile_", "ws-plugin--s2member-profile-", "", ((preg_match("/^(text|textarea|select|selects)$/", $field["type"])) ? "width:99%;" : ""), "", "", $fields, $fields[$field_var], "administrative").'</td>'."\n";
295
  echo '</tr>'."\n";
296
  }
297
  unset($__refs, $__v);
@@ -461,6 +461,9 @@ if(!class_exists("c_ws_plugin__s2member_users_list_in"))
461
  if(isset($_p["ws_plugin__s2member_profile_s2member_subscr_id"]))
462
  update_user_option($user_id, "s2member_subscr_id", $_p["ws_plugin__s2member_profile_s2member_subscr_id"]);
463
 
 
 
 
464
  if(isset($_p["ws_plugin__s2member_profile_s2member_custom"]))
465
  update_user_option($user_id, "s2member_custom", $_p["ws_plugin__s2member_profile_s2member_custom"]);
466
 
@@ -495,9 +498,9 @@ if(!class_exists("c_ws_plugin__s2member_users_list_in"))
495
  {
496
  if((is_array($_p["ws_plugin__s2member_profile_".$field_var]) && !empty($_p["ws_plugin__s2member_profile_".$field_var])) || (is_string($_p["ws_plugin__s2member_profile_".$field_var]) && strlen($_p["ws_plugin__s2member_profile_".$field_var])))
497
  $fields[$field_var] = $_p["ws_plugin__s2member_profile_".$field_var];
498
- else unset($fields[$field_var]);
499
  }
500
- else unset($fields[$field_var]);
501
  }
502
  }
503
  if(!empty($fields))
291
 
292
  echo '<tr>'."\n";
293
  echo '<th><label for="ws-plugin--s2member-profile-'.esc_attr($field_id_class).'">'.((preg_match("/^(checkbox|pre_checkbox)$/", $field["type"])) ? ucwords(preg_replace("/_/", " ", $field_var)) : $field["label"]).':</label></th>'."\n";
294
+ echo '<td>'.c_ws_plugin__s2member_custom_reg_fields::custom_field_gen(__FUNCTION__, $field, "ws_plugin__s2member_profile_", "ws-plugin--s2member-profile-", "", ((preg_match("/^(text|textarea|select|selects)$/", $field["type"])) ? "width:99%;" : ""), "", "", $fields, @$fields[$field_var], "administrative").'</td>'."\n";
295
  echo '</tr>'."\n";
296
  }
297
  unset($__refs, $__v);
461
  if(isset($_p["ws_plugin__s2member_profile_s2member_subscr_id"]))
462
  update_user_option($user_id, "s2member_subscr_id", $_p["ws_plugin__s2member_profile_s2member_subscr_id"]);
463
 
464
+ if(isset($_p["ws_plugin__s2member_profile_s2member_subscr_cid"]))
465
+ update_user_option($user_id, "s2member_subscr_cid", $_p["ws_plugin__s2member_profile_s2member_subscr_cid"]);
466
+
467
  if(isset($_p["ws_plugin__s2member_profile_s2member_custom"]))
468
  update_user_option($user_id, "s2member_custom", $_p["ws_plugin__s2member_profile_s2member_custom"]);
469
 
498
  {
499
  if((is_array($_p["ws_plugin__s2member_profile_".$field_var]) && !empty($_p["ws_plugin__s2member_profile_".$field_var])) || (is_string($_p["ws_plugin__s2member_profile_".$field_var]) && strlen($_p["ws_plugin__s2member_profile_".$field_var])))
500
  $fields[$field_var] = $_p["ws_plugin__s2member_profile_".$field_var];
501
+ else if(isset($fields)) unset($fields[$field_var]);
502
  }
503
+ else if(isset($fields)) unset($fields[$field_var]);
504
  }
505
  }
506
  if(!empty($fields))
includes/functions/api-functions.inc.php CHANGED
@@ -2491,7 +2491,9 @@ if(!function_exists("get_s2member_custom_fields"))
2491
  {
2492
  $fields = ($user_id) ? get_user_option("s2member_custom_fields", $user_id) : false;
2493
 
2494
- foreach(json_decode($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["custom_reg_fields"], true) as $field)
 
 
2495
  {
2496
  if /* Should we try to fill the User's value for this Custom Field? */($user_id)
2497
  $s2member_custom_fields[$field["id"]]["user_value"] = (isset($fields[$field["id"]])) ? $fields[$field["id"]] : false;
2491
  {
2492
  $fields = ($user_id) ? get_user_option("s2member_custom_fields", $user_id) : false;
2493
 
2494
+ if(!$custom_fields = json_decode($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["custom_reg_fields"], true)) return array();
2495
+
2496
+ foreach($custom_fields as $field)
2497
  {
2498
  if /* Should we try to fill the User's value for this Custom Field? */($user_id)
2499
  $s2member_custom_fields[$field["id"]]["user_value"] = (isset($fields[$field["id"]])) ? $fields[$field["id"]] : false;
includes/hooks.inc.php CHANGED
@@ -57,6 +57,7 @@ add_action('admin_init', 'c_ws_plugin__s2member_menu_pages::logs_zip_downloader'
57
 
58
  add_filter('bbp_has_replies_query', 'c_ws_plugin__s2member_querys::_bbp_flag_has_replies');
59
  add_action('pre_get_posts', 'c_ws_plugin__s2member_security::security_gate_query', 100);
 
60
 
61
  add_action('wp', 'c_ws_plugin__s2member_ssl::check_force_ssl', 1);
62
  add_action('wp', 'c_ws_plugin__s2member_security::security_gate', 1);
@@ -108,6 +109,8 @@ add_action('wpmu_activate_user', 'c_ws_plugin__s2member_registrations::configure
108
  add_action('wpmu_activate_blog', 'c_ws_plugin__s2member_registrations::configure_user_on_ms_blog_activation', 10, 5);
109
  add_action('signup_extra_fields', 'c_ws_plugin__s2member_custom_reg_fields::ms_custom_registration_fields');
110
 
 
 
111
  add_action('bp_after_signup_profile_fields', 'c_ws_plugin__s2member_custom_reg_fields_4bp::custom_registration_fields_4bp');
112
  add_action('bp_signup_validate', 'c_ws_plugin__s2member_registrations::custom_registration_field_errors_4bp');
113
  add_action('bp_after_profile_field_content', 'c_ws_plugin__s2member_custom_reg_fields_4bp::custom_profile_fields_4bp');
@@ -197,6 +200,9 @@ add_action('bbp_activation', 'c_ws_plugin__s2member_roles_caps::config_roles', 1
197
  add_action('http_api_debug', 'c_ws_plugin__s2member_utils_logs::http_api_debug', 1000, 5);
198
 
199
  add_action('plugins_loaded', 'c_ws_plugin__s2member_mo_page::back_compat_mop_vars', -(PHP_INT_MAX - 10));
 
 
 
200
  /*
201
  Register the activation | de-activation routines.
202
  */
57
 
58
  add_filter('bbp_has_replies_query', 'c_ws_plugin__s2member_querys::_bbp_flag_has_replies');
59
  add_action('pre_get_posts', 'c_ws_plugin__s2member_security::security_gate_query', 100);
60
+ add_filter('wp_list_pages_excludes', 'c_ws_plugin__s2member_querys::_query_level_access_list_pages', 100);
61
 
62
  add_action('wp', 'c_ws_plugin__s2member_ssl::check_force_ssl', 1);
63
  add_action('wp', 'c_ws_plugin__s2member_security::security_gate', 1);
109
  add_action('wpmu_activate_blog', 'c_ws_plugin__s2member_registrations::configure_user_on_ms_blog_activation', 10, 5);
110
  add_action('signup_extra_fields', 'c_ws_plugin__s2member_custom_reg_fields::ms_custom_registration_fields');
111
 
112
+ add_action('plugins_loaded', 'c_ws_plugin__s2member_custom_reg_fields::add_filters_get_user_option', 1);
113
+
114
  add_action('bp_after_signup_profile_fields', 'c_ws_plugin__s2member_custom_reg_fields_4bp::custom_registration_fields_4bp');
115
  add_action('bp_signup_validate', 'c_ws_plugin__s2member_registrations::custom_registration_field_errors_4bp');
116
  add_action('bp_after_profile_field_content', 'c_ws_plugin__s2member_custom_reg_fields_4bp::custom_profile_fields_4bp');
200
  add_action('http_api_debug', 'c_ws_plugin__s2member_utils_logs::http_api_debug', 1000, 5);
201
 
202
  add_action('plugins_loaded', 'c_ws_plugin__s2member_mo_page::back_compat_mop_vars', -(PHP_INT_MAX - 10));
203
+
204
+ remove_filter('the_content', 'wptexturize'); // Bug fix; see: <https://github.com/websharks/s2member/issues/349>
205
+ // See also, this WP core bug report for further details: <https://core.trac.wordpress.org/ticket/29608>
206
  /*
207
  Register the activation | de-activation routines.
208
  */
includes/menu-pages/api-ops.inc.php CHANGED
@@ -1,1023 +1,1034 @@
1
  <?php
2
  /**
3
- * Menu page for the s2Member plugin (API Notifications page).
4
- *
5
- * Copyright: © 2009-2011
6
- * {@link http://www.websharks-inc.com/ WebSharks, Inc.}
7
- * (coded in the USA)
8
- *
9
- * Released under the terms of the GNU General Public License.
10
- * You should have received a copy of the GNU General Public License,
11
- * along with this software. In the main directory, see: /licensing/
12
- * If not, see: {@link http://www.gnu.org/licenses/}.
13
- *
14
- * @package s2Member\Menu_Pages
15
- * @since 3.0
16
- */
17
- if (realpath (__FILE__) === realpath ($_SERVER["SCRIPT_FILENAME"]))
18
  exit("Do not access this file directly.");
19
 
20
- if (!class_exists ("c_ws_plugin__s2member_menu_page_api_ops"))
 
 
 
 
 
 
 
 
21
  {
22
- /**
23
- * Menu page for the s2Member plugin (API Notifications page).
24
- *
25
- * @package s2Member\Menu_Pages
26
- * @since 110531
27
- */
28
- class c_ws_plugin__s2member_menu_page_api_ops
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
29
  {
30
- public function __construct ()
31
- {
32
- echo '<div class="wrap ws-menu-page">' . "\n";
33
-
34
- echo '<div class="ws-menu-page-toolbox">'."\n";
35
- c_ws_plugin__s2member_menu_pages_tb::display ();
36
- echo '</div>'."\n";
37
-
38
- echo '<h2>API / Notifications</h2>' . "\n";
39
-
40
- echo '<table class="ws-menu-page-table">' . "\n";
41
- echo '<tbody class="ws-menu-page-table-tbody">' . "\n";
42
- echo '<tr class="ws-menu-page-table-tr">' . "\n";
43
- echo '<td class="ws-menu-page-table-l">' . "\n";
44
-
45
- echo '<form method="post" name="ws_plugin__s2member_options_form" id="ws-plugin--s2member-options-form">' . "\n";
46
- 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";
47
- echo '<input type="hidden" name="ws_plugin__s2member_configured" id="ws-plugin--s2member-configured" value="1" />' . "\n";
48
-
49
- do_action("ws_plugin__s2member_during_api_ops_page_before_left_sections", get_defined_vars ());
50
-
51
- if (apply_filters("ws_plugin__s2member_during_api_ops_page_during_left_sections_display_signup_notifications", true, get_defined_vars ()))
52
- {
53
- do_action("ws_plugin__s2member_during_api_ops_page_during_left_sections_before_signup_notifications", get_defined_vars ());
54
-
55
- echo '<div class="ws-menu-page-group" title="Signup Notifications">' . "\n";
56
-
57
- echo '<div class="ws-menu-page-section ws-plugin--s2member-signup-notifications-section">' . "\n";
58
- echo '<h3>Signup Notification URLs (optional)</h3>' . "\n";
59
- 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 "new", "paying" Member signs up. Depending on your fee structure, this may include a payment that establishes their Subscription, or it may not. This Notification will only be triggered once for each Member. Signup Notifications are sent right after a "new", "paying" Member signs up successfully through your Payment Gateway, regardless of whether any money has actually been transacted. In other words, this Notification is triggered anytime a "new", "paying" Member signs up through your Payment Gateway, even if you provided them with something for free <em>(i.e. even if no money is being transacted)</em>.</p>' . "\n";
60
- echo '<p>This Notification will NOT be processed for Free Subscribers that register without going through your Payment Gateway at all (i.e. they simply register on-site; and there is no checkout whatsoever). This Notification will NOT be processed when an "existing" User/Member pays for a new Subscription <em>(see: Modification Notifications for that scenario)</em>.' . ((is_multisite () && c_ws_plugin__s2member_utils_conds::is_multisite_farm () && !is_main_site ()) ? '' : ' And, this Notification will NOT be processed on Buy Now transactions for Independent Custom Capabilities <em>(see: Payment Notifications for that scenario)</em>.') . '</p>' . "\n";
61
- echo '<p>Please note, this feature is not to be confused with the PayPal IPN service. PayPal IPN <em>(and other service integrations)</em> are already built into s2Member. They remain active at all times. These Signup Notifications are an added layer of functionality, and they are completely optional.</p>' . "\n";
62
- echo '<p><strong>See also:</strong> This KB article: <a href="http://www.s2member.com/kb/building-an-api-notification-handler/" target="_blank" rel="external">Building An API Notification Handler</a>.</p>'."\n";
63
- do_action("ws_plugin__s2member_during_api_ops_page_during_left_sections_during_signup_notifications", get_defined_vars ());
64
-
65
- echo '<table class="form-table">' . "\n";
66
- echo '<tbody>' . "\n";
67
- echo '<tr>' . "\n";
68
-
69
- echo '<th>' . "\n";
70
- echo '<label for="ws-plugin--s2member-signup-notification-urls">' . "\n";
71
- echo 'Signup Notification URLs:' . "\n";
72
- echo '</label>' . "\n";
73
- echo '</th>' . "\n";
74
-
75
- echo '</tr>' . "\n";
76
- echo '<tr>' . "\n";
77
-
78
- echo '<td>' . "\n";
79
- echo 'You can input multiple Notification URLs by inserting one per line.<br />' . "\n";
80
- 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";
81
- echo 'Signup Notifications take place silently behind-the-scene, using an HTTP connection.<br /><br />' . "\n";
82
- echo '<strong>You can also use these special Replacement Codes if you need them:</strong>' . "\n";
83
- echo '<ul class="ws-menu-page-li-margins">' . "\n";
84
- echo '<li><code>%%subscr_id%%</code> = The Paid Subscription ID, which remains constant throughout any &amp; all future payments. [ <a href="#" onclick="alert(\'There is one exception. If you are selling Lifetime or Fixed-Term (non-recurring) access, using Buy Now functionality; the %%subscr_id%% is actually set to the Transaction ID for the purchase. Payment Gateways do not provide a specific Subscription ID for Buy Now purchases. Since Lifetime &amp; Fixed-Term Subscriptions are NOT recurring (i.e. there is only ONE payment), using the Transaction ID as the Subscription ID is a graceful way to deal with this minor conflict.\'); return false;">?</a> ]</li>' . "\n";
85
- echo '<li><code>%%subscr_baid%%</code> = Applicable only with PayPal Pro (Payflow Edition); and only for Express Checkout transactions that require a Billing Agreement. This is the Subscription\'s Billing Agreement ID, which remains constant throughout any &amp; all future payments. [ <a href="#" onclick="alert(\'Applicable only with PayPal Pro (Payflow Edition); and only for Express Checkout transactions that require a Billing Agreement. In all other cases, the %%subscr_baid%% is simply set to the %%subscr_id%% value; i.e. it is a duplicate of %%subscr_id%% in most cases.\'); return false;">?</a> ]</li>' . "\n";
86
- echo '<li><code>%%subscr_cid%%</code> = Applicable only with Stripe integration. This is the Customer\'s ID in Stripe, which remains constant throughout any &amp; all future payments. Each Stripe Customer has this Customer ID; and also a Subscription and/or Transaction ID [ <a href="#" onclick="alert(\'Applicable only when you integrate s2Member with Stripe. In all other cases, the %%subscr_cid%% is simply set to the %%subscr_id%% value; i.e. it is a duplicate of %%subscr_id%% when running anything other than Stripe.\\n\\nEach Stripe Customer has a Customer ID; and also a Subscription and/or Transaction ID. See %%subscr_id%% for further details.\'); return false;">?</a> ]</li>' . "\n";
87
- echo '<li><code>%%initial%%</code> = The Initial Fee charged during signup. If you offered a 100% Free Trial, this will be <code>0</code>. [ <a href="#" onclick="alert(\'This will always represent the amount of money the Customer spent, whenever they initially signed up, no matter what. Even if that amount is 0.\\n\\nIf a Customer signs up, under the terms of a 100% Free Trial Period, this will be 0. So be careful using %%initial%% when you offer a 100% Free Trial Period, because a $0.00 sale amount could cause havoc with affiliate programs.\\n\\nIf you\\\'re offering a 100% Free Trial Period, and you need to track sales through affiliate programs, you can either hard-code an amount; or use `Payment Notifications` instead.\'); return false;">?</a> ]</li>' . "\n";
88
- echo '<li><code>%%regular%%</code> = The Regular Amount of the Subscription. If you offer something 100% free, this will be <code>0</code>. [ <a href="#" onclick="alert(\'This is how much the Subscription costs after an Initial Period expires. If you did NOT offer an Initial Period at a different price, %%initial%% and %%regular%% will be equal to the same thing.\'); return false;">?</a> ]</li>' . "\n";
89
- echo '<li><code>%%recurring%%</code> = This is the amount that will be charged on a recurring basis, or <code>0</code> if non-recurring. [ <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.\'); return false;">?</a> ]</li>' . "\n";
90
- echo '<li><code>%%first_name%%</code> = The First Name of the Customer who purchased the Membership Subscription.</li>' . "\n";
91
- echo '<li><code>%%last_name%%</code> = The Last Name of the Customer who purchased the Membership Subscription.</li>' . "\n";
92
- echo '<li><code>%%full_name%%</code> = The Full Name (First &amp; Last) of the Customer who purchased the Membership Subscription.</li>' . "\n";
93
- echo '<li><code>%%payer_email%%</code> = The Email Address of the Customer who purchased the Membership Subscription.</li>' . "\n";
94
- echo '<li><code>%%user_ip%%</code> = The Customer\'s IP Address, detected during checkout via <code>$_SERVER["REMOTE_ADDR"]</code>.</li>' . "\n";
95
- echo '<li><code>%%item_number%%</code> = The Item Number (colon separated <code><em>level:custom_capabilities:fixed term</em></code>) for the Membership Subscription.</li>' . "\n";
96
- echo '<li><code>%%item_name%%</code> = The Item Name (as provided by the <code>desc=""</code> attribute in your Shortcode, which briefly describes the Item Number).</li>' . "\n";
97
- echo '<li><code>%%initial_term%%</code> = This is the term length of the Initial Period. This will be a numeric value, followed by a space, then a single letter. [ <a href="#" onclick="alert(\'Here are some examples:\\n\\n%%initial_term%% = 1 D (this means 1 Day)\\n%%initial_term%% = 1 W (this means 1 Week)\\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.\'); return false;">?</a> ]</li>' . "\n";
98
- echo '<li><code>%%regular_term%%</code> = This is the term length of the Regular Period. This will be a numeric value, followed by a space, then a single letter. [ <a href="#" onclick="alert(\'Here are some examples:\\n\\n%%regular_term%% = 1 D (this means 1 Day)\\n%%regular_term%% = 1 W (this means 1 Week)\\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";
99
- echo '</ul>' . "\n";
100
-
101
- if(c_ws_plugin__s2member_utils_conds::pro_is_installed())
102
- {
103
- echo '<strong>Coupon Replacement Codes (applicable only w/ s2Member Pro Forms):</strong>' . "\n";
104
- echo '<ul class="ws-menu-page-li-margins">' . "\n";
105
- echo '<li><code>%%full_coupon_code%%</code> = A full Coupon Code — if one is accepted by your configuration of s2Member. This may indicate an Affiliate Coupon Code, which will include your Affiliate Suffix Chars too (i.e. the full Coupon Code).</li>' . "\n";
106
- echo '<li><code>%%coupon_code%%</code> = A Coupon Code — if one is accepted by your configuration of s2Member. This will NOT include any Affiliate Suffix Chars. This indicates the actual Coupon Code accepted by your configuration of s2Member (excluding any Affiliate ID).</li>' . "\n";
107
- echo '<li><code>%%coupon_affiliate_id%%</code> = This is the end of an Affiliate Coupon Code <em>(i.e. the referring affiliate\'s ID)</em>. This is only applicable if an Affiliate Coupon Code is accepted by your configuration of s2Member.</li>' . "\n";
108
- echo '</ul>' . "\n";
109
- }
110
-
111
- echo '<strong>Custom Replacement Codes can also be inserted using these instructions:</strong>' . "\n";
112
- echo '<ul class="ws-menu-page-li-margins">' . "\n";
113
- echo '<li><code>%%cv0%%</code> = The domain of your site, which is passed through the `custom` attribute in your Shortcode.</li>' . "\n";
114
- echo '<li><code>%%cv1%%</code> = If you need to track additional custom variables, you can pipe delimit them into the `custom` attribute; inside your Shortcode, like this: <code>custom="' . esc_html ($_SERVER["HTTP_HOST"]) . '|cv1|cv2|cv3"</code>. You can have an unlimited number of custom variables. Obviously, this is for advanced webmasters; but the functionality has been made available for those who need it.</li>' . "\n";
115
- echo '</ul>' . "\n";
116
- echo '<strong>This example uses cv1 to record a special marketing campaign:</strong><br />' . "\n";
117
- echo '<em>(The campaign (i.e. christmas-promo) could be referenced using <code>%%cv1%%</code>)</em><br />' . "\n";
118
- echo '<code>custom="' . esc_html ($_SERVER["HTTP_HOST"]) . '|christmas-promo"</code>' . "\n";
119
-
120
- echo '</td>' . "\n";
121
-
122
- echo '</tr>' . "\n";
123
- echo '</tbody>' . "\n";
124
- echo '</table>' . "\n";
125
-
126
- echo '<div class="ws-menu-page-hr"></div>' . "\n";
127
-
128
- echo '<table class="form-table" style="margin-top:0;">' . "\n";
129
- echo '<tbody>' . "\n";
130
- echo '<tr>' . "\n";
131
-
132
- echo '<th style="padding-top:0;">' . "\n";
133
- echo '<label for="ws-plugin--s2member-signup-notification-recipients">' . "\n";
134
- echo 'Send An Email Transaction Log Of This Event?' . "\n";
135
- echo '</label>' . "\n";
136
- echo '</th>' . "\n";
137
-
138
- echo '</tr>' . "\n";
139
- echo '<tr>' . "\n";
140
-
141
- echo '<td>' . "\n";
142
- echo '<input type="text" autocomplete="off" name="ws_plugin__s2member_signup_notification_recipients" id="ws-plugin--s2member-signup-notification-recipients" value="' . format_to_edit ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["signup_notification_recipients"]) . '" /><br />' . "\n";
143
- echo 'This is a semicolon ( ; ) delimited list of Recipients. Here is an example:<br />' . "\n";
144
- echo '<code>"John" &lt;john@example.com&gt;; admin@example.com; "Webmaster" &lt;webmaster@example.com&gt;</code>' . "\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
-
155
- if (apply_filters("ws_plugin__s2member_during_api_ops_page_during_left_sections_display_registration_notifications", true, get_defined_vars ()))
156
- {
157
- do_action("ws_plugin__s2member_during_api_ops_page_during_left_sections_before_registration_notifications", get_defined_vars ());
158
-
159
- echo '<div class="ws-menu-page-group" title="Registration Notifications">' . "\n";
160
-
161
- echo '<div class="ws-menu-page-section ws-plugin--s2member-registration-notifications-section">' . "\n";
162
- echo '<h3>Registration Notification URLs (optional)</h3>' . "\n";
163
- 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 "new" 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.</p>' . "\n";
164
- echo '<p>This Notification is ALSO triggered whenever you create a "new" User inside your WordPress Dashboard.</p>' . "\n";
165
- echo '<p>Please note, this feature is not to be confused with the PayPal IPN service. PayPal IPN <em>(and other service integrations)</em> are already built into s2Member. They remain active at all times. These Registration Notifications are an added layer of functionality, and they are completely optional.</p>' . "\n";
166
- echo '<p><strong>See also:</strong> This KB article: <a href="http://www.s2member.com/kb/building-an-api-notification-handler/" target="_blank" rel="external">Building An API Notification Handler</a>.</p>'."\n";
167
- do_action("ws_plugin__s2member_during_api_ops_page_during_left_sections_during_registration_notifications", get_defined_vars ());
168
-
169
- echo '<table class="form-table">' . "\n";
170
- echo '<tbody>' . "\n";
171
- echo '<tr>' . "\n";
172
-
173
- echo '<th>' . "\n";
174
- echo '<label for="ws-plugin--s2member-registration-notification-urls">' . "\n";
175
- echo 'Registration Notification URLs:' . "\n";
176
- echo '</label>' . "\n";
177
- echo '</th>' . "\n";
178
-
179
- echo '</tr>' . "\n";
180
- echo '<tr>' . "\n";
181
-
182
- echo '<td>' . "\n";
183
- echo 'You can input multiple Notification URLs by inserting one per line.<br />' . "\n";
184
- 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";
185
- echo 'Registration Notifications take place silently behind-the-scene, using an HTTP connection.<br /><br />' . "\n";
186
- echo '<strong>You can also use these special Replacement Codes if you need them:</strong>' . "\n";
187
- echo '<ul class="ws-menu-page-li-margins">' . "\n";
188
- echo '<li><code>%%role%%</code> = The Role ID <code>(subscriber, s2member_level[0-9]+, administrator, editor, author, contributor)</code>.</li>' . "\n";
189
- echo '<li><code>%%level%%</code> = The Level number <code>(0, 1, 2, 3, 4)</code>. (<em>deprecated, no longer recommended; use <code>%%role%%</code></em>)</li>' . "\n";
190
- echo '<li><code>%%ccaps%%</code> = Custom Capabilities. Ex: <code>music,videos,free_gift</code> (<em>in comma-delimited format</em>).</li>' . "\n";
191
- echo '<li><code>%%auto_eot_time%%</code> = Auto-EOT Time (if applicable). Ex: <code>1299925670</code> (<em>unix timestamp</em>).</li>' . "\n";
192
- echo '<li><code>%%user_first_name%%</code> = The First Name of the Member who registered their Username.</li>' . "\n";
193
- echo '<li><code>%%user_last_name%%</code> = The Last Name of the Member who registered their Username.</li>' . "\n";
194
- echo '<li><code>%%user_full_name%%</code> = The Full Name (First &amp; Last) of the Member who registered their Username.</li>' . "\n";
195
- echo '<li><code>%%user_email%%</code> = The Email Address of the Member who registered their Username.</li>' . "\n";
196
- echo '<li><code>%%user_login%%</code> = The Username the Member selected during registration.</li>' . "\n";
197
- echo '<li><code>%%user_pass%%</code> = The Password selected or generated during registration.</li>' . "\n";
198
- echo '<li><code>%%user_ip%%</code> = The User\'s IP Address, detected via <code>$_SERVER["REMOTE_ADDR"]</code>.</li>' . "\n";
199
- echo '<li><code>%%user_id%%</code> = A unique WordPress User ID generated during registration.</li>' . "\n";
200
- echo '</ul>' . "\n";
201
-
202
- echo '<strong>Custom Registration/Profile Fields are also supported in this Notification:</strong>' . "\n";
203
- echo '<ul class="ws-menu-page-li-margins">' . "\n";
204
- echo '<li><code>%%date_of_birth%%</code> would be valid; if you have a Custom Registration/Profile Field with the ID <code>date_of_birth</code>.</li>' . "\n";
205
- echo '<li><code>%%street_address%%</code> would be valid; if you have a Custom Registration/Profile Field with the ID <code>street_address</code>.</li>' . "\n";
206
- echo '<li><code>%%country%%</code> would be valid; if you have a Custom Registration/Profile Field with the ID <code>country</code>.</li>' . "\n";
207
- echo '<li><em><code>%%etc, etc...%%</code> <strong>see:</strong> s2Member -› General Options -› Registration/Profile Fields</em>.</li>' . "\n";
208
- echo '</ul>' . "\n";
209
-
210
- echo '<strong>Custom Replacement Codes can also be inserted using these instructions:</strong>' . "\n";
211
- echo '<ul class="ws-menu-page-li-margins">' . "\n";
212
- echo '<li><code>%%cv0%%</code> = The domain of your site, which is passed through the `custom` attribute in your Shortcode.</li>' . "\n";
213
- echo '<li><code>%%cv1%%</code> = If you need to track additional custom variables, you can pipe delimit them into the `custom` attribute; inside your Shortcode, like this: <code>custom="' . esc_html ($_SERVER["HTTP_HOST"]) . '|cv1|cv2|cv3"</code>. You can have an unlimited number of custom variables. Obviously, this is for advanced webmasters; but the functionality has been made available for those who need it.</li>' . "\n";
214
- echo '</ul>' . "\n";
215
- echo '<strong>This example uses cv1 to record a special marketing campaign:</strong><br />' . "\n";
216
- echo '<em>(The campaign (i.e. christmas-promo) could be referenced using <code>%%cv1%%</code>)</em><br />' . "\n";
217
- echo '<code>custom="' . esc_html ($_SERVER["HTTP_HOST"]) . '|christmas-promo"</code>' . "\n";
218
-
219
- echo '</td>' . "\n";
220
-
221
- echo '</tr>' . "\n";
222
- echo '</tbody>' . "\n";
223
- echo '</table>' . "\n";
224
-
225
- echo '<div class="ws-menu-page-hr"></div>' . "\n";
226
-
227
- echo '<table class="form-table" style="margin-top:0;">' . "\n";
228
- echo '<tbody>' . "\n";
229
- echo '<tr>' . "\n";
230
-
231
- echo '<th style="padding-top:0;">' . "\n";
232
- echo '<label for="ws-plugin--s2member-registration-notification-recipients">' . "\n";
233
- echo 'Send An Email Transaction Log Of This Event?' . "\n";
234
- echo '</label>' . "\n";
235
- echo '</th>' . "\n";
236
-
237
- echo '</tr>' . "\n";
238
- echo '<tr>' . "\n";
239
-
240
- echo '<td>' . "\n";
241
- echo '<input type="text" autocomplete="off" name="ws_plugin__s2member_registration_notification_recipients" id="ws-plugin--s2member-registration-notification-recipients" value="' . format_to_edit ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["registration_notification_recipients"]) . '" /><br />' . "\n";
242
- echo 'This is a semicolon ( ; ) delimited list of Recipients. Here is an example:<br />' . "\n";
243
- echo '<code>"John" &lt;john@example.com&gt;; admin@example.com; "Webmaster" &lt;webmaster@example.com&gt;</code>' . "\n";
244
- echo '</td>' . "\n";
245
-
246
- echo '</tr>' . "\n";
247
- echo '</tbody>' . "\n";
248
- echo '</table>' . "\n";
249
- echo '</div>' . "\n";
250
-
251
- echo '</div>' . "\n";
252
-
253
- do_action("ws_plugin__s2member_during_api_ops_page_during_left_sections_after_registration_notifications", get_defined_vars ());
254
- }
255
-
256
- if (apply_filters("ws_plugin__s2member_during_api_ops_page_during_left_sections_display_payment_notifications", true, get_defined_vars ()))
257
- {
258
- do_action("ws_plugin__s2member_during_api_ops_page_during_left_sections_before_payment_notifications", get_defined_vars ());
259
-
260
- echo '<div class="ws-menu-page-group" title="Payment Notifications">' . "\n";
261
-
262
- echo '<div class="ws-menu-page-section ws-plugin--s2member-payment-notifications-section">' . "\n";
263
- echo '<h3>Payment Notification URLs (optional)</h3>' . "\n";
264
- echo '<p>If you use affiliate software, or have back-office routines that need to be notified whenever payment transactions <em>(including Recurring Payments)</em> take place, 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.</p>' . "\n";
265
- echo '<p>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 <em>(i.e. no Free Trial is being offered)</em>, 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.</p>' . "\n";
266
- echo (!is_multisite () || !c_ws_plugin__s2member_utils_conds::is_multisite_farm () || is_main_site ()) ? '<p>Payment Notifications are also triggered whenever a Buy Now purchase for Independent Custom Capabilities takes place.</p>' . "\n" : '';
267
- echo '<p>Please note, this feature is not to be confused with the PayPal IPN service. PayPal IPN <em>(and other service integrations)</em> are already built into s2Member. They remain active at all times. These Payment Notifications are an added layer of functionality, and they are completely optional.</p>' . "\n";
268
- echo '<p><strong>See also:</strong> This KB article: <a href="http://www.s2member.com/kb/building-an-api-notification-handler/" target="_blank" rel="external">Building An API Notification Handler</a>.</p>'."\n";
269
- do_action("ws_plugin__s2member_during_api_ops_page_during_left_sections_during_payment_notifications", get_defined_vars ());
270
-
271
- echo '<table class="form-table">' . "\n";
272
- echo '<tbody>' . "\n";
273
- echo '<tr>' . "\n";
274
-
275
- echo '<th>' . "\n";
276
- echo '<label for="ws-plugin--s2member-payment-notification-urls">' . "\n";
277
- echo 'Payment Notification URLs:' . "\n";
278
- echo '</label>' . "\n";
279
- echo '</th>' . "\n";
280
-
281
- echo '</tr>' . "\n";
282
- echo '<tr>' . "\n";
283
-
284
- echo '<td>' . "\n";
285
- echo 'You can input multiple Notification URLs by inserting one per line.<br />' . "\n";
286
- 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";
287
- echo 'Payment Notifications take place silently behind-the-scene, using an HTTP connection.<br /><br />' . "\n";
288
- echo '<strong>You can also use these special Replacement Codes if you need them:</strong>' . "\n";
289
- echo '<ul class="ws-menu-page-li-margins">' . "\n";
290
- echo '<li><code>%%subscr_id%%</code> = The Paid Subscription ID, which remains constant throughout any &amp; all future payments. [ <a href="#" onclick="alert(\'There are some exceptions. If you are selling Lifetime or Fixed-Term (non-recurring) access, and/or Independent Custom Capabilities, using Buy Now functionality; the %%subscr_id%% is actually set to the Transaction ID for the payment.\\n\\nPayment Gateways do not provide a specific Subscription ID for Buy Now purchases. Since Lifetime &amp; Fixed-Term Subscriptions are NOT recurring (i.e. there is only ONE payment), which goes for Independent Custom Capability purchases too; using the Transaction ID as the Subscription ID is a graceful way to deal with this minor conflict.\'); return false;">?</a> ]</li>' . "\n";
291
- echo '<li><code>%%subscr_baid%%</code> = Applicable only with PayPal Pro (Payflow Edition); and only for Express Checkout transactions that require a Billing Agreement. This is the Subscription\'s Billing Agreement ID, which remains constant throughout any &amp; all future payments. [ <a href="#" onclick="alert(\'Applicable only with PayPal Pro (Payflow Edition); and only for Express Checkout transactions that require a Billing Agreement. In all other cases, the %%subscr_baid%% is simply set to the %%subscr_id%% value; i.e. it is a duplicate of %%subscr_id%% in most cases.\'); return false;">?</a> ]</li>' . "\n";
292
- echo '<li><code>%%subscr_cid%%</code> = Applicable only with Stripe integration. This is the Customer\'s ID in Stripe, which remains constant throughout any &amp; all future payments. Each Stripe Customer has this Customer ID; and also a Subscription and/or Transaction ID [ <a href="#" onclick="alert(\'Applicable only when you integrate s2Member with Stripe. In all other cases, the %%subscr_cid%% is simply set to the %%subscr_id%% value; i.e. it is a duplicate of %%subscr_id%% when running anything other than Stripe.\\n\\nEach Stripe Customer has a Customer ID; and also a Subscription and/or Transaction ID. See %%subscr_id%% for further details.\'); return false;">?</a> ]</li>' . "\n";
293
- echo '<li><code>%%txn_id%%</code> = The Payment Transaction ID, which is always unique for each payment received.</li>' . "\n";
294
- echo '<li><code>%%amount%%</code> = The Amount of the payment. Most affiliate programs calculate commissions from this.</li>' . "\n";
295
- echo '<li><code>%%first_name%%</code> = The First Name of the Customer who purchased the Membership Subscription' . ((is_multisite () && c_ws_plugin__s2member_utils_conds::is_multisite_farm () && !is_main_site ()) ? '' : ' or Capabilities.') . '</li>' . "\n";
296
- echo '<li><code>%%last_name%%</code> = The Last Name of the Customer who purchased the Membership Subscription' . ((is_multisite () && c_ws_plugin__s2member_utils_conds::is_multisite_farm () && !is_main_site ()) ? '' : ' or Capabilities.') . '</li>' . "\n";
297
- echo '<li><code>%%full_name%%</code> = The Full Name (First &amp; Last) of the Customer who purchased the Membership Subscription' . ((is_multisite () && c_ws_plugin__s2member_utils_conds::is_multisite_farm () && !is_main_site ()) ? '' : ' or Capabilities.') . '</li>' . "\n";
298
- echo '<li><code>%%payer_email%%</code> = The Email Address of the Customer who purchased the Membership Subscription' . ((is_multisite () && c_ws_plugin__s2member_utils_conds::is_multisite_farm () && !is_main_site ()) ? '' : ' or Capabilities.') . '</li>' . "\n";
299
- echo '<li><code>%%item_number%%</code> = The Item Number (colon separated <code><em>level:custom_capabilities:fixed term</em></code>) that the payment is for.' . ((is_multisite () && c_ws_plugin__s2member_utils_conds::is_multisite_farm () && !is_main_site ()) ? '' : ' [ <a href="#" onclick="alert(\'If the Payment Notification is for Independent Custom Capabilities, the `level` portion of this string will be an asterisk ( `*` ), since the Membership Level is irrelevant, and remains `as it was` in that scenario. In all other cases, the `level` portion will be a numeric value.\'); return false;">?</a> ]') . '</li>' . "\n";
300
- echo '<li><code>%%item_name%%</code> = The Item Name (as provided by the <code>desc=""</code> attribute in your Shortcode, which briefly describes the Item Number).</li>' . "\n";
301
- echo '<li><code>%%user_first_name%%</code> = The First Name listed on their User account. This might be different than what is on file with your Payment Gateway.</li>' . "\n";
302
- echo '<li><code>%%user_last_name%%</code> = The Last Name listed on their User account. This might be different than what is on file with your Payment Gateway.</li>' . "\n";
303
- echo '<li><code>%%user_full_name%%</code> = The Full Name listed on their User account. This might be different than what is on file with your Payment Gateway.</li>' . "\n";
304
- echo '<li><code>%%user_email%%</code> = The Email Address associated with their User account. This might be different than what is on file with your Payment Gateway.</li>' . "\n";
305
- echo '<li><code>%%user_login%%</code> = The Username associated with their account. The Customer created this during registration.</li>' . "\n";
306
- echo '<li><code>%%user_ip%%</code> = The Customer\'s original IP Address, during checkout/registration via <code>$_SERVER["REMOTE_ADDR"]</code>.</li>' . "\n";
307
- echo '<li><code>%%user_id%%</code> = A unique WordPress User ID that references this account in the WordPress database.</li>' . "\n";
308
- echo '</ul>' . "\n";
309
-
310
- if(c_ws_plugin__s2member_utils_conds::pro_is_installed())
311
- {
312
- echo '<strong>Coupon Replacement Codes (applicable only w/ s2Member Pro Forms):</strong><br />' . "\n";
313
- echo '<em>These are ONLY included with payments that occur during checkout. They will NOT be provided with any future recurring payments.</em>'."\n";
314
- echo '<ul class="ws-menu-page-li-margins">' . "\n";
315
- echo '<li><code>%%full_coupon_code%%</code> = A full Coupon Code — if one is accepted by your configuration of s2Member. This may indicate an Affiliate Coupon Code, which will include your Affiliate Suffix Chars too (i.e. the full Coupon Code).</li>' . "\n";
316
- echo '<li><code>%%coupon_code%%</code> = A Coupon Code — if one is accepted by your configuration of s2Member. This will NOT include any Affiliate Suffix Chars. This indicates the actual Coupon Code accepted by your configuration of s2Member (excluding any Affiliate ID).</li>' . "\n";
317
- echo '<li><code>%%coupon_affiliate_id%%</code> = This is the end of an Affiliate Coupon Code <em>(i.e. the referring affiliate\'s ID)</em>. This is only applicable if an Affiliate Coupon Code is accepted by your configuration of s2Member.</li>' . "\n";
318
- echo '</ul>' . "\n";
319
- }
320
-
321
- echo '<strong>Custom Registration/Profile Fields are also supported in this Notification:</strong>' . "\n";
322
- echo '<ul class="ws-menu-page-li-margins">' . "\n";
323
- echo '<li><code>%%date_of_birth%%</code> would be valid; if you have a Custom Registration/Profile Field with the ID <code>date_of_birth</code>.</li>' . "\n";
324
- echo '<li><code>%%street_address%%</code> would be valid; if you have a Custom Registration/Profile Field with the ID <code>street_address</code>.</li>' . "\n";
325
- echo '<li><code>%%country%%</code> would be valid; if you have a Custom Registration/Profile Field with the ID <code>country</code>.</li>' . "\n";
326
- echo '<li><em><code>%%etc, etc...%%</code> <strong>see:</strong> s2Member -› General Options -› Registration/Profile Fields</em>.</li>' . "\n";
327
- echo '</ul>' . "\n";
328
-
329
- echo '<strong>Custom Replacement Codes can also be inserted using these instructions:</strong>' . "\n";
330
- echo '<ul class="ws-menu-page-li-margins">' . "\n";
331
- echo '<li><code>%%cv0%%</code> = The domain of your site, which is passed through the `custom` attribute in your Shortcode.</li>' . "\n";
332
- echo '<li><code>%%cv1%%</code> = If you need to track additional custom variables, you can pipe delimit them into the `custom` attribute; inside your Shortcode, like this: <code>custom="' . esc_html ($_SERVER["HTTP_HOST"]) . '|cv1|cv2|cv3"</code>. You can have an unlimited number of custom variables. Obviously, this is for advanced webmasters; but the functionality has been made available for those who need it.</li>' . "\n";
333
- echo '</ul>' . "\n";
334
- echo '<strong>This example uses cv1 to record a special marketing campaign:</strong><br />' . "\n";
335
- echo '<em>(The campaign (i.e. christmas-promo) could be referenced using <code>%%cv1%%</code>)</em><br />' . "\n";
336
- echo '<code>custom="' . esc_html ($_SERVER["HTTP_HOST"]) . '|christmas-promo"</code>' . "\n";
337
-
338
- echo '</td>' . "\n";
339
-
340
- echo '</tr>' . "\n";
341
- echo '</tbody>' . "\n";
342
- echo '</table>' . "\n";
343
-
344
- echo '<div class="ws-menu-page-hr"></div>' . "\n";
345
-
346
- echo '<table class="form-table" style="margin-top:0;">' . "\n";
347
- echo '<tbody>' . "\n";
348
- echo '<tr>' . "\n";
349
-
350
- echo '<th style="padding-top:0;">' . "\n";
351
- echo '<label for="ws-plugin--s2member-payment-notification-recipients">' . "\n";
352
- echo 'Send An Email Transaction Log Of This Event?' . "\n";
353
- echo '</label>' . "\n";
354
- echo '</th>' . "\n";
355
-
356
- echo '</tr>' . "\n";
357
- echo '<tr>' . "\n";
358
-
359
- echo '<td>' . "\n";
360
- echo '<input type="text" autocomplete="off" name="ws_plugin__s2member_payment_notification_recipients" id="ws-plugin--s2member-payment-notification-recipients" value="' . format_to_edit ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["payment_notification_recipients"]) . '" /><br />' . "\n";
361
- echo 'This is a semicolon ( ; ) delimited list of Recipients. Here is an example:<br />' . "\n";
362
- echo '<code>"John" &lt;john@example.com&gt;; admin@example.com; "Webmaster" &lt;webmaster@example.com&gt;</code>' . "\n";
363
- echo '</td>' . "\n";
364
-
365
- echo '</tr>' . "\n";
366
- echo '</tbody>' . "\n";
367
- echo '</table>' . "\n";
368
- echo '</div>' . "\n";
369
-
370
- echo '</div>' . "\n";
371
-
372
- do_action("ws_plugin__s2member_during_api_ops_page_during_left_sections_after_payment_notifications", get_defined_vars ());
373
- }
374
-
375
- if (apply_filters("ws_plugin__s2member_during_api_ops_page_during_left_sections_display_modification_notifications", true, get_defined_vars ()))
376
- {
377
- do_action("ws_plugin__s2member_during_api_ops_page_during_left_sections_before_modification_notifications", get_defined_vars ());
378
-
379
- echo '<div class="ws-menu-page-group" title="Modification Notifications">' . "\n";
380
-
381
- echo '<div class="ws-menu-page-section ws-plugin--s2member-modification-notifications-section">' . "\n";
382
- echo '<h3>Modification Notification URLs (optional)</h3>' . "\n";
383
- echo '<p>If you use affiliate software, or have back-office routines that need to be notified each time a new Subscription is created by an "existing" User/Member, or an "existing" Member modifies their paid Subscription terms, you\'ll want to read this section. This is marked `Modification`, because the URLs that you list below, will be notified each time an "existing" User/Member <em>(even if they are/were a Free Subscriber)</em> signs up for a paid Subscription <em>(i.e. a Modification takes place against an existing account within WordPress)</em>, or an "existing" Member modifies their paid Subscription terms <em>(again, a Modification takes places against an existing account within WordPress)</em>. Depending on your fee structure, this may include a payment that establishes their Subscription, or it may not.</p>' . "\n";
384
- echo '<p>Modification Notifications are sent right after a Member signs up and/or modifies billing terms successfully through your Payment Gateway, regardless of whether any money has actually been transacted. In other words, this Notification is triggered, even if you provided them with something for free <em>(i.e. even if no money is being transacted)</em>.</p>' . "\n";
385
- echo '<p>This Notification will NOT be processed for "new" Users/Members <em>(see: Signup Notifications for that scenario)</em>.' . ((is_multisite () && c_ws_plugin__s2member_utils_conds::is_multisite_farm () && !is_main_site ()) ? '' : ' And, this Notification will NOT be processed for Independent Custom Capability purchases <em>(see: Payment Notifications for that scenario)</em>.') . '</p>' . "\n";
386
- echo '<p>Please note, this feature is not to be confused with the PayPal IPN service. PayPal IPN <em>(and other service integrations)</em> are already built into s2Member. They remain active at all times. These Modification Notifications are an added layer of functionality, and they are completely optional.</p>' . "\n";
387
- echo '<p><strong>See also:</strong> This KB article: <a href="http://www.s2member.com/kb/building-an-api-notification-handler/" target="_blank" rel="external">Building An API Notification Handler</a>.</p>'."\n";
388
- do_action("ws_plugin__s2member_during_api_ops_page_during_left_sections_during_modification_notifications", get_defined_vars ());
389
-
390
- echo '<table class="form-table">' . "\n";
391
- echo '<tbody>' . "\n";
392
- echo '<tr>' . "\n";
393
-
394
- echo '<th>' . "\n";
395
- echo '<label for="ws-plugin--s2member-modification-notification-urls">' . "\n";
396
- echo 'Modification Notification URLs:' . "\n";
397
- echo '</label>' . "\n";
398
- echo '</th>' . "\n";
399
-
400
- echo '</tr>' . "\n";
401
- echo '<tr>' . "\n";
402
-
403
- echo '<td>' . "\n";
404
- echo 'You can input multiple Notification URLs by inserting one per line.<br />' . "\n";
405
- echo '<textarea name="ws_plugin__s2member_modification_notification_urls" id="ws-plugin--s2member-modification-notification-urls" rows="3" wrap="off">' . format_to_edit ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["modification_notification_urls"]) . '</textarea><br />' . "\n";
406
- echo 'Modification Notifications take place silently behind-the-scene, using an HTTP connection.<br /><br />' . "\n";
407
- echo '<strong>You can also use these special Replacement Codes if you need them:</strong>' . "\n";
408
- echo '<ul class="ws-menu-page-li-margins">' . "\n";
409
- echo '<li><code>%%subscr_id%%</code> = The Paid Subscription ID, which remains constant throughout any &amp; all future payments. [ <a href="#" onclick="alert(\'There is one exception. If you are selling Lifetime or Fixed-Term (non-recurring) access, using Buy Now functionality; the %%subscr_id%% is actually set to the Transaction ID for the purchase. Payment Gateways do not provide a specific Subscription ID for Buy Now purchases. Since Lifetime &amp; Fixed-Term Subscriptions are NOT recurring (i.e. there is only ONE payment), using the Transaction ID as the Subscription ID is a graceful way to deal with this minor conflict.\'); return false;">?</a> ]</li>' . "\n";
410
- echo '<li><code>%%subscr_baid%%</code> = Applicable only with PayPal Pro (Payflow Edition); and only for Express Checkout transactions that require a Billing Agreement. This is the Subscription\'s Billing Agreement ID, which remains constant throughout any &amp; all future payments. [ <a href="#" onclick="alert(\'Applicable only with PayPal Pro (Payflow Edition); and only for Express Checkout transactions that require a Billing Agreement. In all other cases, the %%subscr_baid%% is simply set to the %%subscr_id%% value; i.e. it is a duplicate of %%subscr_id%% in most cases.\'); return false;">?</a> ]</li>' . "\n";
411
- echo '<li><code>%%subscr_cid%%</code> = Applicable only with Stripe integration. This is the Customer\'s ID in Stripe, which remains constant throughout any &amp; all future payments. Each Stripe Customer has this Customer ID; and also a Subscription and/or Transaction ID [ <a href="#" onclick="alert(\'Applicable only when you integrate s2Member with Stripe. In all other cases, the %%subscr_cid%% is simply set to the %%subscr_id%% value; i.e. it is a duplicate of %%subscr_id%% when running anything other than Stripe.\\n\\nEach Stripe Customer has a Customer ID; and also a Subscription and/or Transaction ID. See %%subscr_id%% for further details.\'); return false;">?</a> ]</li>' . "\n";
412
- echo '<li><code>%%initial%%</code> = The Initial Fee. If you offered a 100% Free Trial, this will be <code>0</code>. [ <a href="#" onclick="alert(\'This will always represent the amount of money the Customer spent when they completed checkout, no matter what. Even if that amount is 0.\\n\\nIf a Customer upgrades/downgrades under the terms of a 100% Free Trial Period, this will be 0. So, please be careful using %%initial%% when you offer a 100% Free Trial Period, because a $0.00 sale amount could cause havoc with affiliate programs.\\n\\nIf you\\\'re offering a 100% Free Trial Period, and you need to track sales through affiliate programs, you can either hard-code an amount; or use `Payment Notifications` instead.\'); return false;">?</a> ]</li>' . "\n";
413
- echo '<li><code>%%regular%%</code> = The Regular Amount of the Subscription. If you offer something 100% free, this will be <code>0</code>. [ <a href="#" onclick="alert(\'This is how much the Subscription costs after an Initial Period expires. If you did NOT offer an Initial Period at a different price, %%initial%% and %%regular%% will be equal to the same thing.\'); return false;">?</a> ]</li>' . "\n";
414
- echo '<li><code>%%recurring%%</code> = This is the amount that will be charged on a recurring basis, or <code>0</code> if non-recurring. [ <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.\'); return false;">?</a> ]</li>' . "\n";
415
- echo '<li><code>%%first_name%%</code> = The First Name of the Customer who purchased the Membership Subscription.</li>' . "\n";
416
- echo '<li><code>%%last_name%%</code> = The Last Name of the Customer who purchased the Membership Subscription.</li>' . "\n";
417
- echo '<li><code>%%full_name%%</code> = The Full Name (First &amp; Last) of the Customer who purchased the Membership Subscription.</li>' . "\n";
418
- echo '<li><code>%%payer_email%%</code> = The Email Address of the Customer who purchased the Membership Subscription.</li>' . "\n";
419
- echo '<li><code>%%item_number%%</code> = The Item Number (colon separated <code><em>level:custom_capabilities:fixed term</em></code>) for the Membership Subscription.</li>' . "\n";
420
- echo '<li><code>%%item_name%%</code> = The Item Name (as provided by the <code>desc=""</code> attribute in your Shortcode, which briefly describes the Item Number).</li>' . "\n";
421
- echo '<li><code>%%initial_term%%</code> = This is the term length of the Initial Period. This will be a numeric value, followed by a space, then a single letter. [ <a href="#" onclick="alert(\'Here are some examples:\\n\\n%%initial_term%% = 1 D (this means 1 Day)\\n%%initial_term%% = 1 W (this means 1 Week)\\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.\'); return false;">?</a> ]</li>' . "\n";
422
- echo '<li><code>%%regular_term%%</code> = This is the term length of the Regular Period. This will be a numeric value, followed by a space, then a single letter. [ <a href="#" onclick="alert(\'Here are some examples:\\n\\n%%regular_term%% = 1 D (this means 1 Day)\\n%%regular_term%% = 1 W (this means 1 Week)\\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";
423
- echo '<li><code>%%user_first_name%%</code> = The First Name listed on their User account. This might be different than what is on file with your Payment Gateway.</li>' . "\n";
424
- echo '<li><code>%%user_last_name%%</code> = The Last Name listed on their User account. This might be different than what is on file with your Payment Gateway.</li>' . "\n";
425
- echo '<li><code>%%user_full_name%%</code> = The Full Name listed on their User account. This might be different than what is on file with your Payment Gateway.</li>' . "\n";
426
- echo '<li><code>%%user_email%%</code> = The Email Address associated with their User account. This might be different than what is on file with your Payment Gateway.</li>' . "\n";
427
- echo '<li><code>%%user_login%%</code> = The Username associated with their account. The Customer created this during registration.</li>' . "\n";
428
- echo '<li><code>%%user_ip%%</code> = The Customer\'s original IP Address, during checkout/registration via <code>$_SERVER["REMOTE_ADDR"]</code>.</li>' . "\n";
429
- echo '<li><code>%%user_id%%</code> = A unique WordPress User ID that references this account in the WordPress database.</li>' . "\n";
430
- echo '</ul>' . "\n";
431
-
432
- if(c_ws_plugin__s2member_utils_conds::pro_is_installed())
433
- {
434
- echo '<strong>Coupon Replacement Codes (applicable only w/ s2Member Pro Forms):</strong>' . "\n";
435
- echo '<ul class="ws-menu-page-li-margins">' . "\n";
436
- echo '<li><code>%%full_coupon_code%%</code> = A full Coupon Code — if one is accepted by your configuration of s2Member. This may indicate an Affiliate Coupon Code, which will include your Affiliate Suffix Chars too (i.e. the full Coupon Code).</li>' . "\n";
437
- echo '<li><code>%%coupon_code%%</code> = A Coupon Code — if one is accepted by your configuration of s2Member. This will NOT include any Affiliate Suffix Chars. This indicates the actual Coupon Code accepted by your configuration of s2Member (excluding any Affiliate ID).</li>' . "\n";
438
- echo '<li><code>%%coupon_affiliate_id%%</code> = This is the end of an Affiliate Coupon Code <em>(i.e. the referring affiliate\'s ID)</em>. This is only applicable if an Affiliate Coupon Code is accepted by your configuration of s2Member.</li>' . "\n";
439
- echo '</ul>' . "\n";
440
- }
441
-
442
- echo '<strong>Custom Registration/Profile Fields are also supported in this Notification:</strong>' . "\n";
443
- echo '<ul class="ws-menu-page-li-margins">' . "\n";
444
- echo '<li><code>%%date_of_birth%%</code> would be valid; if you have a Custom Registration/Profile Field with the ID <code>date_of_birth</code>.</li>' . "\n";
445
- echo '<li><code>%%street_address%%</code> would be valid; if you have a Custom Registration/Profile Field with the ID <code>street_address</code>.</li>' . "\n";
446
- echo '<li><code>%%country%%</code> would be valid; if you have a Custom Registration/Profile Field with the ID <code>country</code>.</li>' . "\n";
447
- echo '<li><em><code>%%etc, etc...%%</code> <strong>see:</strong> s2Member -› General Options -› Registration/Profile Fields</em>.</li>' . "\n";
448
- echo '</ul>' . "\n";
449
-
450
- echo '<strong>Custom Replacement Codes can also be inserted using these instructions:</strong>' . "\n";
451
- echo '<ul class="ws-menu-page-li-margins">' . "\n";
452
- echo '<li><code>%%cv0%%</code> = The domain of your site, which is passed through the `custom` attribute in your Shortcode.</li>' . "\n";
453
- echo '<li><code>%%cv1%%</code> = If you need to track additional custom variables, you can pipe delimit them into the `custom` attribute; inside your Shortcode, like this: <code>custom="' . esc_html ($_SERVER["HTTP_HOST"]) . '|cv1|cv2|cv3"</code>. You can have an unlimited number of custom variables. Obviously, this is for advanced webmasters; but the functionality has been made available for those who need it.</li>' . "\n";
454
- echo '</ul>' . "\n";
455
- echo '<strong>This example uses cv1 to record a special marketing campaign:</strong><br />' . "\n";
456
- echo '<em>(The campaign (i.e. christmas-promo) could be referenced using <code>%%cv1%%</code>)</em><br />' . "\n";
457
- echo '<code>custom="' . esc_html ($_SERVER["HTTP_HOST"]) . '|christmas-promo"</code>' . "\n";
458
-
459
- echo '</td>' . "\n";
460
-
461
- echo '</tr>' . "\n";
462
- echo '</tbody>' . "\n";
463
- echo '</table>' . "\n";
464
-
465
- echo '<div class="ws-menu-page-hr"></div>' . "\n";
466
-
467
- echo '<table class="form-table" style="margin-top:0;">' . "\n";
468
- echo '<tbody>' . "\n";
469
- echo '<tr>' . "\n";
470
-
471
- echo '<th style="padding-top:0;">' . "\n";
472
- echo '<label for="ws-plugin--s2member-modification-notification-recipients">' . "\n";
473
- echo 'Send An Email Transaction Log Of This Event?' . "\n";
474
- echo '</label>' . "\n";
475
- echo '</th>' . "\n";
476
-
477
- echo '</tr>' . "\n";
478
- echo '<tr>' . "\n";
479
-
480
- echo '<td>' . "\n";
481
- echo '<input type="text" autocomplete="off" name="ws_plugin__s2member_modification_notification_recipients" id="ws-plugin--s2member-modification-notification-recipients" value="' . format_to_edit ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["modification_notification_recipients"]) . '" /><br />' . "\n";
482
- echo 'This is a semicolon ( ; ) delimited list of Recipients. Here is an example:<br />' . "\n";
483
- echo '<code>"John" &lt;john@example.com&gt;; admin@example.com; "Webmaster" &lt;webmaster@example.com&gt;</code>' . "\n";
484
- echo '</td>' . "\n";
485
-
486
- echo '</tr>' . "\n";
487
- echo '</tbody>' . "\n";
488
- echo '</table>' . "\n";
489
- echo '</div>' . "\n";
490
-
491
- echo '</div>' . "\n";
492
- }
493
-
494
- if (apply_filters("ws_plugin__s2member_during_api_ops_page_during_left_sections_display_cancellation_notifications", true, get_defined_vars ()))
495
- {
496
- do_action("ws_plugin__s2member_during_api_ops_page_during_left_sections_before_cancellation_notifications", get_defined_vars ());
497
-
498
- echo '<div class="ws-menu-page-group" title="Cancellation Notifications">' . "\n";
499
-
500
- echo '<div class="ws-menu-page-section ws-plugin--s2member-cancellation-notifications-section">' . "\n";
501
- echo '<h3>Cancellation Notification URLs (optional)</h3>' . "\n";
502
- echo '<p>If you use affiliate software, or have back-office routines that need to be notified whenever Subscriptions are cancelled through your Payment Gateway, you\'ll want to read this section. This is marked `Cancellation`, because the URLs that you list below, will be notified each time a Subscription is cancelled. A Cancellation is triggered when you cancel a Customer\'s Subscription through your Payment Gateway, or when a Customer cancels their own Subscription.</p>' . "\n";
503
- echo '<p>Please note, this feature is not to be confused with the PayPal IPN service. PayPal IPN <em>(and other service integrations)</em> are already built into s2Member. They remain active at all times. These Cancellation Notifications are an added layer of functionality, and they are completely optional.</p>' . "\n";
504
- echo '<p><em><strong>*Understanding Cancellations*</strong> It\'s important to realize that a Cancellation is not an EOT (End Of Term). All that happens during a Cancellation event, is that billing is stopped, and it\'s understood that the Customer is going to lose access, at some point in the future. This does NOT mean, that access will be revoked immediately. A separate EOT event will automatically handle a (demotion or deletion) later, at the appropriate time; which could be several days, or even a year after the Cancellation took place.</em></p>' . "\n";
505
- echo '<p><em><strong>*Some Hairy Details*</strong> There might be times whenever you notice that a Member\'s Subscription has been cancelled through your Payment Gateway... but, s2Member continues allowing the User access to your site as a paid Member. Please don\'t be confused by this... in 99.9% of these cases, the reason for this is legitimate. s2Member will only remove the User\'s Membership privileges when an EOT (End Of Term) is processed, a refund occurs, a chargeback occurs, or when a cancellation occurs - which would later result in a delayed Auto-EOT by s2Member.</em></p>' . "\n";
506
- echo '<p><em>s2Member will not process an EOT (End Of Term) until the User has completely used up the time they paid for. In other words, if a User signs up for a monthly Subscription on Jan 1st, and then cancels their Subscription on Jan 15th; technically, they should still be allowed to access the site for another 15 days, and then on Feb 1st, the time they paid for has completely elapsed. At that time, s2Member will remove their Membership privileges; by either demoting them to a Free Subscriber, or deleting their account from the system (based on your configuration). s2Member also calculates one extra day (24 hours) into its equation, just to make sure access is not removed sooner than a Customer might expect.</em></p>' . "\n";
507
- echo '<p><strong>See also:</strong> This KB article: <a href="http://www.s2member.com/kb/building-an-api-notification-handler/" target="_blank" rel="external">Building An API Notification Handler</a>.</p>'."\n";
508
- do_action("ws_plugin__s2member_during_api_ops_page_during_left_sections_during_cancellation_notifications", get_defined_vars ());
509
-
510
- echo '<table class="form-table">' . "\n";
511
- echo '<tbody>' . "\n";
512
- echo '<tr>' . "\n";
513
-
514
- echo '<th>' . "\n";
515
- echo '<label for="ws-plugin--s2member-cancellation-notification-urls">' . "\n";
516
- echo 'Cancellation Notification URLs:' . "\n";
517
- echo '</label>' . "\n";
518
- echo '</th>' . "\n";
519
-
520
- echo '</tr>' . "\n";
521
- echo '<tr>' . "\n";
522
-
523
- echo '<td>' . "\n";
524
- echo 'You can input multiple Notification URLs by inserting one per line.<br />' . "\n";
525
- echo '<textarea name="ws_plugin__s2member_cancellation_notification_urls" id="ws-plugin--s2member-cancellation-notification-urls" rows="3" wrap="off">' . format_to_edit ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["cancellation_notification_urls"]) . '</textarea><br />' . "\n";
526
- echo 'Cancellation Notifications take place silently behind-the-scene, using an HTTP connection.<br /><br />' . "\n";
527
- echo '<strong>You can also use these special Replacement Codes if you need them:</strong>' . "\n";
528
- echo '<ul class="ws-menu-page-li-margins">' . "\n";
529
- echo '<li><code>%%subscr_id%%</code> = The Paid Subscription ID, which remained constant throughout the lifetime of the Membership. [ <a href="#" onclick="alert(\'There is one exception. If you are selling Lifetime or Fixed-Term (non-recurring) access, using Buy Now functionality; the %%subscr_id%% is actually set to the original Transaction ID for the purchase. Payment Gateways do not provide a specific Subscription ID for Buy Now purchases. Since Lifetime &amp; Fixed-Term Subscriptions are NOT recurring (i.e. there was only ONE payment), using the Transaction ID as the Subscription ID is a graceful way to deal with this minor conflict.\'); return false;">?</a> ]</li>' . "\n";
530
- echo '<li><code>%%subscr_baid%%</code> = Applicable only with PayPal Pro (Payflow Edition); and only for Express Checkout transactions that required a Billing Agreement. This is the Subscription\'s Billing Agreement ID, which remained constant throughout the lifetime of the Membership. [ <a href="#" onclick="alert(\'Applicable only with PayPal Pro (Payflow Edition); and only for Express Checkout transactions that required a Billing Agreement. In all other cases, the %%subscr_baid%% is simply set to the %%subscr_id%% value; i.e. it is a duplicate of %%subscr_id%% in most cases.\'); return false;">?</a> ]</li>' . "\n";
531
- echo '<li><code>%%subscr_cid%%</code> = Applicable only with Stripe integration. This is the Customer\'s ID in Stripe, which remained constant throughout the lifetime of the Membership. Each Stripe Customer has this Customer ID; and also a Subscription and/or Transaction ID [ <a href="#" onclick="alert(\'Applicable only when you integrate s2Member with Stripe. In all other cases, the %%subscr_cid%% is simply set to the %%subscr_id%% value; i.e. it is a duplicate of %%subscr_id%% when running anything other than Stripe.\\n\\nEach Stripe Customer has a Customer ID; and also a Subscription and/or Transaction ID. See %%subscr_id%% for further details.\'); return false;">?</a> ]</li>' . "\n";
532
- echo '<li><code>%%item_number%%</code> = The Item Number (colon separated <em>level:custom_capabilities:fixed term</em>) that the Subscription was for.</li>' . "\n";
533
- echo '<li><code>%%item_name%%</code> = The Item Name (as provided by the <code>desc=""</code> attribute in your Shortcode, which briefly describes the Item Number).</li>' . "\n";
534
- echo '<li><code>%%user_first_name%%</code> = The First Name listed on their User account. This might be different than what is on file with your Payment Gateway.</li>' . "\n";
535
- echo '<li><code>%%user_last_name%%</code> = The Last Name listed on their User account. This might be different than what is on file with your Payment Gateway.</li>' . "\n";
536
- echo '<li><code>%%user_full_name%%</code> = The Full Name listed on their User account. This might be different than what is on file with your Payment Gateway.</li>' . "\n";
537
- echo '<li><code>%%user_email%%</code> = The Email Address associated with their User account. This might be different than what is on file with your Payment Gateway.</li>' . "\n";
538
- echo '<li><code>%%user_login%%</code> = The Username associated with their account. The Customer created this during registration.</li>' . "\n";
539
- echo '<li><code>%%user_ip%%</code> = The Customer\'s original IP Address, during checkout/registration via <code>$_SERVER["REMOTE_ADDR"]</code>.</li>' . "\n";
540
- echo '<li><code>%%user_id%%</code> = A unique WordPress User ID that references this account in the WordPress database.</li>' . "\n";
541
- echo '</ul>' . "\n";
542
-
543
- echo '<strong>Custom Registration/Profile Fields are also supported in this Notification:</strong>' . "\n";
544
- echo '<ul class="ws-menu-page-li-margins">' . "\n";
545
- echo '<li><code>%%date_of_birth%%</code> would be valid; if you have a Custom Registration/Profile Field with the ID <code>date_of_birth</code>.</li>' . "\n";
546
- echo '<li><code>%%street_address%%</code> would be valid; if you have a Custom Registration/Profile Field with the ID <code>street_address</code>.</li>' . "\n";
547
- echo '<li><code>%%country%%</code> would be valid; if you have a Custom Registration/Profile Field with the ID <code>country</code>.</li>' . "\n";
548
- echo '<li><em><code>%%etc, etc...%%</code> <strong>see:</strong> s2Member -› General Options -› Registration/Profile Fields</em>.</li>' . "\n";
549
- echo '</ul>' . "\n";
550
-
551
- echo '<strong>Custom Replacement Codes can also be inserted using these instructions:</strong>' . "\n";
552
- echo '<ul class="ws-menu-page-li-margins">' . "\n";
553
- echo '<li><code>%%cv0%%</code> = The domain of your site, which is passed through the `custom` attribute in your Shortcode.</li>' . "\n";
554
- echo '<li><code>%%cv1%%</code> = If you need to track additional custom variables, you can pipe delimit them into the `custom` attribute; inside your Shortcode, like this: <code>custom="' . esc_html ($_SERVER["HTTP_HOST"]) . '|cv1|cv2|cv3"</code>. You can have an unlimited number of custom variables. Obviously, this is for advanced webmasters; but the functionality has been made available for those who need it.</li>' . "\n";
555
- echo '</ul>' . "\n";
556
- echo '<strong>This example uses cv1 to record a special marketing campaign:</strong><br />' . "\n";
557
- echo '<em>(The campaign (i.e. christmas-promo) could be referenced using <code>%%cv1%%</code>)</em><br />' . "\n";
558
- echo '<code>custom="' . esc_html ($_SERVER["HTTP_HOST"]) . '|christmas-promo"</code>' . "\n";
559
-
560
- echo '</td>' . "\n";
561
-
562
- echo '</tr>' . "\n";
563
- echo '</tbody>' . "\n";
564
- echo '</table>' . "\n";
565
-
566
- echo '<div class="ws-menu-page-hr"></div>' . "\n";
567
-
568
- echo '<table class="form-table" style="margin-top:0;">' . "\n";
569
- echo '<tbody>' . "\n";
570
- echo '<tr>' . "\n";
571
-
572
- echo '<th style="padding-top:0;">' . "\n";
573
- echo '<label for="ws-plugin--s2member-cancellation-notification-recipients">' . "\n";
574
- echo 'Send An Email Transaction Log Of This Event?' . "\n";
575
- echo '</label>' . "\n";
576
- echo '</th>' . "\n";
577
-
578
- echo '</tr>' . "\n";
579
- echo '<tr>' . "\n";
580
-
581
- echo '<td>' . "\n";
582
- echo '<input type="text" autocomplete="off" name="ws_plugin__s2member_cancellation_notification_recipients" id="ws-plugin--s2member-cancellation-notification-recipients" value="' . format_to_edit ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["cancellation_notification_recipients"]) . '" /><br />' . "\n";
583
- echo 'This is a semicolon ( ; ) delimited list of Recipients. Here is an example:<br />' . "\n";
584
- echo '<code>"John" &lt;john@example.com&gt;; admin@example.com; "Webmaster" &lt;webmaster@example.com&gt;</code>' . "\n";
585
- echo '</td>' . "\n";
586
-
587
- echo '</tr>' . "\n";
588
- echo '</tbody>' . "\n";
589
- echo '</table>' . "\n";
590
- echo '</div>' . "\n";
591
-
592
- echo '</div>' . "\n";
593
-
594
- do_action("ws_plugin__s2member_during_api_ops_page_during_left_sections_after_cancellation_notifications", get_defined_vars ());
595
- }
596
-
597
- if (apply_filters("ws_plugin__s2member_during_api_ops_page_during_left_sections_display_eot_deletion_notifications", true, get_defined_vars ()))
598
- {
599
- do_action("ws_plugin__s2member_during_api_ops_page_during_left_sections_before_eot_deletion_notifications", get_defined_vars ());
600
-
601
- echo '<div class="ws-menu-page-group" title="EOT/Deletion Notifications">' . "\n";
602
-
603
- echo '<div class="ws-menu-page-section ws-plugin--s2member-eot-deletion-notifications-section">' . "\n";
604
- echo '<h3>EOT/Deletion Notification URLs (optional)</h3>' . "\n";
605
- echo '<p>If you use affiliate software, or have back-office routines that need to be notified whenever Subscriptions have ended <em>(and a Member is demoted to a Free Subscriber)</em>, 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.</p>' . "\n";
606
- echo '<p><strong>EOT = End Of Term.</strong> An EOT is triggered <em>immediately</em> when you refund a Customer, when a Customer forces a chargeback to occur, or when a paid Subscription ends naturally <em>(i.e. expires)</em>, and your Payment Gateway sends s2Member an EOT (End Of Term) response. Delayed EOTs occur after a Cancellation, either as a result of you cancelling a Customer\'s Subscription, or a Customer cancelling their own Subscription. A Cancellation usually results in a delayed EOT, because a Cancellation does NOT always warrant an immediate action; there could still be time left on their Subscription.</p>' . "\n";
607
- echo '<p>Manual Deletions will trigger this Notification too. If you delete an account manually from within your WordPress Dashboard, your URLs can be notified automatically through this API Notification, and this scenario can be detected through the Replacement Code <code>%%eot_del_type%%</code>, which is documented below. So the two events are an EOT <em>(of any kind)</em> and/or a Manual Deletion.</p>' . "\n";
608
- echo '<p>Please note, this feature is not to be confused with the PayPal IPN service. PayPal IPN <em>(and other service integrations)</em> are already built into s2Member. They remain active at all times. These EOT/Deletion Notifications are an added layer of functionality, and they are completely optional.</p>' . "\n";
609
- echo '<p><em><strong>*Some Hairy Details*</strong> There might be times whenever you notice that a Member\'s Subscription has been cancelled through your Payment Gateway... but, s2Member continues allowing the User access to your site as a paid Member. Please don\'t be confused by this... in 99.9% of these cases, the reason for this is legitimate. s2Member will only remove the User\'s Membership privileges when an EOT (End Of Term) is processed, a refund occurs, a chargeback occurs, or when a cancellation occurs - which would later result in a delayed Auto-EOT by s2Member.</em></p>' . "\n";
610
- echo '<p><em>s2Member will not process an EOT (End Of Term) until the User has completely used up the time they paid for. In other words, if a User signs up for a monthly Subscription on Jan 1st, and then cancels their Subscription on Jan 15th; technically, they should still be allowed to access the site for another 15 days, and then on Feb 1st, the time they paid for has completely elapsed. At that time, s2Member will remove their Membership privileges; by either demoting them to a Free Subscriber, or deleting their account from the system (based on your configuration). s2Member also calculates one extra day (24 hours) into its equation, just to make sure access is not removed sooner than a Customer might expect.</em></p>' . "\n";
611
- echo '<p><strong>See also:</strong> This KB article: <a href="http://www.s2member.com/kb/building-an-api-notification-handler/" target="_blank" rel="external">Building An API Notification Handler</a>.</p>'."\n";
612
- do_action("ws_plugin__s2member_during_api_ops_page_during_left_sections_during_eot_deletion_notifications", get_defined_vars ());
613
-
614
- echo '<table class="form-table">' . "\n";
615
- echo '<tbody>' . "\n";
616
- echo '<tr>' . "\n";
617
-
618
- echo '<th>' . "\n";
619
- echo '<label for="ws-plugin--s2member-eot-del-notification-urls">' . "\n";
620
- echo 'EOT/Deletion Notification URLs:' . "\n";
621
- echo '</label>' . "\n";
622
- echo '</th>' . "\n";
623
-
624
- echo '</tr>' . "\n";
625
- echo '<tr>' . "\n";
626
-
627
- echo '<td>' . "\n";
628
- echo 'You can input multiple Notification URLs by inserting one per line.<br />' . "\n";
629
- 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";
630
- echo 'EOT/Deletion Notifications take place silently behind-the-scene, using an HTTP connection.<br /><br />' . "\n";
631
- echo '<strong>You can also use these special Replacement Codes if you need them:</strong>' . "\n";
632
- echo '<ul class="ws-menu-page-li-margins">' . "\n";
633
- echo '<li><code>%%eot_del_type%%</code> = The type of event that triggered this Notification. [ <a href="#" onclick="alert(\'List of possible values:\\n\\nuser-removal-deletion (i.e. manual removal/deletion)\\nauto-eot-cancellation-expiration-demotion\\nauto-eot-cancellation-expiration-deletion\\nipn-cancellation-expiration-demotion\\nipn-cancellation-expiration-deletion\\nipn-refund-reversal-demotion\\nipn-refund-reversal-deletion\'); return false;">list of possible values</a> ]</li>' . "\n";
634
- echo '<li><code>%%subscr_id%%</code> = The Paid Subscription ID, which remained constant throughout the lifetime of the Membership. [ <a href="#" onclick="alert(\'There is one exception. If you are selling Lifetime or Fixed-Term (non-recurring) access, using Buy Now functionality; the %%subscr_id%% is actually set to the original Transaction ID for the purchase. Payment Gateways do not provide a specific Subscription ID for Buy Now purchases. Since Lifetime &amp; Fixed-Term Subscriptions are NOT recurring (i.e. there was only ONE payment), using the Transaction ID as the Subscription ID is a graceful way to deal with this minor conflict.\'); return false;">?</a> ]</li>' . "\n";
635
- echo '<li><code>%%subscr_baid%%</code> = Applicable only with PayPal Pro (Payflow Edition); and only for Express Checkout transactions that required a Billing Agreement. This is the Subscription\'s Billing Agreement ID, which remained constant throughout the lifetime of the Membership. [ <a href="#" onclick="alert(\'Applicable only with PayPal Pro (Payflow Edition); and only for Express Checkout transactions that required a Billing Agreement. In all other cases, the %%subscr_baid%% is simply set to the %%subscr_id%% value; i.e. it is a duplicate of %%subscr_id%% in most cases.\'); return false;">?</a> ]</li>' . "\n";
636
- echo '<li><code>%%subscr_cid%%</code> = Applicable only with Stripe integration. This is the Customer\'s ID in Stripe, which remained constant throughout the lifetime of the Membership. Each Stripe Customer has this Customer ID; and also a Subscription and/or Transaction ID [ <a href="#" onclick="alert(\'Applicable only when you integrate s2Member with Stripe. In all other cases, the %%subscr_cid%% is simply set to the %%subscr_id%% value; i.e. it is a duplicate of %%subscr_id%% when running anything other than Stripe.\\n\\nEach Stripe Customer has a Customer ID; and also a Subscription and/or Transaction ID. See %%subscr_id%% for further details.\'); return false;">?</a> ]</li>' . "\n";
637
- echo '<li><code>%%user_first_name%%</code> = The First Name listed on their User account. This might be different than what is on file with your Payment Gateway.</li>' . "\n";
638
- echo '<li><code>%%user_last_name%%</code> = The Last Name listed on their User account. This might be different than what is on file with your Payment Gateway.</li>' . "\n";
639
- echo '<li><code>%%user_full_name%%</code> = The Full Name listed on their User account. This might be different than what is on file with your Payment Gateway.</li>' . "\n";
640
- echo '<li><code>%%user_email%%</code> = The Email Address associated with their User account. This might be different than what is on file with your Payment Gateway.</li>' . "\n";
641
- echo '<li><code>%%user_login%%</code> = The Username associated with their account. The Customer created this during registration.</li>' . "\n";
642
- echo '<li><code>%%user_ip%%</code> = The Customer\'s original IP Address, during checkout/registration via <code>$_SERVER["REMOTE_ADDR"]</code>.</li>' . "\n";
643
- echo '<li><code>%%user_id%%</code> = A unique WordPress User ID that references this account in the WordPress database.</li>' . "\n";
644
- echo '</ul>' . "\n";
645
-
646
- echo '<strong>Custom Registration/Profile Fields are also supported in this Notification:</strong>' . "\n";
647
- echo '<ul class="ws-menu-page-li-margins">' . "\n";
648
- echo '<li><code>%%date_of_birth%%</code> would be valid; if you have a Custom Registration/Profile Field with the ID <code>date_of_birth</code>.</li>' . "\n";
649
- echo '<li><code>%%street_address%%</code> would be valid; if you have a Custom Registration/Profile Field with the ID <code>street_address</code>.</li>' . "\n";
650
- echo '<li><code>%%country%%</code> would be valid; if you have a Custom Registration/Profile Field with the ID <code>country</code>.</li>' . "\n";
651
- echo '<li><em><code>%%etc, etc...%%</code> <strong>see:</strong> s2Member -› General Options -› Registration/Profile Fields</em>.</li>' . "\n";
652
- echo '</ul>' . "\n";
653
-
654
- echo '<strong>Custom Replacement Codes can also be inserted using these instructions:</strong>' . "\n";
655
- echo '<ul class="ws-menu-page-li-margins">' . "\n";
656
- echo '<li><code>%%cv0%%</code> = The domain of your site, which is passed through the `custom` attribute in your Shortcode.</li>' . "\n";
657
- echo '<li><code>%%cv1%%</code> = If you need to track additional custom variables, you can pipe delimit them into the `custom` attribute; inside your Shortcode, like this: <code>custom="' . esc_html ($_SERVER["HTTP_HOST"]) . '|cv1|cv2|cv3"</code>. You can have an unlimited number of custom variables. Obviously, this is for advanced webmasters; but the functionality has been made available for those who need it.</li>' . "\n";
658
- echo '</ul>' . "\n";
659
- echo '<strong>This example uses cv1 to record a special marketing campaign:</strong><br />' . "\n";
660
- echo '<em>(The campaign (i.e. christmas-promo) could be referenced using <code>%%cv1%%</code>)</em><br />' . "\n";
661
- echo '<code>custom="' . esc_html ($_SERVER["HTTP_HOST"]) . '|christmas-promo"</code>' . "\n";
662
-
663
- echo '</td>' . "\n";
664
-
665
- echo '</tr>' . "\n";
666
- echo '</tbody>' . "\n";
667
- echo '</table>' . "\n";
668
-
669
- echo '<div class="ws-menu-page-hr"></div>' . "\n";
670
-
671
- echo '<table class="form-table" style="margin-top:0;">' . "\n";
672
- echo '<tbody>' . "\n";
673
- echo '<tr>' . "\n";
674
-
675
- echo '<th style="padding-top:0;">' . "\n";
676
- echo '<label for="ws-plugin--s2member-eot-del-notification-recipients">' . "\n";
677
- echo 'Send An Email Transaction Log Of This Event?' . "\n";
678
- echo '</label>' . "\n";
679
- echo '</th>' . "\n";
680
-
681
- echo '</tr>' . "\n";
682
- echo '<tr>' . "\n";
683
-
684
- echo '<td>' . "\n";
685
- echo '<input type="text" autocomplete="off" name="ws_plugin__s2member_eot_del_notification_recipients" id="ws-plugin--s2member-eot-del-notification-recipients" value="' . format_to_edit ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["eot_del_notification_recipients"]) . '" /><br />' . "\n";
686
- echo 'This is a semicolon ( ; ) delimited list of Recipients. Here is an example:<br />' . "\n";
687
- echo '<code>"John" &lt;john@example.com&gt;; admin@example.com; "Webmaster" &lt;webmaster@example.com&gt;</code>' . "\n";
688
- echo '</td>' . "\n";
689
-
690
- echo '</tr>' . "\n";
691
- echo '</tbody>' . "\n";
692
- echo '</table>' . "\n";
693
- echo '</div>' . "\n";
694
-
695
- echo '</div>' . "\n";
696
-
697
- do_action("ws_plugin__s2member_during_api_ops_page_during_left_sections_after_eot_deletion_notifications", get_defined_vars ());
698
- }
699
-
700
- if (apply_filters("ws_plugin__s2member_during_api_ops_page_during_left_sections_display_refund_reversal_notifications", true, get_defined_vars ()))
701
- {
702
- do_action("ws_plugin__s2member_during_api_ops_page_during_left_sections_before_refund_reversal_notifications", get_defined_vars ());
703
-
704
- echo '<div class="ws-menu-page-group" title="Refund/Reversal Notifications">' . "\n";
705
-
706
- echo '<div class="ws-menu-page-section ws-plugin--s2member-refund-reversal-notifications-section">' . "\n";
707
- echo '<h3>Refund/Reversal Notification URLs (optional)</h3>' . "\n";
708
- echo '<p>If you use affiliate software, or have back-office routines that need to be notified whenever Subscriptions have been refunded or reversed <em>(i.e. charged back to you)</em>, 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 EOT/Deletion Notifications, which are all-inclusive.</p>' . "\n";
709
- echo '<p>This is very similar to the EOT/Deletion Notification described above. However, there is an important distinction. The all-inclusive EOT/Deletion Notification includes cancellations, expirations, failed payments, refunds, chargebacks, and even manual deletions by the Administrator from within the Dashboard. In other words, EOT/Deletion Notifications are processed ANY time a deletion or End Of Term action takes place. This API Notification, that is, Refund/Reversal Notifications, do NOT include all of those scenarios.</p>' . "\n";
710
- echo '<p>So the distinction is that Refund/Reversal Notifications are ONLY sent under two specific circumstances: 1. You log into your Payment Gateway and refund a payment that is associated with a Subscription. 2. The Customer complains to your Payment Gateway and a chargeback occurs, forcing a Reversal. In both of these cases, an EOT/Deletion Notification will be sent <em>(as described in the previous section)</em>, but since EOT/Deletion is a broader Notification, these Refund/Reversal Notifications are here so you can nail down specific back-office operations in these two specific scenarios.</p>' . "\n";
711
- echo '<p>Please note, this feature is not to be confused with the PayPal IPN service. PayPal IPN <em>(and other service integrations)</em> are already built into s2Member. They remain active at all times. These Refund/Reversal Notifications are an added layer of functionality, and they are completely optional.</p>' . "\n";
712
- echo '<p><strong>See also:</strong> This KB article: <a href="http://www.s2member.com/kb/building-an-api-notification-handler/" target="_blank" rel="external">Building An API Notification Handler</a>.</p>'."\n";
713
- do_action("ws_plugin__s2member_during_api_ops_page_during_left_sections_during_refund_reversal_notifications", get_defined_vars ());
714
-
715
- echo '<table class="form-table">' . "\n";
716
- echo '<tbody>' . "\n";
717
- echo '<tr>' . "\n";
718
-
719
- echo '<th>' . "\n";
720
- echo '<label for="ws-plugin--s2member-ref-rev-notification-urls">' . "\n";
721
- echo 'Refund/Reversal Notification URLs:' . "\n";
722
- echo '</label>' . "\n";
723
- echo '</th>' . "\n";
724
-
725
- echo '</tr>' . "\n";
726
- echo '<tr>' . "\n";
727
-
728
- echo '<td>' . "\n";
729
- echo 'You can input multiple Notification URLs by inserting one per line.<br />' . "\n";
730
- 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";
731
- echo 'Refund/Reversal Notifications take place silently behind-the-scene, using an HTTP connection.<br /><br />' . "\n";
732
- echo '<strong>You can also use these special Replacement Codes if you need them:</strong>' . "\n";
733
- echo '<ul class="ws-menu-page-li-margins">' . "\n";
734
- echo '<li><code>%%subscr_id%%</code> = The Paid Subscription ID, which remained constant throughout the lifetime of the Membership. [ <a href="#" onclick="alert(\'There is one exception. If you are selling Lifetime or Fixed-Term (non-recurring) access, using Buy Now functionality; the %%subscr_id%% is actually set to the original Transaction ID for the purchase. Payment Gateways do not provide a specific Subscription ID for Buy Now purchases. Since Lifetime &amp; Fixed-Term Subscriptions are NOT recurring (i.e. there was only ONE payment), using the Transaction ID as the Subscription ID is a graceful way to deal with this minor conflict.\'); return false;">?</a> ]</li>' . "\n";
735
- echo '<li><code>%%subscr_baid%%</code> = Applicable only with PayPal Pro (Payflow Edition); and only for Express Checkout transactions that required a Billing Agreement. This is the Subscription\'s Billing Agreement ID, which remained constant throughout the lifetime of the Membership. [ <a href="#" onclick="alert(\'Applicable only with PayPal Pro (Payflow Edition); and only for Express Checkout transactions that required a Billing Agreement. In all other cases, the %%subscr_baid%% is simply set to the %%subscr_id%% value; i.e. it is a duplicate of %%subscr_id%% in most cases.\'); return false;">?</a> ]</li>' . "\n";
736
- echo '<li><code>%%subscr_cid%%</code> = Applicable only with Stripe integration. This is the Customer\'s ID in Stripe, which remained constant throughout the lifetime of the Membership. Each Stripe Customer has this Customer ID; and also a Subscription and/or Transaction ID [ <a href="#" onclick="alert(\'Applicable only when you integrate s2Member with Stripe. In all other cases, the %%subscr_cid%% is simply set to the %%subscr_id%% value; i.e. it is a duplicate of %%subscr_id%% when running anything other than Stripe.\\n\\nEach Stripe Customer has a Customer ID; and also a Subscription and/or Transaction ID. See %%subscr_id%% for further details.\'); return false;">?</a> ]</li>' . "\n";
737
- echo '<li><code>%%parent_txn_id%%</code> = The Parent Transaction ID, associated with the original payment being refunded/reversed.</li>' . "\n";
738
- echo '<li><code>%%-amount%%</code> = The Negative Amount of the payment, that was refunded or reversed back to the Customer.</li>' . "\n";
739
- echo '<li><code>%%-fee%%</code> = The Negative Payment Gateway fee, that was refunded back to you as the Merchant/Seller.</li>' . "\n";
740
- echo '<li><code>%%first_name%%</code> = The First Name of the Customer who purchased the Membership Subscription.</li>' . "\n";
741
- echo '<li><code>%%last_name%%</code> = The Last Name of the Customer who purchased the Membership Subscription.</li>' . "\n";
742
- echo '<li><code>%%full_name%%</code> = The Full Name (First &amp; Last) of the Customer who purchased the Membership Subscription.</li>' . "\n";
743
- echo '<li><code>%%payer_email%%</code> = The Email Address of the Customer who purchased the Membership Subscription.</li>' . "\n";
744
- echo '<li><code>%%item_number%%</code> = The Item Number (colon separated <em>level:custom_capabilities:fixed term</em>) that the payment was for.</li>' . "\n";
745
- echo '<li><code>%%item_name%%</code> = The Item Name (as provided by the <code>desc=""</code> attribute in your Shortcode, which briefly describes the Item Number).</li>' . "\n";
746
- echo '<li><code>%%user_ip%%</code> = The Customer\'s original IP Address, during checkout/registration via <code>$_SERVER["REMOTE_ADDR"]</code>.</li>' . "\n";
747
- echo '<li><code>%%user_id%%</code> = A unique WordPress User ID that references this account in the WordPress database.</li>' . "\n";
748
- echo '</ul>' . "\n";
749
-
750
- echo '<strong>Custom Registration/Profile Fields are also supported in this Notification:</strong>' . "\n";
751
- echo '<ul class="ws-menu-page-li-margins">' . "\n";
752
- echo '<li><code>%%date_of_birth%%</code> would be valid; if you have a Custom Registration/Profile Field with the ID <code>date_of_birth</code>.</li>' . "\n";
753
- echo '<li><code>%%street_address%%</code> would be valid; if you have a Custom Registration/Profile Field with the ID <code>street_address</code>.</li>' . "\n";
754
- echo '<li><code>%%country%%</code> would be valid; if you have a Custom Registration/Profile Field with the ID <code>country</code>.</li>' . "\n";
755
- echo '<li><em><code>%%etc, etc...%%</code> <strong>see:</strong> s2Member -› General Options -› Registration/Profile Fields</em>.</li>' . "\n";
756
- echo '</ul>' . "\n";
757
-
758
- echo '<strong>Custom Replacement Codes can also be inserted using these instructions:</strong>' . "\n";
759
- echo '<ul class="ws-menu-page-li-margins">' . "\n";
760
- echo '<li><code>%%cv0%%</code> = The domain of your site, which is passed through the `custom` attribute in your Shortcode.</li>' . "\n";
761
- echo '<li><code>%%cv1%%</code> = If you need to track additional custom variables, you can pipe delimit them into the `custom` attribute; inside your Shortcode, like this: <code>custom="' . esc_html ($_SERVER["HTTP_HOST"]) . '|cv1|cv2|cv3"</code>. You can have an unlimited number of custom variables. Obviously, this is for advanced webmasters; but the functionality has been made available for those who need it.</li>' . "\n";
762
- echo '</ul>' . "\n";
763
- echo '<strong>This example uses cv1 to record a special marketing campaign:</strong><br />' . "\n";
764
- echo '<em>(The campaign (i.e. christmas-promo) could be referenced using <code>%%cv1%%</code>)</em><br />' . "\n";
765
- echo '<code>custom="' . esc_html ($_SERVER["HTTP_HOST"]) . '|christmas-promo"</code>' . "\n";
766
-
767
- echo '</td>' . "\n";
768
-
769
- echo '</tr>' . "\n";
770
- echo '</tbody>' . "\n";
771
- echo '</table>' . "\n";
772
-
773
- echo '<div class="ws-menu-page-hr"></div>' . "\n";
774
-
775
- echo '<table class="form-table" style="margin-top:0;">' . "\n";
776
- echo '<tbody>' . "\n";
777
- echo '<tr>' . "\n";
778
-
779
- echo '<th style="padding-top:0;">' . "\n";
780
- echo '<label for="ws-plugin--s2member-ref-rev-notification-recipients">' . "\n";
781
- echo 'Send An Email Transaction Log Of This Event?' . "\n";
782
- echo '</label>' . "\n";
783
- echo '</th>' . "\n";
784
-
785
- echo '</tr>' . "\n";
786
- echo '<tr>' . "\n";
787
-
788
- echo '<td>' . "\n";
789
- echo '<input type="text" autocomplete="off" name="ws_plugin__s2member_ref_rev_notification_recipients" id="ws-plugin--s2member-ref-rev-notification-recipients" value="' . format_to_edit ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["ref_rev_notification_recipients"]) . '" /><br />' . "\n";
790
- echo 'This is a semicolon ( ; ) delimited list of Recipients. Here is an example:<br />' . "\n";
791
- echo '<code>"John" &lt;john@example.com&gt;; admin@example.com; "Webmaster" &lt;webmaster@example.com&gt;</code>' . "\n";
792
- echo '</td>' . "\n";
793
-
794
- echo '</tr>' . "\n";
795
- echo '</tbody>' . "\n";
796
- echo '</table>' . "\n";
797
- echo '</div>' . "\n";
798
-
799
- echo '</div>' . "\n";
800
-
801
- do_action("ws_plugin__s2member_during_api_ops_page_during_left_sections_after_refund_reversal_notifications", get_defined_vars ());
802
- }
803
-
804
- if (apply_filters("ws_plugin__s2member_during_api_ops_page_during_left_sections_display_sp_sale_notifications", true, get_defined_vars ()))
805
- {
806
- do_action("ws_plugin__s2member_during_api_ops_page_during_left_sections_before_sp_sale_notifications", get_defined_vars ());
807
-
808
- echo '<div class="ws-menu-page-group" title="Specific Post/Page ~ Sale Notifications">' . "\n";
809
-
810
- echo '<div class="ws-menu-page-section ws-plugin--s2member-sp-sale-notifications-section">' . "\n";
811
- echo '<h3>Specific Post/Page ~ Sale Notification URLs (optional)</h3>' . "\n";
812
- echo '<p>If you use affiliate software, or have back-office routines that need to be notified whenever Specific Post/Page sales take place, you\'ll want to read this section. This is marked `Specific Post/Page`, because the URLs that you list below, will be notified each time a payment occurs, on a sale providing access to a Specific Post/Page.</p>' . "\n";
813
- echo '<p>This is one of only two API Notifications that are sent for Specific Post/Page Access <em>(i.e. this one, and another below, for Refunds/Reversals)</em>. All of the other API Notifications are designed for Membership Level Access' . ((is_multisite () && c_ws_plugin__s2member_utils_conds::is_multisite_farm () && !is_main_site ()) ? '' : ' and Independent Custom Capabilities') . '. None of the other API Notifications will ever be processed for Specific Post/Page Access. If you intend to respond to events related to Specific Post/Page Access, you MUST use one of the two API Notifications specifically geared to Post/Page Access.</p>' . "\n";
814
- echo '<p>Please note, this feature is not to be confused with the PayPal IPN service. PayPal IPN <em>(and other service integrations)</em> are already built into s2Member. They remain active at all times. These Sale Notifications are an added layer of functionality, and they are completely optional.</p>' . "\n";
815
- echo '<p><strong>See also:</strong> This KB article: <a href="http://www.s2member.com/kb/building-an-api-notification-handler/" target="_blank" rel="external">Building An API Notification Handler</a>.</p>'."\n";
816
- do_action("ws_plugin__s2member_during_api_ops_page_during_left_sections_during_sp_sale_notifications", get_defined_vars ());
817
-
818
- echo '<table class="form-table">' . "\n";
819
- echo '<tbody>' . "\n";
820
- echo '<tr>' . "\n";
821
-
822
- echo '<th>' . "\n";
823
- echo '<label for="ws-plugin--s2member-sp-sale-notification-urls">' . "\n";
824
- echo 'Specific Post/Page ~ Sale Notification URLs:' . "\n";
825
- echo '</label>' . "\n";
826
- echo '</th>' . "\n";
827
-
828
- echo '</tr>' . "\n";
829
- echo '<tr>' . "\n";
830
-
831
- echo '<td>' . "\n";
832
- echo 'You can input multiple Notification URLs by inserting one per line.<br />' . "\n";
833
- echo '<textarea name="ws_plugin__s2member_sp_sale_notification_urls" id="ws-plugin--s2member-sp-sale-notification-urls" rows="3" wrap="off">' . format_to_edit ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["sp_sale_notification_urls"]) . '</textarea><br />' . "\n";
834
- echo 'Specific Post/Page ~ Sale Notifications take place silently behind-the-scene, using an HTTP connection.<br /><br />' . "\n";
835
- echo '<strong>You can also use these special Replacement Codes if you need them:</strong>' . "\n";
836
- echo '<ul class="ws-menu-page-li-margins">' . "\n";
837
- echo '<li><code>%%sp_access_url%%</code> = The full URL (generated by s2Member) where the Customer can gain access.</li>' . "\n";
838
- echo '<li><code>%%sp_access_exp%%</code> = Human readable expiration for <code>%%sp_access_url%%</code>. Ex: <em>(link expires in <code>%%sp_access_exp%%</code>)</em>.</li>' . "\n";
839
- echo '<li><code>%%txn_id%%</code> = The Paid Transaction ID. Payment Gateways assign a unique identifier for every purchase.</li>' . "\n";
840
- echo '<li><code>%%txn_cid%%</code> = Applicable only with Stripe integration. This is the Customer\'s ID in Stripe. Each Stripe Customer has this Customer ID; and also a Transaction ID associated with their purchase of the Specific Post/Page [ <a href="#" onclick="alert(\'Applicable only when you integrate s2Member with Stripe. In all other cases, the %%txn_cid%% is simply set to the %%txn_id%% value; i.e. it is a duplicate of %%txn_id%% when running anything other than Stripe.\\n\\nEach Stripe Customer has a Customer ID; and also a Transaction ID. See %%txn_id%% for further details.\'); return false;">?</a> ]</li>' . "\n";
841
- echo '<li><code>%%amount%%</code> = The full Amount of the sale. If you offer something 100% free, this will be <code>0</code>.</li>' . "\n";
842
- echo '<li><code>%%first_name%%</code> = The First Name of the Customer who purchased Specific Post/Page Access.</li>' . "\n";
843
- echo '<li><code>%%last_name%%</code> = The Last Name of the Customer who purchased Specific Post/Page Access.</li>' . "\n";
844
- echo '<li><code>%%full_name%%</code> = The Full Name (First &amp; Last) of the Customer who purchased Specific Post/Page Access.</li>' . "\n";
845
- echo '<li><code>%%payer_email%%</code> = The Email Address of the Customer who purchased Specific Post/Page Access.</li>' . "\n";
846
- echo '<li><code>%%user_ip%%</code> = The Customers\'s IP Address, during checkout via <code>$_SERVER["REMOTE_ADDR"]</code>.</li>' . "\n";
847
- echo '<li><code>%%item_number%%</code> = The Item Number. Ex: <code><em>sp:13,24,36:72</em></code> (translates to: <code><em>sp:comma-delimited IDs:expiration hours</em></code>).</li>' . "\n";
848
- echo '<li><code>%%item_name%%</code> = The Item Name (as provided by the <code>desc=""</code> attribute in your Shortcode, which briefly describes the Item Number).</li>' . "\n";
849
- echo '</ul>' . "\n";
850
-
851
- if(c_ws_plugin__s2member_utils_conds::pro_is_installed())
852
- {
853
- echo '<strong>Coupon Replacement Codes (applicable only w/ s2Member Pro Forms):</strong>' . "\n";
854
- echo '<ul class="ws-menu-page-li-margins">' . "\n";
855
- echo '<li><code>%%full_coupon_code%%</code> = A full Coupon Code — if one is accepted by your configuration of s2Member. This may indicate an Affiliate Coupon Code, which will include your Affiliate Suffix Chars too (i.e. the full Coupon Code).</li>' . "\n";
856
- echo '<li><code>%%coupon_code%%</code> = A Coupon Code — if one is accepted by your configuration of s2Member. This will NOT include any Affiliate Suffix Chars. This indicates the actual Coupon Code accepted by your configuration of s2Member (excluding any Affiliate ID).</li>' . "\n";
857
- echo '<li><code>%%coupon_affiliate_id%%</code> = This is the end of an Affiliate Coupon Code <em>(i.e. the referring affiliate\'s ID)</em>. This is only applicable if an Affiliate Coupon Code is accepted by your configuration of s2Member.</li>' . "\n";
858
- echo '</ul>' . "\n";
859
- }
860
-
861
- echo '<strong>Custom Replacement Codes can also be inserted using these instructions:</strong>' . "\n";
862
- echo '<ul class="ws-menu-page-li-margins">' . "\n";
863
- echo '<li><code>%%cv0%%</code> = The domain of your site, which is passed through the `custom` attribute in your Shortcode.</li>' . "\n";
864
- echo '<li><code>%%cv1%%</code> = If you need to track additional custom variables, you can pipe delimit them into the `custom` attribute; inside your Shortcode, like this: <code>custom="' . esc_html ($_SERVER["HTTP_HOST"]) . '|cv1|cv2|cv3"</code>. You can have an unlimited number of custom variables. Obviously, this is for advanced webmasters; but the functionality has been made available for those who need it.</li>' . "\n";
865
- echo '</ul>' . "\n";
866
- echo '<strong>This example uses cv1 to record a special marketing campaign:</strong><br />' . "\n";
867
- echo '<em>(The campaign (i.e. christmas-promo) could be referenced using <code>%%cv1%%</code>)</em><br />' . "\n";
868
- echo '<code>custom="' . esc_html ($_SERVER["HTTP_HOST"]) . '|christmas-promo"</code>' . "\n";
869
-
870
- echo '</td>' . "\n";
871
-
872
- echo '</tr>' . "\n";
873
- echo '</tbody>' . "\n";
874
- echo '</table>' . "\n";
875
-
876
- echo '<div class="ws-menu-page-hr"></div>' . "\n";
877
-
878
- echo '<table class="form-table" style="margin-top:0;">' . "\n";
879
- echo '<tbody>' . "\n";
880
- echo '<tr>' . "\n";
881
-
882
- echo '<th style="padding-top:0;">' . "\n";
883
- echo '<label for="ws-plugin--s2member-sp-sale-notification-recipients">' . "\n";
884
- echo 'Send An Email Transaction Log Of This Event?' . "\n";
885
- echo '</label>' . "\n";
886
- echo '</th>' . "\n";
887
-
888
- echo '</tr>' . "\n";
889
- echo '<tr>' . "\n";
890
-
891
- echo '<td>' . "\n";
892
- echo '<input type="text" autocomplete="off" name="ws_plugin__s2member_sp_sale_notification_recipients" id="ws-plugin--s2member-sp-sale-notification-recipients" value="' . format_to_edit ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["sp_sale_notification_recipients"]) . '" /><br />' . "\n";
893
- echo 'This is a semicolon ( ; ) delimited list of Recipients. Here is an example:<br />' . "\n";
894
- echo '<code>"John" &lt;john@example.com&gt;; admin@example.com; "Webmaster" &lt;webmaster@example.com&gt;</code>' . "\n";
895
- echo '</td>' . "\n";
896
-
897
- echo '</tr>' . "\n";
898
- echo '</tbody>' . "\n";
899
- echo '</table>' . "\n";
900
- echo '</div>' . "\n";
901
-
902
- echo '</div>' . "\n";
903
-
904
- do_action("ws_plugin__s2member_during_api_ops_page_during_left_sections_after_sp_sale_notifications", get_defined_vars ());
905
- }
906
-
907
- if (apply_filters("ws_plugin__s2member_during_api_ops_page_during_left_sections_display_sp_refund_reversal_notifications", true, get_defined_vars ()))
908
- {
909
- do_action("ws_plugin__s2member_during_api_ops_page_during_left_sections_before_sp_refund_reversal_notifications", get_defined_vars ());
910
-
911
- echo '<div class="ws-menu-page-group" title="Specific Post/Page ~ Refund/Reversal Notifications">' . "\n";
912
-
913
- echo '<div class="ws-menu-page-section ws-plugin--s2member-sp-refund-reversal-notifications-section">' . "\n";
914
- echo '<h3>Specific Post/Page ~ Refund/Reversal Notification URLs (optional)</h3>' . "\n";
915
- echo '<p>If you use affiliate software, or have back-office routines that need to be notified whenever sales have been refunded or reversed <em>(i.e. charged back to you)</em>, you\'ll want to read this section. This is marked `Specific Post/Page`, because the URLs that you list below, will be notified each time a Refund or Reversal occurs, on a sale that provided access to a Specific Post/Page.</p>' . "\n";
916
- echo '<p>This is one of only two Notifications that are sent for Specific Post/Page Access <em>(i.e. this one, and another above, for Sales)</em>. All of the other API Notifications are designed for Membership Level Access' . ((is_multisite () && c_ws_plugin__s2member_utils_conds::is_multisite_farm () && !is_main_site ()) ? '' : ' and Independent Custom Capabilities') . '. None of the other API Notifications will ever be processed for Specific Post/Page Access. If you intend to respond to events related to Specific Post/Page Access, you MUST use one of the two API Notifications specifically geared to Post/Page Access.</p>' . "\n";
917
- echo '<p>Please note, this feature is not to be confused with the PayPal IPN service. PayPal IPN <em>(and other service integrations)</em> are already built into s2Member. They remain active at all times. These Refund/Reversal Notifications are an added layer of functionality, and they are completely optional.</p>' . "\n";
918
- echo '<p><strong>See also:</strong> This KB article: <a href="http://www.s2member.com/kb/building-an-api-notification-handler/" target="_blank" rel="external">Building An API Notification Handler</a>.</p>'."\n";
919
- do_action("ws_plugin__s2member_during_api_ops_page_during_left_sections_during_sp_refund_reversal_notifications", get_defined_vars ());
920
-
921
- echo '<table class="form-table">' . "\n";
922
- echo '<tbody>' . "\n";
923
- echo '<tr>' . "\n";
924
-
925
- echo '<th>' . "\n";
926
- echo '<label for="ws-plugin--s2member-sp-ref-rev-notification-urls">' . "\n";
927
- echo 'Specific Post/Page ~ Refund/Reversal Notification URLs:' . "\n";
928
- echo '</label>' . "\n";
929
- echo '</th>' . "\n";
930
-
931
- echo '</tr>' . "\n";
932
- echo '<tr>' . "\n";
933
-
934
- echo '<td>' . "\n";
935
- echo 'You can input multiple Notification URLs by inserting one per line.<br />' . "\n";
936
- echo '<textarea name="ws_plugin__s2member_sp_ref_rev_notification_urls" id="ws-plugin--s2member-sp-ref-rev-notification-urls" rows="3" wrap="off">' . format_to_edit ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["sp_ref_rev_notification_urls"]) . '</textarea><br />' . "\n";
937
- echo 'Specific Post/Page ~ Refund/Reversal Notifications take place silently behind-the-scene, using an HTTP connection.<br /><br />' . "\n";
938
- echo '<strong>You can also use these special Replacement Codes if you need them:</strong>' . "\n";
939
- echo '<ul class="ws-menu-page-li-margins">' . "\n";
940
- echo '<li><code>%%parent_txn_id%%</code> = The Parent Transaction ID, associated with the original payment being refunded/reversed.</li>' . "\n";
941
- echo '<li><code>%%parent_txn_cid%%</code> = Applicable only with Stripe integration. This is the Customer\'s ID in Stripe. Each Stripe Customer has this Customer ID; and also a Transaction ID associated with their purchase of the Specific Post/Page [ <a href="#" onclick="alert(\'Applicable only when you integrate s2Member with Stripe. In all other cases, the %%parent_txn_cid%% is simply set to the %%parent_txn_id%% value; i.e. it is a duplicate of %%parent_txn_id%% when running anything other than Stripe.\\n\\nEach Stripe Customer has a Customer ID; and also a Transaction ID. See %%parent_txn_id%% for further details.\'); return false;">?</a> ]</li>' . "\n";
942
- echo '<li><code>%%-amount%%</code> = The Negative Amount of the payment, that was refunded or reversed back to the Customer.</li>' . "\n";
943
- echo '<li><code>%%-fee%%</code> = The Negative Payment Gateway fee, that was refunded back to you as the Merchant/Seller.</li>' . "\n";
944
- echo '<li><code>%%first_name%%</code> = The First Name of the Customer who purchased access to a Specific Post/Page.</li>' . "\n";
945
- echo '<li><code>%%last_name%%</code> = The Last Name of the Customer who purchased access to a Specific Post/Page.</li>' . "\n";
946
- echo '<li><code>%%full_name%%</code> = The Full Name (First &amp; Last) of the Customer who purchased access to a Specific Post/Page.</li>' . "\n";
947
- echo '<li><code>%%payer_email%%</code> = The Email Address of the Customer who purchased access to a Specific Post/Page.</li>' . "\n";
948
- echo '<li><code>%%user_ip%%</code> = The Customer\'s original IP Address, during checkout via <code>$_SERVER["REMOTE_ADDR"]</code>.</li>' . "\n";
949
- echo '<li><code>%%item_number%%</code> = The Item Number. Ex: <code><em>sp:13,24,36:72</em></code> (translates to: <code><em>sp:comma-delimited IDs:expiration hours</em></code>).</li>' . "\n";
950
- echo '<li><code>%%item_name%%</code> = The Item Name (as provided by the <code>desc=""</code> attribute in your Shortcode, which briefly describes the Item Number).</li>' . "\n";
951
- echo '</ul>' . "\n";
952
-
953
- echo '<strong>Custom Replacement Codes can also be inserted using these instructions:</strong>' . "\n";
954
- echo '<ul class="ws-menu-page-li-margins">' . "\n";
955
- echo '<li><code>%%cv0%%</code> = The domain of your site, which is passed through the `custom` attribute in your Shortcode.</li>' . "\n";
956
- echo '<li><code>%%cv1%%</code> = If you need to track additional custom variables, you can pipe delimit them into the `custom` attribute; inside your Shortcode, like this: <code>custom="' . esc_html ($_SERVER["HTTP_HOST"]) . '|cv1|cv2|cv3"</code>. You can have an unlimited number of custom variables. Obviously, this is for advanced webmasters; but the functionality has been made available for those who need it.</li>' . "\n";
957
- echo '</ul>' . "\n";
958
- echo '<strong>This example uses cv1 to record a special marketing campaign:</strong><br />' . "\n";
959
- echo '<em>(The campaign (i.e. christmas-promo) could be referenced using <code>%%cv1%%</code>)</em><br />' . "\n";
960
- echo '<code>custom="' . esc_html ($_SERVER["HTTP_HOST"]) . '|christmas-promo"</code>' . "\n";
961
-
962
- echo '</td>' . "\n";
963
-
964
- echo '</tr>' . "\n";
965
- echo '</tbody>' . "\n";
966
- echo '</table>' . "\n";
967
-
968
- echo '<div class="ws-menu-page-hr"></div>' . "\n";
969
-
970
- echo '<table class="form-table" style="margin-top:0;">' . "\n";
971
- echo '<tbody>' . "\n";
972
- echo '<tr>' . "\n";
973
-
974
- echo '<th style="padding-top:0;">' . "\n";
975
- echo '<label for="ws-plugin--s2member-sp-ref-rev-notification-recipients">' . "\n";
976
- echo 'Send An Email Transaction Log Of This Event?' . "\n";
977
- echo '</label>' . "\n";
978
- echo '</th>' . "\n";
979
-
980
- echo '</tr>' . "\n";
981
- echo '<tr>' . "\n";
982
-
983
- echo '<td>' . "\n";
984
- echo '<input type="text" autocomplete="off" name="ws_plugin__s2member_sp_ref_rev_notification_recipients" id="ws-plugin--s2member-sp-ref-rev-notification-recipients" value="' . format_to_edit ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["sp_ref_rev_notification_recipients"]) . '" /><br />' . "\n";
985
- echo 'This is a semicolon ( ; ) delimited list of Recipients. Here is an example:<br />' . "\n";
986
- echo '<code>"John" &lt;john@example.com&gt;; admin@example.com; "Webmaster" &lt;webmaster@example.com&gt;</code>' . "\n";
987
- echo '</td>' . "\n";
988
-
989
- echo '</tr>' . "\n";
990
- echo '</tbody>' . "\n";
991
- echo '</table>' . "\n";
992
- echo '</div>' . "\n";
993
-
994
- echo '</div>' . "\n";
995
-
996
- do_action("ws_plugin__s2member_during_api_ops_page_during_left_sections_after_sp_refund_reversal_notifications", get_defined_vars ());
997
- }
998
-
999
- do_action("ws_plugin__s2member_during_api_ops_page_after_left_sections", get_defined_vars ());
1000
-
1001
- echo '<div class="ws-menu-page-hr"></div>' . "\n";
1002
-
1003
- echo '<p class="submit"><input type="submit" value="Save All Changes" /></p>' . "\n";
1004
-
1005
- echo '</form>' . "\n";
1006
-
1007
- echo '</td>' . "\n";
1008
-
1009
- echo '<td class="ws-menu-page-table-r">' . "\n";
1010
- c_ws_plugin__s2member_menu_pages_rs::display ();
1011
- echo '</td>' . "\n";
1012
-
1013
- echo '</tr>' . "\n";
1014
- echo '</tbody>' . "\n";
1015
- echo '</table>' . "\n";
1016
-
1017
- echo '</div>' . "\n";
1018
- }
1019
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1020
  }
 
1021
 
1022
- new c_ws_plugin__s2member_menu_page_api_ops ();
1023
- ?>
1
  <?php
2
  /**
3
+ * Menu page for the s2Member plugin (API Notifications page).
4
+ *
5
+ * Copyright: © 2009-2011
6
+ * {@link http://www.websharks-inc.com/ WebSharks, Inc.}
7
+ * (coded in the USA)
8
+ *
9
+ * Released under the terms of the GNU General Public License.
10
+ * You should have received a copy of the GNU General Public License,
11
+ * along with this software. In the main directory, see: /licensing/
12
+ * If not, see: {@link http://www.gnu.org/licenses/}.
13
+ *
14
+ * @package s2Member\Menu_Pages
15
+ * @since 3.0
16
+ */
17
+ if(realpath(__FILE__) === realpath($_SERVER["SCRIPT_FILENAME"]))
18
  exit("Do not access this file directly.");
19
 
20
+ if(!class_exists("c_ws_plugin__s2member_menu_page_api_ops"))
21
+ {
22
+ /**
23
+ * Menu page for the s2Member plugin (API Notifications page).
24
+ *
25
+ * @package s2Member\Menu_Pages
26
+ * @since 110531
27
+ */
28
+ class c_ws_plugin__s2member_menu_page_api_ops
29
  {
30
+ public function __construct()
31
+ {
32
+ echo '<div class="wrap ws-menu-page">'."\n";
33
+
34
+ echo '<div class="ws-menu-page-toolbox">'."\n";
35
+ c_ws_plugin__s2member_menu_pages_tb::display();
36
+ echo '</div>'."\n";
37
+
38
+ echo '<h2>API / Notifications</h2>'."\n";
39
+
40
+ echo '<table class="ws-menu-page-table">'."\n";
41
+ echo '<tbody class="ws-menu-page-table-tbody">'."\n";
42
+ echo '<tr class="ws-menu-page-table-tr">'."\n";
43
+ echo '<td class="ws-menu-page-table-l">'."\n";
44
+
45
+ echo '<form method="post" name="ws_plugin__s2member_options_form" id="ws-plugin--s2member-options-form">'."\n";
46
+ 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";
47
+ echo '<input type="hidden" name="ws_plugin__s2member_configured" id="ws-plugin--s2member-configured" value="1" />'."\n";
48
+
49
+ do_action("ws_plugin__s2member_during_api_ops_page_before_left_sections", get_defined_vars());
50
+
51
+ if(apply_filters("ws_plugin__s2member_during_api_ops_page_during_left_sections_display_signup_notifications", TRUE, get_defined_vars()))
52
+ {
53
+ do_action("ws_plugin__s2member_during_api_ops_page_during_left_sections_before_signup_notifications", get_defined_vars());
54
+
55
+ echo '<div class="ws-menu-page-group" title="Signup Notifications">'."\n";
56
+
57
+ echo '<div class="ws-menu-page-section ws-plugin--s2member-signup-notifications-section">'."\n";
58
+ echo '<h3>Signup Notification URLs (optional)</h3>'."\n";
59
+ 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 "new", "paying" Member signs up. Depending on your fee structure, this may include a payment that establishes their Subscription, or it may not. This Notification will only be triggered once for each Member. Signup Notifications are sent right after a "new", "paying" Member signs up successfully through your Payment Gateway, regardless of whether any money has actually been transacted. In other words, this Notification is triggered anytime a "new", "paying" Member signs up through your Payment Gateway, even if you provided them with something for free <em>(i.e. even if no money is being transacted)</em>.</p>'."\n";
60
+ echo '<p>This Notification will NOT be processed for Free Subscribers that register without going through your Payment Gateway at all (i.e. they simply register on-site; and there is no checkout whatsoever). This Notification will NOT be processed when an "existing" User/Member pays for a new Subscription <em>(see: Modification Notifications for that scenario)</em>.'.((is_multisite() && c_ws_plugin__s2member_utils_conds::is_multisite_farm() && !is_main_site()) ? '' : ' And, this Notification will NOT be processed on Buy Now transactions for Independent Custom Capabilities <em>(see: Payment Notifications for that scenario)</em>.').'</p>'."\n";
61
+ echo '<p>Please note, this feature is not to be confused with the PayPal IPN service. PayPal IPN <em>(and other service integrations)</em> are already built into s2Member. They remain active at all times. These Signup Notifications are an added layer of functionality, and they are completely optional.</p>'."\n";
62
+ echo '<p><strong>See also:</strong> This KB article: <a href="http://www.s2member.com/kb/building-an-api-notification-handler/" target="_blank" rel="external">Building An API Notification Handler</a>.</p>'."\n";
63
+ do_action("ws_plugin__s2member_during_api_ops_page_during_left_sections_during_signup_notifications", get_defined_vars());
64
+
65
+ echo '<table class="form-table">'."\n";
66
+ echo '<tbody>'."\n";
67
+ echo '<tr>'."\n";
68
+
69
+ echo '<th>'."\n";
70
+ echo '<label for="ws-plugin--s2member-signup-notification-urls">'."\n";
71
+ echo 'Signup Notification URLs:'."\n";
72
+ echo '</label>'."\n";
73
+ echo '</th>'."\n";
74
+
75
+ echo '</tr>'."\n";
76
+ echo '<tr>'."\n";
77
+
78
+ echo '<td>'."\n";
79
+ echo 'You can input multiple Notification URLs by inserting one per line.<br />'."\n";
80
+ 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";
81
+ echo 'Signup Notifications take place silently behind-the-scene, using an HTTP connection.<br /><br />'."\n";
82
+ echo '<strong>You can also use these special Replacement Codes if you need them:</strong>'."\n";
83
+ echo '<ul class="ws-menu-page-li-margins">'."\n";
84
+ echo '<li><code>%%subscr_id%%</code> = The Paid Subscription ID, which remains constant throughout any &amp; all future payments. [ <a href="#" onclick="alert(\'There is one exception. If you are selling Lifetime or Fixed-Term (non-recurring) access, using Buy Now functionality; the %%subscr_id%% is actually set to the Transaction ID for the purchase. Payment Gateways do not provide a specific Subscription ID for Buy Now purchases. Since Lifetime &amp; Fixed-Term Subscriptions are NOT recurring (i.e. there is only ONE payment), using the Transaction ID as the Subscription ID is a graceful way to deal with this minor conflict.\'); return false;">?</a> ]</li>'."\n";
85
+ echo '<li><code>%%subscr_baid%%</code> = Applicable only with PayPal Pro (Payflow Edition); and only for Express Checkout transactions that require a Billing Agreement. This is the Subscription\'s Billing Agreement ID, which remains constant throughout any &amp; all future payments. [ <a href="#" onclick="alert(\'Applicable only with PayPal Pro (Payflow Edition); and only for Express Checkout transactions that require a Billing Agreement. In all other cases, the %%subscr_baid%% is simply set to the %%subscr_id%% value; i.e. it is a duplicate of %%subscr_id%% in most cases.\'); return false;">?</a> ]</li>'."\n";
86
+ echo '<li><code>%%subscr_cid%%</code> = Applicable only with Stripe integration. This is the Customer\'s ID in Stripe, which remains constant throughout any &amp; all future payments. Each Stripe Customer has this Customer ID; and also a Subscription and/or Transaction ID [ <a href="#" onclick="alert(\'Applicable only when you integrate s2Member with Stripe. In all other cases, the %%subscr_cid%% is simply set to the %%subscr_id%% value; i.e. it is a duplicate of %%subscr_id%% when running anything other than Stripe.\\n\\nEach Stripe Customer has a Customer ID; and also a Subscription and/or Transaction ID. See %%subscr_id%% for further details.\'); return false;">?</a> ]</li>'."\n";
87
+ echo '<li><code>%%currency%%</code> = Three-character currency code (uppercase); e.g. <code>USD</code></li>'."\n";
88
+ echo '<li><code>%%currency_symbol%%</code> = Currency code symbol; e.g. <code>$</code></li>'."\n";
89
+ echo '<li><code>%%initial%%</code> = The Initial Fee charged during signup. If you offered a 100% Free Trial, this will be <code>0</code>. [ <a href="#" onclick="alert(\'This will always represent the amount of money the Customer spent, whenever they initially signed up, no matter what. Even if that amount is 0.\\n\\nIf a Customer signs up, under the terms of a 100% Free Trial Period, this will be 0. So be careful using %%initial%% when you offer a 100% Free Trial Period, because a $0.00 sale amount could cause havoc with affiliate programs.\\n\\nIf you\\\'re offering a 100% Free Trial Period, and you need to track sales through affiliate programs, you can either hard-code an amount; or use `Payment Notifications` instead.\'); return false;">?</a> ]</li>'."\n";
90
+ echo '<li><code>%%regular%%</code> = The Regular Amount of the Subscription. If you offer something 100% free, this will be <code>0</code>. [ <a href="#" onclick="alert(\'This is how much the Subscription costs after an Initial Period expires. If you did NOT offer an Initial Period at a different price, %%initial%% and %%regular%% will be equal to the same thing.\'); return false;">?</a> ]</li>'."\n";
91
+ echo '<li><code>%%recurring%%</code> = This is the amount that will be charged on a recurring basis, or <code>0</code> if non-recurring. [ <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.\'); return false;">?</a> ]</li>'."\n";
92
+ echo '<li><code>%%first_name%%</code> = The First Name of the Customer who purchased the Membership Subscription.</li>'."\n";
93
+ echo '<li><code>%%last_name%%</code> = The Last Name of the Customer who purchased the Membership Subscription.</li>'."\n";
94
+ echo '<li><code>%%full_name%%</code> = The Full Name (First &amp; Last) of the Customer who purchased the Membership Subscription.</li>'."\n";
95
+ echo '<li><code>%%payer_email%%</code> = The Email Address of the Customer who purchased the Membership Subscription.</li>'."\n";
96
+ echo '<li><code>%%user_ip%%</code> = The Customer\'s IP Address, detected during checkout via <code>$_SERVER["REMOTE_ADDR"]</code>.</li>'."\n";
97
+ echo '<li><code>%%item_number%%</code> = The Item Number (colon separated <code><em>level:custom_capabilities:fixed term</em></code>) for the Membership Subscription.</li>'."\n";
98
+ echo '<li><code>%%item_name%%</code> = The Item Name (as provided by the <code>desc=""</code> attribute in your Shortcode, which briefly describes the Item Number).</li>'."\n";
99
+ echo '<li><code>%%initial_term%%</code> = This is the term length of the Initial Period. This will be a numeric value, followed by a space, then a single letter. [ <a href="#" onclick="alert(\'Here are some examples:\\n\\n%%initial_term%% = 1 D (this means 1 Day)\\n%%initial_term%% = 1 W (this means 1 Week)\\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.\'); return false;">?</a> ]</li>'."\n";
100
+ echo '<li><code>%%regular_term%%</code> = This is the term length of the Regular Period. This will be a numeric value, followed by a space, then a single letter. [ <a href="#" onclick="alert(\'Here are some examples:\\n\\n%%regular_term%% = 1 D (this means 1 Day)\\n%%regular_term%% = 1 W (this means 1 Week)\\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";
101
+ echo '</ul>'."\n";
102
+
103
+ if(c_ws_plugin__s2member_utils_conds::pro_is_installed())
104
+ {
105
+ echo '<strong>Coupon Replacement Codes (applicable only w/ s2Member Pro Forms):</strong>'."\n";
106
+ echo '<ul class="ws-menu-page-li-margins">'."\n";
107
+ echo '<li><code>%%full_coupon_code%%</code> = A full Coupon Code — if one is accepted by your configuration of s2Member. This may indicate an Affiliate Coupon Code, which will include your Affiliate Suffix Chars too (i.e. the full Coupon Code).</li>'."\n";
108
+ echo '<li><code>%%coupon_code%%</code> = A Coupon Code — if one is accepted by your configuration of s2Member. This will NOT include any Affiliate Suffix Chars. This indicates the actual Coupon Code accepted by your configuration of s2Member (excluding any Affiliate ID).</li>'."\n";
109
+ echo '<li><code>%%coupon_affiliate_id%%</code> = This is the end of an Affiliate Coupon Code <em>(i.e. the referring affiliate\'s ID)</em>. This is only applicable if an Affiliate Coupon Code is accepted by your configuration of s2Member.</li>'."\n";
110
+ echo '</ul>'."\n";
111
+ }
112
+
113
+ echo '<strong>Custom Replacement Codes can also be inserted using these instructions:</strong>'."\n";
114
+ echo '<ul class="ws-menu-page-li-margins">'."\n";
115
+ echo '<li><code>%%cv0%%</code> = The domain of your site, which is passed through the `custom` attribute in your Shortcode.</li>'."\n";
116
+ echo '<li><code>%%cv1%%</code> = If you need to track additional custom variables, you can pipe delimit them into the `custom` attribute; inside your Shortcode, like this: <code>custom="'.esc_html($_SERVER["HTTP_HOST"]).'|cv1|cv2|cv3"</code>. You can have an unlimited number of custom variables. Obviously, this is for advanced webmasters; but the functionality has been made available for those who need it.</li>'."\n";
117
+ echo '</ul>'."\n";
118
+ echo '<strong>This example uses cv1 to record a special marketing campaign:</strong><br />'."\n";
119
+ echo '<em>(The campaign (i.e. christmas-promo) could be referenced using <code>%%cv1%%</code>)</em><br />'."\n";
120
+ echo '<code>custom="'.esc_html($_SERVER["HTTP_HOST"]).'|christmas-promo"</code>'."\n";
121
+
122
+ echo '</td>'."\n";
123
+
124
+ echo '</tr>'."\n";
125
+ echo '</tbody>'."\n";
126
+ echo '</table>'."\n";
127
+
128
+ echo '<div class="ws-menu-page-hr"></div>'."\n";
129
+
130
+ echo '<table class="form-table" style="margin-top:0;">'."\n";
131
+ echo '<tbody>'."\n";
132
+ echo '<tr>'."\n";
133
+
134
+ echo '<th style="padding-top:0;">'."\n";
135
+ echo '<label for="ws-plugin--s2member-signup-notification-recipients">'."\n";
136
+ echo 'Send An Email Transaction Log Of This Event?'."\n";
137
+ echo '</label>'."\n";
138
+ echo '</th>'."\n";
139
+
140
+ echo '</tr>'."\n";
141
+ echo '<tr>'."\n";
142
+
143
+ echo '<td>'."\n";
144
+ echo '<input type="text" autocomplete="off" name="ws_plugin__s2member_signup_notification_recipients" id="ws-plugin--s2member-signup-notification-recipients" value="'.format_to_edit($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["signup_notification_recipients"]).'" /><br />'."\n";
145
+ echo 'This is a semicolon ( ; ) delimited list of Recipients. Here is an example:<br />'."\n";
146
+ echo '<code>"John" &lt;john@example.com&gt;; admin@example.com; "Webmaster" &lt;webmaster@example.com&gt;</code>'."\n";
147
+ echo '</td>'."\n";
148
+
149
+ echo '</tr>'."\n";
150
+ echo '</tbody>'."\n";
151
+ echo '</table>'."\n";
152
+ echo '</div>'."\n";
153
+
154
+ echo '</div>'."\n";
155
+ }
156
+
157
+ if(apply_filters("ws_plugin__s2member_during_api_ops_page_during_left_sections_display_registration_notifications", TRUE, get_defined_vars()))
158
+ {
159
+ do_action("ws_plugin__s2member_during_api_ops_page_during_left_sections_before_registration_notifications", get_defined_vars());
160
+
161
+ echo '<div class="ws-menu-page-group" title="Registration Notifications">'."\n";
162
+
163
+ echo '<div class="ws-menu-page-section ws-plugin--s2member-registration-notifications-section">'."\n";
164
+ echo '<h3>Registration Notification URLs (optional)</h3>'."\n";
165
+ 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 "new" 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.</p>'."\n";
166
+ echo '<p>This Notification is ALSO triggered whenever you create a "new" User inside your WordPress Dashboard.</p>'."\n";
167
+ echo '<p>Please note, this feature is not to be confused with the PayPal IPN service. PayPal IPN <em>(and other service integrations)</em> are already built into s2Member. They remain active at all times. These Registration Notifications are an added layer of functionality, and they are completely optional.</p>'."\n";
168
+ echo '<p><strong>See also:</strong> This KB article: <a href="http://www.s2member.com/kb/building-an-api-notification-handler/" target="_blank" rel="external">Building An API Notification Handler</a>.</p>'."\n";
169
+ do_action("ws_plugin__s2member_during_api_ops_page_during_left_sections_during_registration_notifications", get_defined_vars());
170
+
171
+ echo '<table class="form-table">'."\n";
172
+ echo '<tbody>'."\n";
173
+ echo '<tr>'."\n";
174
+
175
+ echo '<th>'."\n";
176
+ echo '<label for="ws-plugin--s2member-registration-notification-urls">'."\n";
177
+ echo 'Registration Notification URLs:'."\n";
178
+ echo '</label>'."\n";
179
+ echo '</th>'."\n";
180
+
181
+ echo '</tr>'."\n";
182
+ echo '<tr>'."\n";
183
+
184
+ echo '<td>'."\n";
185
+ echo 'You can input multiple Notification URLs by inserting one per line.<br />'."\n";
186
+ 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";
187
+ echo 'Registration Notifications take place silently behind-the-scene, using an HTTP connection.<br /><br />'."\n";
188
+ echo '<strong>You can also use these special Replacement Codes if you need them:</strong>'."\n";
189
+ echo '<ul class="ws-menu-page-li-margins">'."\n";
190
+ echo '<li><code>%%role%%</code> = The Role ID <code>(subscriber, s2member_level[0-9]+, administrator, editor, author, contributor)</code>.</li>'."\n";
191
+ echo '<li><code>%%level%%</code> = The Level number <code>(0, 1, 2, 3, 4)</code>. (<em>deprecated, no longer recommended; use <code>%%role%%</code></em>)</li>'."\n";
192
+ echo '<li><code>%%ccaps%%</code> = Custom Capabilities. Ex: <code>music,videos,free_gift</code> (<em>in comma-delimited format</em>).</li>'."\n";
193
+ echo '<li><code>%%auto_eot_time%%</code> = Auto-EOT Time (if applicable). Ex: <code>1299925670</code> (<em>unix timestamp</em>).</li>'."\n";
194
+ echo '<li><code>%%user_first_name%%</code> = The First Name of the Member who registered their Username.</li>'."\n";
195
+ echo '<li><code>%%user_last_name%%</code> = The Last Name of the Member who registered their Username.</li>'."\n";
196
+ echo '<li><code>%%user_full_name%%</code> = The Full Name (First &amp; Last) of the Member who registered their Username.</li>'."\n";
197
+ echo '<li><code>%%user_email%%</code> = The Email Address of the Member who registered their Username.</li>'."\n";
198
+ echo '<li><code>%%user_login%%</code> = The Username the Member selected during registration.</li>'."\n";
199
+ echo '<li><code>%%user_pass%%</code> = The Password selected or generated during registration.</li>'."\n";
200
+ echo '<li><code>%%user_ip%%</code> = The User\'s IP Address, detected via <code>$_SERVER["REMOTE_ADDR"]</code>.</li>'."\n";
201
+ echo '<li><code>%%user_id%%</code> = A unique WordPress User ID generated during registration.</li>'."\n";
202
+ echo '</ul>'."\n";
203
+
204
+ echo '<strong>Custom Registration/Profile Fields are also supported in this Notification:</strong>'."\n";
205
+ echo '<ul class="ws-menu-page-li-margins">'."\n";
206
+ echo '<li><code>%%date_of_birth%%</code> would be valid; if you have a Custom Registration/Profile Field with the ID <code>date_of_birth</code>.</li>'."\n";
207
+ echo '<li><code>%%street_address%%</code> would be valid; if you have a Custom Registration/Profile Field with the ID <code>street_address</code>.</li>'."\n";
208
+ echo '<li><code>%%country%%</code> would be valid; if you have a Custom Registration/Profile Field with the ID <code>country</code>.</li>'."\n";
209
+ echo '<li><em><code>%%etc, etc...%%</code> <strong>see:</strong> s2Member -› General Options -› Registration/Profile Fields</em>.</li>'."\n";
210
+ echo '</ul>'."\n";
211
+
212
+ echo '<strong>Custom Replacement Codes can also be inserted using these instructions:</strong>'."\n";
213
+ echo '<ul class="ws-menu-page-li-margins">'."\n";
214
+ echo '<li><code>%%cv0%%</code> = The domain of your site, which is passed through the `custom` attribute in your Shortcode.</li>'."\n";
215
+ echo '<li><code>%%cv1%%</code> = If you need to track additional custom variables, you can pipe delimit them into the `custom` attribute; inside your Shortcode, like this: <code>custom="'.esc_html($_SERVER["HTTP_HOST"]).'|cv1|cv2|cv3"</code>. You can have an unlimited number of custom variables. Obviously, this is for advanced webmasters; but the functionality has been made available for those who need it.</li>'."\n";
216
+ echo '</ul>'."\n";
217
+ echo '<strong>This example uses cv1 to record a special marketing campaign:</strong><br />'."\n";
218
+ echo '<em>(The campaign (i.e. christmas-promo) could be referenced using <code>%%cv1%%</code>)</em><br />'."\n";
219
+ echo '<code>custom="'.esc_html($_SERVER["HTTP_HOST"]).'|christmas-promo"</code>'."\n";
220
+
221
+ echo '</td>'."\n";
222
+
223
+ echo '</tr>'."\n";
224
+ echo '</tbody>'."\n";
225
+ echo '</table>'."\n";
226
+
227
+ echo '<div class="ws-menu-page-hr"></div>'."\n";
228
+
229
+ echo '<table class="form-table" style="margin-top:0;">'."\n";
230
+ echo '<tbody>'."\n";
231
+ echo '<tr>'."\n";
232
+
233
+ echo '<th style="padding-top:0;">'."\n";
234
+ echo '<label for="ws-plugin--s2member-registration-notification-recipients">'."\n";
235
+ echo 'Send An Email Transaction Log Of This Event?'."\n";
236
+ echo '</label>'."\n";
237
+ echo '</th>'."\n";
238
+
239
+ echo '</tr>'."\n";
240
+ echo '<tr>'."\n";
241
+
242
+ echo '<td>'."\n";
243
+ echo '<input type="text" autocomplete="off" name="ws_plugin__s2member_registration_notification_recipients" id="ws-plugin--s2member-registration-notification-recipients" value="'.format_to_edit($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["registration_notification_recipients"]).'" /><br />'."\n";
244
+ echo 'This is a semicolon ( ; ) delimited list of Recipients. Here is an example:<br />'."\n";
245
+ echo '<code>"John" &lt;john@example.com&gt;; admin@example.com; "Webmaster" &lt;webmaster@example.com&gt;</code>'."\n";
246
+ echo '</td>'."\n";
247
+
248
+ echo '</tr>'."\n";
249
+ echo '</tbody>'."\n";
250
+ echo '</table>'."\n";
251
+ echo '</div>'."\n";
252
+
253
+ echo '</div>'."\n";
254
+
255
+ do_action("ws_plugin__s2member_during_api_ops_page_during_left_sections_after_registration_notifications", get_defined_vars());
256
+ }
257
+
258
+ if(apply_filters("ws_plugin__s2member_during_api_ops_page_during_left_sections_display_payment_notifications", TRUE, get_defined_vars()))
259
+ {
260
+ do_action("ws_plugin__s2member_during_api_ops_page_during_left_sections_before_payment_notifications", get_defined_vars());
261
+
262
+ echo '<div class="ws-menu-page-group" title="Payment Notifications">'."\n";
263
+
264
+ echo '<div class="ws-menu-page-section ws-plugin--s2member-payment-notifications-section">'."\n";
265
+ echo '<h3>Payment Notification URLs (optional)</h3>'."\n";
266
+ echo '<p>If you use affiliate software, or have back-office routines that need to be notified whenever payment transactions <em>(including Recurring Payments)</em> take place, 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.</p>'."\n";
267
+ echo '<p>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 <em>(i.e. no Free Trial is being offered)</em>, 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.</p>'."\n";
268
+ echo (!is_multisite() || !c_ws_plugin__s2member_utils_conds::is_multisite_farm() || is_main_site()) ? '<p>Payment Notifications are also triggered whenever a Buy Now purchase for Independent Custom Capabilities takes place.</p>'."\n" : '';
269
+ echo '<p>Please note, this feature is not to be confused with the PayPal IPN service. PayPal IPN <em>(and other service integrations)</em> are already built into s2Member. They remain active at all times. These Payment Notifications are an added layer of functionality, and they are completely optional.</p>'."\n";
270
+ echo '<p><strong>See also:</strong> This KB article: <a href="http://www.s2member.com/kb/building-an-api-notification-handler/" target="_blank" rel="external">Building An API Notification Handler</a>.</p>'."\n";
271
+ do_action("ws_plugin__s2member_during_api_ops_page_during_left_sections_during_payment_notifications", get_defined_vars());
272
+
273
+ echo '<table class="form-table">'."\n";
274
+ echo '<tbody>'."\n";
275
+ echo '<tr>'."\n";
276
+
277
+ echo '<th>'."\n";
278
+ echo '<label for="ws-plugin--s2member-payment-notification-urls">'."\n";
279
+ echo 'Payment Notification URLs:'."\n";
280
+ echo '</label>'."\n";
281
+ echo '</th>'."\n";
282
+
283
+ echo '</tr>'."\n";
284
+ echo '<tr>'."\n";
285
+
286
+ echo '<td>'."\n";
287
+ echo 'You can input multiple Notification URLs by inserting one per line.<br />'."\n";
288
+ 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";
289
+ echo 'Payment Notifications take place silently behind-the-scene, using an HTTP connection.<br /><br />'."\n";
290
+ echo '<strong>You can also use these special Replacement Codes if you need them:</strong>'."\n";
291
+ echo '<ul class="ws-menu-page-li-margins">'."\n";
292
+ echo '<li><code>%%subscr_id%%</code> = The Paid Subscription ID, which remains constant throughout any &amp; all future payments. [ <a href="#" onclick="alert(\'There are some exceptions. If you are selling Lifetime or Fixed-Term (non-recurring) access, and/or Independent Custom Capabilities, using Buy Now functionality; the %%subscr_id%% is actually set to the Transaction ID for the payment.\\n\\nPayment Gateways do not provide a specific Subscription ID for Buy Now purchases. Since Lifetime &amp; Fixed-Term Subscriptions are NOT recurring (i.e. there is only ONE payment), which goes for Independent Custom Capability purchases too; using the Transaction ID as the Subscription ID is a graceful way to deal with this minor conflict.\'); return false;">?</a> ]</li>'."\n";
293
+ echo '<li><code>%%subscr_baid%%</code> = Applicable only with PayPal Pro (Payflow Edition); and only for Express Checkout transactions that require a Billing Agreement. This is the Subscription\'s Billing Agreement ID, which remains constant throughout any &amp; all future payments. [ <a href="#" onclick="alert(\'Applicable only with PayPal Pro (Payflow Edition); and only for Express Checkout transactions that require a Billing Agreement. In all other cases, the %%subscr_baid%% is simply set to the %%subscr_id%% value; i.e. it is a duplicate of %%subscr_id%% in most cases.\'); return false;">?</a> ]</li>'."\n";
294
+ echo '<li><code>%%subscr_cid%%</code> = Applicable only with Stripe integration. This is the Customer\'s ID in Stripe, which remains constant throughout any &amp; all future payments. Each Stripe Customer has this Customer ID; and also a Subscription and/or Transaction ID [ <a href="#" onclick="alert(\'Applicable only when you integrate s2Member with Stripe. In all other cases, the %%subscr_cid%% is simply set to the %%subscr_id%% value; i.e. it is a duplicate of %%subscr_id%% when running anything other than Stripe.\\n\\nEach Stripe Customer has a Customer ID; and also a Subscription and/or Transaction ID. See %%subscr_id%% for further details.\'); return false;">?</a> ]</li>'."\n";
295
+ echo '<li><code>%%txn_id%%</code> = The Payment Transaction ID, which is always unique for each payment received.</li>'."\n";
296
+ echo '<li><code>%%currency%%</code> = Three-character currency code (uppercase); e.g. <code>USD</code></li>'."\n";
297
+ echo '<li><code>%%currency_symbol%%</code> = Currency code symbol; e.g. <code>$</code></li>'."\n";
298
+ echo '<li><code>%%amount%%</code> = The Amount of the payment. Most affiliate programs calculate commissions from this.</li>'."\n";
299
+ echo '<li><code>%%first_name%%</code> = The First Name of the Customer who purchased the Membership Subscription'.((is_multisite() && c_ws_plugin__s2member_utils_conds::is_multisite_farm() && !is_main_site()) ? '' : ' or Capabilities.').'</li>'."\n";
300
+ echo '<li><code>%%last_name%%</code> = The Last Name of the Customer who purchased the Membership Subscription'.((is_multisite() && c_ws_plugin__s2member_utils_conds::is_multisite_farm() && !is_main_site()) ? '' : ' or Capabilities.').'</li>'."\n";
301
+ echo '<li><code>%%full_name%%</code> = The Full Name (First &amp; Last) of the Customer who purchased the Membership Subscription'.((is_multisite() && c_ws_plugin__s2member_utils_conds::is_multisite_farm() && !is_main_site()) ? '' : ' or Capabilities.').'</li>'."\n";
302
+ echo '<li><code>%%payer_email%%</code> = The Email Address of the Customer who purchased the Membership Subscription'.((is_multisite() && c_ws_plugin__s2member_utils_conds::is_multisite_farm() && !is_main_site()) ? '' : ' or Capabilities.').'</li>'."\n";
303
+ echo '<li><code>%%item_number%%</code> = The Item Number (colon separated <code><em>level:custom_capabilities:fixed term</em></code>) that the payment is for.'.((is_multisite() && c_ws_plugin__s2member_utils_conds::is_multisite_farm() && !is_main_site()) ? '' : ' [ <a href="#" onclick="alert(\'If the Payment Notification is for Independent Custom Capabilities, the `level` portion of this string will be an asterisk ( `*` ), since the Membership Level is irrelevant, and remains `as it was` in that scenario. In all other cases, the `level` portion will be a numeric value.\'); return false;">?</a> ]').'</li>'."\n";
304
+ echo '<li><code>%%item_name%%</code> = The Item Name (as provided by the <code>desc=""</code> attribute in your Shortcode, which briefly describes the Item Number).</li>'."\n";
305
+ echo '<li><code>%%user_first_name%%</code> = The First Name listed on their User account. This might be different than what is on file with your Payment Gateway.</li>'."\n";
306
+ echo '<li><code>%%user_last_name%%</code> = The Last Name listed on their User account. This might be different than what is on file with your Payment Gateway.</li>'."\n";
307
+ echo '<li><code>%%user_full_name%%</code> = The Full Name listed on their User account. This might be different than what is on file with your Payment Gateway.</li>'."\n";
308
+ echo '<li><code>%%user_email%%</code> = The Email Address associated with their User account. This might be different than what is on file with your Payment Gateway.</li>'."\n";
309
+ echo '<li><code>%%user_login%%</code> = The Username associated with their account. The Customer created this during registration.</li>'."\n";
310
+ echo '<li><code>%%user_ip%%</code> = The Customer\'s original IP Address, during checkout/registration via <code>$_SERVER["REMOTE_ADDR"]</code>.</li>'."\n";
311
+ echo '<li><code>%%user_id%%</code> = A unique WordPress User ID that references this account in the WordPress database.</li>'."\n";
312
+ echo '</ul>'."\n";
313
+
314
+ if(c_ws_plugin__s2member_utils_conds::pro_is_installed())
315
+ {
316
+ echo '<strong>Coupon Replacement Codes (applicable only w/ s2Member Pro Forms):</strong><br />'."\n";
317
+ echo '<em>These are ONLY included with payments that occur during checkout. They will NOT be provided with any future recurring payments.</em>'."\n";
318
+ echo '<ul class="ws-menu-page-li-margins">'."\n";
319
+ echo '<li><code>%%full_coupon_code%%</code> = A full Coupon Code — if one is accepted by your configuration of s2Member. This may indicate an Affiliate Coupon Code, which will include your Affiliate Suffix Chars too (i.e. the full Coupon Code).</li>'."\n";
320
+ echo '<li><code>%%coupon_code%%</code> = A Coupon Code — if one is accepted by your configuration of s2Member. This will NOT include any Affiliate Suffix Chars. This indicates the actual Coupon Code accepted by your configuration of s2Member (excluding any Affiliate ID).</li>'."\n";
321
+ echo '<li><code>%%coupon_affiliate_id%%</code> = This is the end of an Affiliate Coupon Code <em>(i.e. the referring affiliate\'s ID)</em>. This is only applicable if an Affiliate Coupon Code is accepted by your configuration of s2Member.</li>'."\n";
322
+ echo '</ul>'."\n";
323
+ }
324
+
325
+ echo '<strong>Custom Registration/Profile Fields are also supported in this Notification:</strong>'."\n";
326
+ echo '<ul class="ws-menu-page-li-margins">'."\n";
327
+ echo '<li><code>%%date_of_birth%%</code> would be valid; if you have a Custom Registration/Profile Field with the ID <code>date_of_birth</code>.</li>'."\n";
328
+ echo '<li><code>%%street_address%%</code> would be valid; if you have a Custom Registration/Profile Field with the ID <code>street_address</code>.</li>'."\n";
329
+ echo '<li><code>%%country%%</code> would be valid; if you have a Custom Registration/Profile Field with the ID <code>country</code>.</li>'."\n";
330
+ echo '<li><em><code>%%etc, etc...%%</code> <strong>see:</strong> s2Member -› General Options -› Registration/Profile Fields</em>.</li>'."\n";
331
+ echo '</ul>'."\n";
332
+
333
+ echo '<strong>Custom Replacement Codes can also be inserted using these instructions:</strong>'."\n";
334
+ echo '<ul class="ws-menu-page-li-margins">'."\n";
335
+ echo '<li><code>%%cv0%%</code> = The domain of your site, which is passed through the `custom` attribute in your Shortcode.</li>'."\n";
336
+ echo '<li><code>%%cv1%%</code> = If you need to track additional custom variables, you can pipe delimit them into the `custom` attribute; inside your Shortcode, like this: <code>custom="'.esc_html($_SERVER["HTTP_HOST"]).'|cv1|cv2|cv3"</code>. You can have an unlimited number of custom variables. Obviously, this is for advanced webmasters; but the functionality has been made available for those who need it.</li>'."\n";
337
+ echo '</ul>'."\n";
338
+ echo '<strong>This example uses cv1 to record a special marketing campaign:</strong><br />'."\n";
339
+ echo '<em>(The campaign (i.e. christmas-promo) could be referenced using <code>%%cv1%%</code>)</em><br />'."\n";
340
+ echo '<code>custom="'.esc_html($_SERVER["HTTP_HOST"]).'|christmas-promo"</code>'."\n";
341
+
342
+ echo '</td>'."\n";
343
+
344
+ echo '</tr>'."\n";
345
+ echo '</tbody>'."\n";
346
+ echo '</table>'."\n";
347
+
348
+ echo '<div class="ws-menu-page-hr"></div>'."\n";
349
+
350
+ echo '<table class="form-table" style="margin-top:0;">'."\n";
351
+ echo '<tbody>'."\n";
352
+ echo '<tr>'."\n";
353
+
354
+ echo '<th style="padding-top:0;">'."\n";
355
+ echo '<label for="ws-plugin--s2member-payment-notification-recipients">'."\n";
356
+ echo 'Send An Email Transaction Log Of This Event?'."\n";
357
+ echo '</label>'."\n";
358
+ echo '</th>'."\n";
359
+
360
+ echo '</tr>'."\n";
361
+ echo '<tr>'."\n";
362
+
363
+ echo '<td>'."\n";
364
+ echo '<input type="text" autocomplete="off" name="ws_plugin__s2member_payment_notification_recipients" id="ws-plugin--s2member-payment-notification-recipients" value="'.format_to_edit($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["payment_notification_recipients"]).'" /><br />'."\n";
365
+ echo 'This is a semicolon ( ; ) delimited list of Recipients. Here is an example:<br />'."\n";
366
+ echo '<code>"John" &lt;john@example.com&gt;; admin@example.com; "Webmaster" &lt;webmaster@example.com&gt;</code>'."\n";
367
+ echo '</td>'."\n";
368
+
369
+ echo '</tr>'."\n";
370
+ echo '</tbody>'."\n";
371
+ echo '</table>'."\n";
372
+ echo '</div>'."\n";
373
+
374
+ echo '</div>'."\n";
375
+
376
+ do_action("ws_plugin__s2member_during_api_ops_page_during_left_sections_after_payment_notifications", get_defined_vars());
377
+ }
378
+
379
+ if(apply_filters("ws_plugin__s2member_during_api_ops_page_during_left_sections_display_modification_notifications", TRUE, get_defined_vars()))
380
+ {
381
+ do_action("ws_plugin__s2member_during_api_ops_page_during_left_sections_before_modification_notifications", get_defined_vars());
382
+
383
+ echo '<div class="ws-menu-page-group" title="Modification Notifications">'."\n";
384
+
385
+ echo '<div class="ws-menu-page-section ws-plugin--s2member-modification-notifications-section">'."\n";
386
+ echo '<h3>Modification Notification URLs (optional)</h3>'."\n";
387
+ echo '<p>If you use affiliate software, or have back-office routines that need to be notified each time a new Subscription is created by an "existing" User/Member, or an "existing" Member modifies their paid Subscription terms, you\'ll want to read this section. This is marked `Modification`, because the URLs that you list below, will be notified each time an "existing" User/Member <em>(even if they are/were a Free Subscriber)</em> signs up for a paid Subscription <em>(i.e. a Modification takes place against an existing account within WordPress)</em>, or an "existing" Member modifies their paid Subscription terms <em>(again, a Modification takes places against an existing account within WordPress)</em>. Depending on your fee structure, this may include a payment that establishes their Subscription, or it may not.</p>'."\n";
388
+ echo '<p>Modification Notifications are sent right after a Member signs up and/or modifies billing terms successfully through your Payment Gateway, regardless of whether any money has actually been transacted. In other words, this Notification is triggered, even if you provided them with something for free <em>(i.e. even if no money is being transacted)</em>.</p>'."\n";
389
+ echo '<p>This Notification will NOT be processed for "new" Users/Members <em>(see: Signup Notifications for that scenario)</em>.'.((is_multisite() && c_ws_plugin__s2member_utils_conds::is_multisite_farm() && !is_main_site()) ? '' : ' And, this Notification will NOT be processed for Independent Custom Capability purchases <em>(see: Payment Notifications for that scenario)</em>.').'</p>'."\n";
390
+ echo '<p>Please note, this feature is not to be confused with the PayPal IPN service. PayPal IPN <em>(and other service integrations)</em> are already built into s2Member. They remain active at all times. These Modification Notifications are an added layer of functionality, and they are completely optional.</p>'."\n";
391
+ echo '<p><strong>See also:</strong> This KB article: <a href="http://www.s2member.com/kb/building-an-api-notification-handler/" target="_blank" rel="external">Building An API Notification Handler</a>.</p>'."\n";
392
+ do_action("ws_plugin__s2member_during_api_ops_page_during_left_sections_during_modification_notifications", get_defined_vars());
393
+
394
+ echo '<table class="form-table">'."\n";
395
+ echo '<tbody>'."\n";
396
+ echo '<tr>'."\n";
397
+
398
+ echo '<th>'."\n";
399
+ echo '<label for="ws-plugin--s2member-modification-notification-urls">'."\n";
400
+ echo 'Modification Notification URLs:'."\n";
401
+ echo '</label>'."\n";
402
+ echo '</th>'."\n";
403
+
404
+ echo '</tr>'."\n";
405
+ echo '<tr>'."\n";
406
+
407
+ echo '<td>'."\n";
408
+ echo 'You can input multiple Notification URLs by inserting one per line.<br />'."\n";
409
+ echo '<textarea name="ws_plugin__s2member_modification_notification_urls" id="ws-plugin--s2member-modification-notification-urls" rows="3" wrap="off">'.format_to_edit($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["modification_notification_urls"]).'</textarea><br />'."\n";
410
+ echo 'Modification Notifications take place silently behind-the-scene, using an HTTP connection.<br /><br />'."\n";
411
+ echo '<strong>You can also use these special Replacement Codes if you need them:</strong>'."\n";
412
+ echo '<ul class="ws-menu-page-li-margins">'."\n";
413
+ echo '<li><code>%%subscr_id%%</code> = The Paid Subscription ID, which remains constant throughout any &amp; all future payments. [ <a href="#" onclick="alert(\'There is one exception. If you are selling Lifetime or Fixed-Term (non-recurring) access, using Buy Now functionality; the %%subscr_id%% is actually set to the Transaction ID for the purchase. Payment Gateways do not provide a specific Subscription ID for Buy Now purchases. Since Lifetime &amp; Fixed-Term Subscriptions are NOT recurring (i.e. there is only ONE payment), using the Transaction ID as the Subscription ID is a graceful way to deal with this minor conflict.\'); return false;">?</a> ]</li>'."\n";
414
+ echo '<li><code>%%subscr_baid%%</code> = Applicable only with PayPal Pro (Payflow Edition); and only for Express Checkout transactions that require a Billing Agreement. This is the Subscription\'s Billing Agreement ID, which remains constant throughout any &amp; all future payments. [ <a href="#" onclick="alert(\'Applicable only with PayPal Pro (Payflow Edition); and only for Express Checkout transactions that require a Billing Agreement. In all other cases, the %%subscr_baid%% is simply set to the %%subscr_id%% value; i.e. it is a duplicate of %%subscr_id%% in most cases.\'); return false;">?</a> ]</li>'."\n";
415
+ echo '<li><code>%%subscr_cid%%</code> = Applicable only with Stripe integration. This is the Customer\'s ID in Stripe, which remains constant throughout any &amp; all future payments. Each Stripe Customer has this Customer ID; and also a Subscription and/or Transaction ID [ <a href="#" onclick="alert(\'Applicable only when you integrate s2Member with Stripe. In all other cases, the %%subscr_cid%% is simply set to the %%subscr_id%% value; i.e. it is a duplicate of %%subscr_id%% when running anything other than Stripe.\\n\\nEach Stripe Customer has a Customer ID; and also a Subscription and/or Transaction ID. See %%subscr_id%% for further details.\'); return false;">?</a> ]</li>'."\n";
416
+ echo '<li><code>%%currency%%</code> = Three-character currency code (uppercase); e.g. <code>USD</code></li>'."\n";
417
+ echo '<li><code>%%currency_symbol%%</code> = Currency code symbol; e.g. <code>$</code></li>'."\n";
418
+ echo '<li><code>%%initial%%</code> = The Initial Fee. If you offered a 100% Free Trial, this will be <code>0</code>. [ <a href="#" onclick="alert(\'This will always represent the amount of money the Customer spent when they completed checkout, no matter what. Even if that amount is 0.\\n\\nIf a Customer upgrades/downgrades under the terms of a 100% Free Trial Period, this will be 0. So, please be careful using %%initial%% when you offer a 100% Free Trial Period, because a $0.00 sale amount could cause havoc with affiliate programs.\\n\\nIf you\\\'re offering a 100% Free Trial Period, and you need to track sales through affiliate programs, you can either hard-code an amount; or use `Payment Notifications` instead.\'); return false;">?</a> ]</li>'."\n";
419
+ echo '<li><code>%%regular%%</code> = The Regular Amount of the Subscription. If you offer something 100% free, this will be <code>0</code>. [ <a href="#" onclick="alert(\'This is how much the Subscription costs after an Initial Period expires. If you did NOT offer an Initial Period at a different price, %%initial%% and %%regular%% will be equal to the same thing.\'); return false;">?</a> ]</li>'."\n";
420
+ echo '<li><code>%%recurring%%</code> = This is the amount that will be charged on a recurring basis, or <code>0</code> if non-recurring. [ <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.\'); return false;">?</a> ]</li>'."\n";
421
+ echo '<li><code>%%first_name%%</code> = The First Name of the Customer who purchased the Membership Subscription.</li>'."\n";
422
+ echo '<li><code>%%last_name%%</code> = The Last Name of the Customer who purchased the Membership Subscription.</li>'."\n";
423
+ echo '<li><code>%%full_name%%</code> = The Full Name (First &amp; Last) of the Customer who purchased the Membership Subscription.</li>'."\n";
424
+ echo '<li><code>%%payer_email%%</code> = The Email Address of the Customer who purchased the Membership Subscription.</li>'."\n";
425
+ echo '<li><code>%%item_number%%</code> = The Item Number (colon separated <code><em>level:custom_capabilities:fixed term</em></code>) for the Membership Subscription.</li>'."\n";
426
+ echo '<li><code>%%item_name%%</code> = The Item Name (as provided by the <code>desc=""</code> attribute in your Shortcode, which briefly describes the Item Number).</li>'."\n";
427
+ echo '<li><code>%%initial_term%%</code> = This is the term length of the Initial Period. This will be a numeric value, followed by a space, then a single letter. [ <a href="#" onclick="alert(\'Here are some examples:\\n\\n%%initial_term%% = 1 D (this means 1 Day)\\n%%initial_term%% = 1 W (this means 1 Week)\\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.\'); return false;">?</a> ]</li>'."\n";
428
+ echo '<li><code>%%regular_term%%</code> = This is the term length of the Regular Period. This will be a numeric value, followed by a space, then a single letter. [ <a href="#" onclick="alert(\'Here are some examples:\\n\\n%%regular_term%% = 1 D (this means 1 Day)\\n%%regular_term%% = 1 W (this means 1 Week)\\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";
429
+ echo '<li><code>%%user_first_name%%</code> = The First Name listed on their User account. This might be different than what is on file with your Payment Gateway.</li>'."\n";
430
+ echo '<li><code>%%user_last_name%%</code> = The Last Name listed on their User account. This might be different than what is on file with your Payment Gateway.</li>'."\n";
431
+ echo '<li><code>%%user_full_name%%</code> = The Full Name listed on their User account. This might be different than what is on file with your Payment Gateway.</li>'."\n";
432
+ echo '<li><code>%%user_email%%</code> = The Email Address associated with their User account. This might be different than what is on file with your Payment Gateway.</li>'."\n";
433
+ echo '<li><code>%%user_login%%</code> = The Username associated with their account. The Customer created this during registration.</li>'."\n";
434
+ echo '<li><code>%%user_ip%%</code> = The Customer\'s original IP Address, during checkout/registration via <code>$_SERVER["REMOTE_ADDR"]</code>.</li>'."\n";
435
+ echo '<li><code>%%user_id%%</code> = A unique WordPress User ID that references this account in the WordPress database.</li>'."\n";
436
+ echo '</ul>'."\n";
437
+
438
+ if(c_ws_plugin__s2member_utils_conds::pro_is_installed())
439
+ {
440
+ echo '<strong>Coupon Replacement Codes (applicable only w/ s2Member Pro Forms):</strong>'."\n";
441
+ echo '<ul class="ws-menu-page-li-margins">'."\n";
442
+ echo '<li><code>%%full_coupon_code%%</code> = A full Coupon Code — if one is accepted by your configuration of s2Member. This may indicate an Affiliate Coupon Code, which will include your Affiliate Suffix Chars too (i.e. the full Coupon Code).</li>'."\n";
443
+ echo '<li><code>%%coupon_code%%</code> = A Coupon Code — if one is accepted by your configuration of s2Member. This will NOT include any Affiliate Suffix Chars. This indicates the actual Coupon Code accepted by your configuration of s2Member (excluding any Affiliate ID).</li>'."\n";
444
+ echo '<li><code>%%coupon_affiliate_id%%</code> = This is the end of an Affiliate Coupon Code <em>(i.e. the referring affiliate\'s ID)</em>. This is only applicable if an Affiliate Coupon Code is accepted by your configuration of s2Member.</li>'."\n";
445
+ echo '</ul>'."\n";
446
+ }
447
+
448
+ echo '<strong>Custom Registration/Profile Fields are also supported in this Notification:</strong>'."\n";
449
+ echo '<ul class="ws-menu-page-li-margins">'."\n";
450
+ echo '<li><code>%%date_of_birth%%</code> would be valid; if you have a Custom Registration/Profile Field with the ID <code>date_of_birth</code>.</li>'."\n";
451
+ echo '<li><code>%%street_address%%</code> would be valid; if you have a Custom Registration/Profile Field with the ID <code>street_address</code>.</li>'."\n";
452
+ echo '<li><code>%%country%%</code> would be valid; if you have a Custom Registration/Profile Field with the ID <code>country</code>.</li>'."\n";
453
+ echo '<li><em><code>%%etc, etc...%%</code> <strong>see:</strong> s2Member -› General Options -› Registration/Profile Fields</em>.</li>'."\n";
454
+ echo '</ul>'."\n";
455
+
456
+ echo '<strong>Custom Replacement Codes can also be inserted using these instructions:</strong>'."\n";
457
+ echo '<ul class="ws-menu-page-li-margins">'."\n";
458
+ echo '<li><code>%%cv0%%</code> = The domain of your site, which is passed through the `custom` attribute in your Shortcode.</li>'."\n";
459
+ echo '<li><code>%%cv1%%</code> = If you need to track additional custom variables, you can pipe delimit them into the `custom` attribute; inside your Shortcode, like this: <code>custom="'.esc_html($_SERVER["HTTP_HOST"]).'|cv1|cv2|cv3"</code>. You can have an unlimited number of custom variables. Obviously, this is for advanced webmasters; but the functionality has been made available for those who need it.</li>'."\n";
460
+ echo '</ul>'."\n";
461
+ echo '<strong>This example uses cv1 to record a special marketing campaign:</strong><br />'."\n";
462
+ echo '<em>(The campaign (i.e. christmas-promo) could be referenced using <code>%%cv1%%</code>)</em><br />'."\n";
463
+ echo '<code>custom="'.esc_html($_SERVER["HTTP_HOST"]).'|christmas-promo"</code>'."\n";
464
+
465
+ echo '</td>'."\n";
466
+
467
+ echo '</tr>'."\n";
468
+ echo '</tbody>'."\n";
469
+ echo '</table>'."\n";
470
+
471
+ echo '<div class="ws-menu-page-hr"></div>'."\n";
472
+
473
+ echo '<table class="form-table" style="margin-top:0;">'."\n";
474
+ echo '<tbody>'."\n";
475
+ echo '<tr>'."\n";
476
+
477
+ echo '<th style="padding-top:0;">'."\n";
478
+ echo '<label for="ws-plugin--s2member-modification-notification-recipients">'."\n";
479
+ echo 'Send An Email Transaction Log Of This Event?'."\n";
480
+ echo '</label>'."\n";
481
+ echo '</th>'."\n";
482
+
483
+ echo '</tr>'."\n";
484
+ echo '<tr>'."\n";
485
+
486
+ echo '<td>'."\n";
487
+ echo '<input type="text" autocomplete="off" name="ws_plugin__s2member_modification_notification_recipients" id="ws-plugin--s2member-modification-notification-recipients" value="'.format_to_edit($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["modification_notification_recipients"]).'" /><br />'."\n";
488
+ echo 'This is a semicolon ( ; ) delimited list of Recipients. Here is an example:<br />'."\n";
489
+ echo '<code>"John" &lt;john@example.com&gt;; admin@example.com; "Webmaster" &lt;webmaster@example.com&gt;</code>'."\n";
490
+ echo '</td>'."\n";
491
+
492
+ echo '</tr>'."\n";
493
+ echo '</tbody>'."\n";
494
+ echo '</table>'."\n";
495
+ echo '</div>'."\n";
496
+
497
+ echo '</div>'."\n";
498
+ }
499
+
500
+ if(apply_filters("ws_plugin__s2member_during_api_ops_page_during_left_sections_display_cancellation_notifications", TRUE, get_defined_vars()))
501
+ {
502
+ do_action("ws_plugin__s2member_during_api_ops_page_during_left_sections_before_cancellation_notifications", get_defined_vars());
503
+
504
+ echo '<div class="ws-menu-page-group" title="Cancellation Notifications">'."\n";
505
+
506
+ echo '<div class="ws-menu-page-section ws-plugin--s2member-cancellation-notifications-section">'."\n";
507
+ echo '<h3>Cancellation Notification URLs (optional)</h3>'."\n";
508
+ echo '<p>If you use affiliate software, or have back-office routines that need to be notified whenever Subscriptions are cancelled through your Payment Gateway, you\'ll want to read this section. This is marked `Cancellation`, because the URLs that you list below, will be notified each time a Subscription is cancelled. A Cancellation is triggered when you cancel a Customer\'s Subscription through your Payment Gateway, or when a Customer cancels their own Subscription.</p>'."\n";
509
+ echo '<p>Please note, this feature is not to be confused with the PayPal IPN service. PayPal IPN <em>(and other service integrations)</em> are already built into s2Member. They remain active at all times. These Cancellation Notifications are an added layer of functionality, and they are completely optional.</p>'."\n";
510
+ echo '<p><em><strong>*Understanding Cancellations*</strong> It\'s important to realize that a Cancellation is not an EOT (End Of Term). All that happens during a Cancellation event, is that billing is stopped, and it\'s understood that the Customer is going to lose access, at some point in the future. This does NOT mean, that access will be revoked immediately. A separate EOT event will automatically handle a (demotion or deletion) later, at the appropriate time; which could be several days, or even a year after the Cancellation took place.</em></p>'."\n";
511
+ echo '<p><em><strong>*Some Hairy Details*</strong> There might be times whenever you notice that a Member\'s Subscription has been cancelled through your Payment Gateway... but, s2Member continues allowing the User access to your site as a paid Member. Please don\'t be confused by this... in 99.9% of these cases, the reason for this is legitimate. s2Member will only remove the User\'s Membership privileges when an EOT (End Of Term) is processed, a refund occurs, a chargeback occurs, or when a cancellation occurs - which would later result in a delayed Auto-EOT by s2Member.</em></p>'."\n";
512
+ echo '<p><em>s2Member will not process an EOT (End Of Term) until the User has completely used up the time they paid for. In other words, if a User signs up for a monthly Subscription on Jan 1st, and then cancels their Subscription on Jan 15th; technically, they should still be allowed to access the site for another 15 days, and then on Feb 1st, the time they paid for has completely elapsed. At that time, s2Member will remove their Membership privileges; by either demoting them to a Free Subscriber, or deleting their account from the system (based on your configuration). s2Member also calculates one extra day (24 hours) into its equation, just to make sure access is not removed sooner than a Customer might expect.</em></p>'."\n";
513
+ echo '<p><strong>See also:</strong> This KB article: <a href="http://www.s2member.com/kb/building-an-api-notification-handler/" target="_blank" rel="external">Building An API Notification Handler</a>.</p>'."\n";
514
+ do_action("ws_plugin__s2member_during_api_ops_page_during_left_sections_during_cancellation_notifications", get_defined_vars());
515
+
516
+ echo '<table class="form-table">'."\n";
517
+ echo '<tbody>'."\n";
518
+ echo '<tr>'."\n";
519
+
520
+ echo '<th>'."\n";
521
+ echo '<label for="ws-plugin--s2member-cancellation-notification-urls">'."\n";
522
+ echo 'Cancellation Notification URLs:'."\n";
523
+ echo '</label>'."\n";
524
+ echo '</th>'."\n";
525
+
526
+ echo '</tr>'."\n";
527
+ echo '<tr>'."\n";
528
+
529
+ echo '<td>'."\n";
530
+ echo 'You can input multiple Notification URLs by inserting one per line.<br />'."\n";
531
+ echo '<textarea name="ws_plugin__s2member_cancellation_notification_urls" id="ws-plugin--s2member-cancellation-notification-urls" rows="3" wrap="off">'.format_to_edit($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["cancellation_notification_urls"]).'</textarea><br />'."\n";
532
+ echo 'Cancellation Notifications take place silently behind-the-scene, using an HTTP connection.<br /><br />'."\n";
533
+ echo '<strong>You can also use these special Replacement Codes if you need them:</strong>'."\n";
534
+ echo '<ul class="ws-menu-page-li-margins">'."\n";
535
+ echo '<li><code>%%subscr_id%%</code> = The Paid Subscription ID, which remained constant throughout the lifetime of the Membership. [ <a href="#" onclick="alert(\'There is one exception. If you are selling Lifetime or Fixed-Term (non-recurring) access, using Buy Now functionality; the %%subscr_id%% is actually set to the original Transaction ID for the purchase. Payment Gateways do not provide a specific Subscription ID for Buy Now purchases. Since Lifetime &amp; Fixed-Term Subscriptions are NOT recurring (i.e. there was only ONE payment), using the Transaction ID as the Subscription ID is a graceful way to deal with this minor conflict.\'); return false;">?</a> ]</li>'."\n";
536
+ echo '<li><code>%%subscr_baid%%</code> = Applicable only with PayPal Pro (Payflow Edition); and only for Express Checkout transactions that required a Billing Agreement. This is the Subscription\'s Billing Agreement ID, which remained constant throughout the lifetime of the Membership. [ <a href="#" onclick="alert(\'Applicable only with PayPal Pro (Payflow Edition); and only for Express Checkout transactions that required a Billing Agreement. In all other cases, the %%subscr_baid%% is simply set to the %%subscr_id%% value; i.e. it is a duplicate of %%subscr_id%% in most cases.\'); return false;">?</a> ]</li>'."\n";
537
+ echo '<li><code>%%subscr_cid%%</code> = Applicable only with Stripe integration. This is the Customer\'s ID in Stripe, which remained constant throughout the lifetime of the Membership. Each Stripe Customer has this Customer ID; and also a Subscription and/or Transaction ID [ <a href="#" onclick="alert(\'Applicable only when you integrate s2Member with Stripe. In all other cases, the %%subscr_cid%% is simply set to the %%subscr_id%% value; i.e. it is a duplicate of %%subscr_id%% when running anything other than Stripe.\\n\\nEach Stripe Customer has a Customer ID; and also a Subscription and/or Transaction ID. See %%subscr_id%% for further details.\'); return false;">?</a> ]</li>'."\n";
538
+ echo '<li><code>%%item_number%%</code> = The Item Number (colon separated <em>level:custom_capabilities:fixed term</em>) that the Subscription was for.</li>'."\n";
539
+ echo '<li><code>%%item_name%%</code> = The Item Name (as provided by the <code>desc=""</code> attribute in your Shortcode, which briefly describes the Item Number).</li>'."\n";
540
+ echo '<li><code>%%user_first_name%%</code> = The First Name listed on their User account. This might be different than what is on file with your Payment Gateway.</li>'."\n";
541
+ echo '<li><code>%%user_last_name%%</code> = The Last Name listed on their User account. This might be different than what is on file with your Payment Gateway.</li>'."\n";
542
+ echo '<li><code>%%user_full_name%%</code> = The Full Name listed on their User account. This might be different than what is on file with your Payment Gateway.</li>'."\n";
543
+ echo '<li><code>%%user_email%%</code> = The Email Address associated with their User account. This might be different than what is on file with your Payment Gateway.</li>'."\n";
544
+ echo '<li><code>%%user_login%%</code> = The Username associated with their account. The Customer created this during registration.</li>'."\n";
545
+ echo '<li><code>%%user_ip%%</code> = The Customer\'s original IP Address, during checkout/registration via <code>$_SERVER["REMOTE_ADDR"]</code>.</li>'."\n";
546
+ echo '<li><code>%%user_id%%</code> = A unique WordPress User ID that references this account in the WordPress database.</li>'."\n";
547
+ echo '</ul>'."\n";
548
+
549
+ echo '<strong>Custom Registration/Profile Fields are also supported in this Notification:</strong>'."\n";
550
+ echo '<ul class="ws-menu-page-li-margins">'."\n";
551
+ echo '<li><code>%%date_of_birth%%</code> would be valid; if you have a Custom Registration/Profile Field with the ID <code>date_of_birth</code>.</li>'."\n";
552
+ echo '<li><code>%%street_address%%</code> would be valid; if you have a Custom Registration/Profile Field with the ID <code>street_address</code>.</li>'."\n";
553
+ echo '<li><code>%%country%%</code> would be valid; if you have a Custom Registration/Profile Field with the ID <code>country</code>.</li>'."\n";
554
+ echo '<li><em><code>%%etc, etc...%%</code> <strong>see:</strong> s2Member -› General Options -› Registration/Profile Fields</em>.</li>'."\n";
555
+ echo '</ul>'."\n";
556
+
557
+ echo '<strong>Custom Replacement Codes can also be inserted using these instructions:</strong>'."\n";
558
+ echo '<ul class="ws-menu-page-li-margins">'."\n";
559
+ echo '<li><code>%%cv0%%</code> = The domain of your site, which is passed through the `custom` attribute in your Shortcode.</li>'."\n";
560
+ echo '<li><code>%%cv1%%</code> = If you need to track additional custom variables, you can pipe delimit them into the `custom` attribute; inside your Shortcode, like this: <code>custom="'.esc_html($_SERVER["HTTP_HOST"]).'|cv1|cv2|cv3"</code>. You can have an unlimited number of custom variables. Obviously, this is for advanced webmasters; but the functionality has been made available for those who need it.</li>'."\n";
561
+ echo '</ul>'."\n";
562
+ echo '<strong>This example uses cv1 to record a special marketing campaign:</strong><br />'."\n";
563
+ echo '<em>(The campaign (i.e. christmas-promo) could be referenced using <code>%%cv1%%</code>)</em><br />'."\n";
564
+ echo '<code>custom="'.esc_html($_SERVER["HTTP_HOST"]).'|christmas-promo"</code>'."\n";
565
+
566
+ echo '</td>'."\n";
567
+
568
+ echo '</tr>'."\n";
569
+ echo '</tbody>'."\n";
570
+ echo '</table>'."\n";
571
+
572
+ echo '<div class="ws-menu-page-hr"></div>'."\n";
573
+
574
+ echo '<table class="form-table" style="margin-top:0;">'."\n";
575
+ echo '<tbody>'."\n";
576
+ echo '<tr>'."\n";
577
+
578
+ echo '<th style="padding-top:0;">'."\n";
579
+ echo '<label for="ws-plugin--s2member-cancellation-notification-recipients">'."\n";
580
+ echo 'Send An Email Transaction Log Of This Event?'."\n";
581
+ echo '</label>'."\n";
582
+ echo '</th>'."\n";
583
+
584
+ echo '</tr>'."\n";
585
+ echo '<tr>'."\n";
586
+
587
+ echo '<td>'."\n";
588
+ echo '<input type="text" autocomplete="off" name="ws_plugin__s2member_cancellation_notification_recipients" id="ws-plugin--s2member-cancellation-notification-recipients" value="'.format_to_edit($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["cancellation_notification_recipients"]).'" /><br />'."\n";
589
+ echo 'This is a semicolon ( ; ) delimited list of Recipients. Here is an example:<br />'."\n";
590
+ echo '<code>"John" &lt;john@example.com&gt;; admin@example.com; "Webmaster" &lt;webmaster@example.com&gt;</code>'."\n";
591
+ echo '</td>'."\n";
592
+
593
+ echo '</tr>'."\n";
594
+ echo '</tbody>'."\n";
595
+ echo '</table>'."\n";
596
+ echo '</div>'."\n";
597
+
598
+ echo '</div>'."\n";
599
+
600
+ do_action("ws_plugin__s2member_during_api_ops_page_during_left_sections_after_cancellation_notifications", get_defined_vars());
601
+ }
602
+
603
+ if(apply_filters("ws_plugin__s2member_during_api_ops_page_during_left_sections_display_eot_deletion_notifications", TRUE, get_defined_vars()))
604
+ {
605
+ do_action("ws_plugin__s2member_during_api_ops_page_during_left_sections_before_eot_deletion_notifications", get_defined_vars());
606
+
607
+ echo '<div class="ws-menu-page-group" title="EOT/Deletion Notifications">'."\n";
608
+
609
+ echo '<div class="ws-menu-page-section ws-plugin--s2member-eot-deletion-notifications-section">'."\n";
610
+ echo '<h3>EOT/Deletion Notification URLs (optional)</h3>'."\n";
611
+ echo '<p>If you use affiliate software, or have back-office routines that need to be notified whenever Subscriptions have ended <em>(and a Member is demoted to a Free Subscriber)</em>, 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.</p>'."\n";
612
+ echo '<p><strong>EOT = End Of Term.</strong> An EOT is triggered <em>immediately</em> when you refund a Customer, when a Customer forces a chargeback to occur, or when a paid Subscription ends naturally <em>(i.e. expires)</em>, and your Payment Gateway sends s2Member an EOT (End Of Term) response. Delayed EOTs occur after a Cancellation, either as a result of you cancelling a Customer\'s Subscription, or a Customer cancelling their own Subscription. A Cancellation usually results in a delayed EOT, because a Cancellation does NOT always warrant an immediate action; there could still be time left on their Subscription.</p>'."\n";
613
+ echo '<p>Manual Deletions will trigger this Notification too. If you delete an account manually from within your WordPress Dashboard, your URLs can be notified automatically through this API Notification, and this scenario can be detected through the Replacement Code <code>%%eot_del_type%%</code>, which is documented below. So the two events are an EOT <em>(of any kind)</em> and/or a Manual Deletion.</p>'."\n";
614
+ echo '<p>Please note, this feature is not to be confused with the PayPal IPN service. PayPal IPN <em>(and other service integrations)</em> are already built into s2Member. They remain active at all times. These EOT/Deletion Notifications are an added layer of functionality, and they are completely optional.</p>'."\n";
615
+ echo '<p><em><strong>*Some Hairy Details*</strong> There might be times whenever you notice that a Member\'s Subscription has been cancelled through your Payment Gateway... but, s2Member continues allowing the User access to your site as a paid Member. Please don\'t be confused by this... in 99.9% of these cases, the reason for this is legitimate. s2Member will only remove the User\'s Membership privileges when an EOT (End Of Term) is processed, a refund occurs, a chargeback occurs, or when a cancellation occurs - which would later result in a delayed Auto-EOT by s2Member.</em></p>'."\n";
616
+ echo '<p><em>s2Member will not process an EOT (End Of Term) until the User has completely used up the time they paid for. In other words, if a User signs up for a monthly Subscription on Jan 1st, and then cancels their Subscription on Jan 15th; technically, they should still be allowed to access the site for another 15 days, and then on Feb 1st, the time they paid for has completely elapsed. At that time, s2Member will remove their Membership privileges; by either demoting them to a Free Subscriber, or deleting their account from the system (based on your configuration). s2Member also calculates one extra day (24 hours) into its equation, just to make sure access is not removed sooner than a Customer might expect.</em></p>'."\n";
617
+ echo '<p><strong>See also:</strong> This KB article: <a href="http://www.s2member.com/kb/building-an-api-notification-handler/" target="_blank" rel="external">Building An API Notification Handler</a>.</p>'."\n";
618
+ do_action("ws_plugin__s2member_during_api_ops_page_during_left_sections_during_eot_deletion_notifications", get_defined_vars());
619
+
620
+ echo '<table class="form-table">'."\n";
621
+ echo '<tbody>'."\n";
622
+ echo '<tr>'."\n";
623
+
624
+ echo '<th>'."\n";
625
+ echo '<label for="ws-plugin--s2member-eot-del-notification-urls">'."\n";
626
+ echo 'EOT/Deletion Notification URLs:'."\n";
627
+ echo '</label>'."\n";
628
+ echo '</th>'."\n";
629
+
630
+ echo '</tr>'."\n";
631
+ echo '<tr>'."\n";
632
+
633
+ echo '<td>'."\n";
634
+ echo 'You can input multiple Notification URLs by inserting one per line.<br />'."\n";
635
+ 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";
636
+ echo 'EOT/Deletion Notifications take place silently behind-the-scene, using an HTTP connection.<br /><br />'."\n";
637
+ echo '<strong>You can also use these special Replacement Codes if you need them:</strong>'."\n";
638
+ echo '<ul class="ws-menu-page-li-margins">'."\n";
639
+ echo '<li><code>%%eot_del_type%%</code> = The type of event that triggered this Notification. [ <a href="#" onclick="alert(\'List of possible values:\\n\\nuser-removal-deletion (i.e. manual removal/deletion)\\nauto-eot-cancellation-expiration-demotion\\nauto-eot-cancellation-expiration-deletion\\nipn-cancellation-expiration-demotion\\nipn-cancellation-expiration-deletion\\nipn-refund-reversal-demotion\\nipn-refund-reversal-deletion\'); return false;">list of possible values</a> ]</li>'."\n";
640
+ echo '<li><code>%%subscr_id%%</code> = The Paid Subscription ID, which remained constant throughout the lifetime of the Membership. [ <a href="#" onclick="alert(\'There is one exception. If you are selling Lifetime or Fixed-Term (non-recurring) access, using Buy Now functionality; the %%subscr_id%% is actually set to the original Transaction ID for the purchase. Payment Gateways do not provide a specific Subscription ID for Buy Now purchases. Since Lifetime &amp; Fixed-Term Subscriptions are NOT recurring (i.e. there was only ONE payment), using the Transaction ID as the Subscription ID is a graceful way to deal with this minor conflict.\'); return false;">?</a> ]</li>'."\n";
641
+ echo '<li><code>%%subscr_baid%%</code> = Applicable only with PayPal Pro (Payflow Edition); and only for Express Checkout transactions that required a Billing Agreement. This is the Subscription\'s Billing Agreement ID, which remained constant throughout the lifetime of the Membership. [ <a href="#" onclick="alert(\'Applicable only with PayPal Pro (Payflow Edition); and only for Express Checkout transactions that required a Billing Agreement. In all other cases, the %%subscr_baid%% is simply set to the %%subscr_id%% value; i.e. it is a duplicate of %%subscr_id%% in most cases.\'); return false;">?</a> ]</li>'."\n";
642
+ echo '<li><code>%%subscr_cid%%</code> = Applicable only with Stripe integration. This is the Customer\'s ID in Stripe, which remained constant throughout the lifetime of the Membership. Each Stripe Customer has this Customer ID; and also a Subscription and/or Transaction ID [ <a href="#" onclick="alert(\'Applicable only when you integrate s2Member with Stripe. In all other cases, the %%subscr_cid%% is simply set to the %%subscr_id%% value; i.e. it is a duplicate of %%subscr_id%% when running anything other than Stripe.\\n\\nEach Stripe Customer has a Customer ID; and also a Subscription and/or Transaction ID. See %%subscr_id%% for further details.\'); return false;">?</a> ]</li>'."\n";
643
+ echo '<li><code>%%user_first_name%%</code> = The First Name listed on their User account. This might be different than what is on file with your Payment Gateway.</li>'."\n";
644
+ echo '<li><code>%%user_last_name%%</code> = The Last Name listed on their User account. This might be different than what is on file with your Payment Gateway.</li>'."\n";
645
+ echo '<li><code>%%user_full_name%%</code> = The Full Name listed on their User account. This might be different than what is on file with your Payment Gateway.</li>'."\n";
646
+ echo '<li><code>%%user_email%%</code> = The Email Address associated with their User account. This might be different than what is on file with your Payment Gateway.</li>'."\n";
647
+ echo '<li><code>%%user_login%%</code> = The Username associated with their account. The Customer created this during registration.</li>'."\n";
648
+ echo '<li><code>%%user_ip%%</code> = The Customer\'s original IP Address, during checkout/registration via <code>$_SERVER["REMOTE_ADDR"]</code>.</li>'."\n";
649
+ echo '<li><code>%%user_id%%</code> = A unique WordPress User ID that references this account in the WordPress database.</li>'."\n";
650
+ echo '</ul>'."\n";
651
+
652
+ echo '<strong>Custom Registration/Profile Fields are also supported in this Notification:</strong>'."\n";
653
+ echo '<ul class="ws-menu-page-li-margins">'."\n";
654
+ echo '<li><code>%%date_of_birth%%</code> would be valid; if you have a Custom Registration/Profile Field with the ID <code>date_of_birth</code>.</li>'."\n";
655
+ echo '<li><code>%%street_address%%</code> would be valid; if you have a Custom Registration/Profile Field with the ID <code>street_address</code>.</li>'."\n";
656
+ echo '<li><code>%%country%%</code> would be valid; if you have a Custom Registration/Profile Field with the ID <code>country</code>.</li>'."\n";
657
+ echo '<li><em><code>%%etc, etc...%%</code> <strong>see:</strong> s2Member -› General Options -› Registration/Profile Fields</em>.</li>'."\n";
658
+ echo '</ul>'."\n";
659
+
660
+ echo '<strong>Custom Replacement Codes can also be inserted using these instructions:</strong>'."\n";
661
+ echo '<ul class="ws-menu-page-li-margins">'."\n";
662
+ echo '<li><code>%%cv0%%</code> = The domain of your site, which is passed through the `custom` attribute in your Shortcode.</li>'."\n";
663
+ echo '<li><code>%%cv1%%</code> = If you need to track additional custom variables, you can pipe delimit them into the `custom` attribute; inside your Shortcode, like this: <code>custom="'.esc_html($_SERVER["HTTP_HOST"]).'|cv1|cv2|cv3"</code>. You can have an unlimited number of custom variables. Obviously, this is for advanced webmasters; but the functionality has been made available for those who need it.</li>'."\n";
664
+ echo '</ul>'."\n";
665
+ echo '<strong>This example uses cv1 to record a special marketing campaign:</strong><br />'."\n";
666
+ echo '<em>(The campaign (i.e. christmas-promo) could be referenced using <code>%%cv1%%</code>)</em><br />'."\n";
667
+ echo '<code>custom="'.esc_html($_SERVER["HTTP_HOST"]).'|christmas-promo"</code>'."\n";
668
+
669
+ echo '</td>'."\n";
670
+
671
+ echo '</tr>'."\n";
672
+ echo '</tbody>'."\n";
673
+ echo '</table>'."\n";
674
+
675
+ echo '<div class="ws-menu-page-hr"></div>'."\n";
676
+
677
+ echo '<table class="form-table" style="margin-top:0;">'."\n";
678
+ echo '<tbody>'."\n";
679
+ echo '<tr>'."\n";
680
+
681
+ echo '<th style="padding-top:0;">'."\n";
682
+ echo '<label for="ws-plugin--s2member-eot-del-notification-recipients">'."\n";
683
+ echo 'Send An Email Transaction Log Of This Event?'."\n";
684
+ echo '</label>'."\n";
685
+ echo '</th>'."\n";
686
+
687
+ echo '</tr>'."\n";
688
+ echo '<tr>'."\n";
689
+
690
+ echo '<td>'."\n";
691
+ echo '<input type="text" autocomplete="off" name="ws_plugin__s2member_eot_del_notification_recipients" id="ws-plugin--s2member-eot-del-notification-recipients" value="'.format_to_edit($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["eot_del_notification_recipients"]).'" /><br />'."\n";
692
+ echo 'This is a semicolon ( ; ) delimited list of Recipients. Here is an example:<br />'."\n";
693
+ echo '<code>"John" &lt;john@example.com&gt;; admin@example.com; "Webmaster" &lt;webmaster@example.com&gt;</code>'."\n";
694
+ echo '</td>'."\n";
695
+
696
+ echo '</tr>'."\n";
697
+ echo '</tbody>'."\n";
698
+ echo '</table>'."\n";
699
+ echo '</div>'."\n";
700
+
701
+ echo '</div>'."\n";
702
+
703
+ do_action("ws_plugin__s2member_during_api_ops_page_during_left_sections_after_eot_deletion_notifications", get_defined_vars());
704
+ }
705
+
706
+ if(apply_filters("ws_plugin__s2member_during_api_ops_page_during_left_sections_display_refund_reversal_notifications", TRUE, get_defined_vars()))
707
  {
708
+ do_action("ws_plugin__s2member_during_api_ops_page_during_left_sections_before_refund_reversal_notifications", get_defined_vars());
709
+
710
+ echo '<div class="ws-menu-page-group" title="Refund/Reversal Notifications">'."\n";
711
+
712
+ echo '<div class="ws-menu-page-section ws-plugin--s2member-refund-reversal-notifications-section">'."\n";
713
+ echo '<h3>Refund/Reversal Notification URLs (optional)</h3>'."\n";
714
+ echo '<p>If you use affiliate software, or have back-office routines that need to be notified whenever Subscriptions have been refunded or reversed <em>(i.e. charged back to you)</em>, 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 EOT/Deletion Notifications, which are all-inclusive.</p>'."\n";
715
+ echo '<p>This is very similar to the EOT/Deletion Notification described above. However, there is an important distinction. The all-inclusive EOT/Deletion Notification includes cancellations, expirations, failed payments, refunds, chargebacks, and even manual deletions by the Administrator from within the Dashboard. In other words, EOT/Deletion Notifications are processed ANY time a deletion or End Of Term action takes place. This API Notification, that is, Refund/Reversal Notifications, do NOT include all of those scenarios.</p>'."\n";
716
+ echo '<p>So the distinction is that Refund/Reversal Notifications are ONLY sent under two specific circumstances: 1. You log into your Payment Gateway and refund a payment that is associated with a Subscription. 2. The Customer complains to your Payment Gateway and a chargeback occurs, forcing a Reversal. In both of these cases, an EOT/Deletion Notification will be sent <em>(as described in the previous section)</em>, but since EOT/Deletion is a broader Notification, these Refund/Reversal Notifications are here so you can nail down specific back-office operations in these two specific scenarios.</p>'."\n";
717
+ echo '<p>Please note, this feature is not to be confused with the PayPal IPN service. PayPal IPN <em>(and other service integrations)</em> are already built into s2Member. They remain active at all times. These Refund/Reversal Notifications are an added layer of functionality, and they are completely optional.</p>'."\n";
718
+ echo '<p><strong>See also:</strong> This KB article: <a href="http://www.s2member.com/kb/building-an-api-notification-handler/" target="_blank" rel="external">Building An API Notification Handler</a>.</p>'."\n";
719
+ do_action("ws_plugin__s2member_during_api_ops_page_during_left_sections_during_refund_reversal_notifications", get_defined_vars());
720
+
721
+ echo '<table class="form-table">'."\n";
722
+ echo '<tbody>'."\n";
723
+ echo '<tr>'."\n";
724
+
725
+ echo '<th>'."\n";
726
+ echo '<label for="ws-plugin--s2member-ref-rev-notification-urls">'."\n";
727
+ echo 'Refund/Reversal Notification URLs:'."\n";
728
+ echo '</label>'."\n";
729
+ echo '</th>'."\n";
730
+
731
+ echo '</tr>'."\n";
732
+ echo '<tr>'."\n";
733
+
734
+ echo '<td>'."\n";
735
+ echo 'You can input multiple Notification URLs by inserting one per line.<br />'."\n";
736
+ 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";
737
+ echo 'Refund/Reversal Notifications take place silently behind-the-scene, using an HTTP connection.<br /><br />'."\n";
738
+ echo '<strong>You can also use these special Replacement Codes if you need them:</strong>'."\n";
739
+ echo '<ul class="ws-menu-page-li-margins">'."\n";
740
+ echo '<li><code>%%subscr_id%%</code> = The Paid Subscription ID, which remained constant throughout the lifetime of the Membership. [ <a href="#" onclick="alert(\'There is one exception. If you are selling Lifetime or Fixed-Term (non-recurring) access, using Buy Now functionality; the %%subscr_id%% is actually set to the original Transaction ID for the purchase. Payment Gateways do not provide a specific Subscription ID for Buy Now purchases. Since Lifetime &amp; Fixed-Term Subscriptions are NOT recurring (i.e. there was only ONE payment), using the Transaction ID as the Subscription ID is a graceful way to deal with this minor conflict.\'); return false;">?</a> ]</li>'."\n";
741
+ echo '<li><code>%%subscr_baid%%</code> = Applicable only with PayPal Pro (Payflow Edition); and only for Express Checkout transactions that required a Billing Agreement. This is the Subscription\'s Billing Agreement ID, which remained constant throughout the lifetime of the Membership. [ <a href="#" onclick="alert(\'Applicable only with PayPal Pro (Payflow Edition); and only for Express Checkout transactions that required a Billing Agreement. In all other cases, the %%subscr_baid%% is simply set to the %%subscr_id%% value; i.e. it is a duplicate of %%subscr_id%% in most cases.\'); return false;">?</a> ]</li>'."\n";
742
+ echo '<li><code>%%subscr_cid%%</code> = Applicable only with Stripe integration. This is the Customer\'s ID in Stripe, which remained constant throughout the lifetime of the Membership. Each Stripe Customer has this Customer ID; and also a Subscription and/or Transaction ID [ <a href="#" onclick="alert(\'Applicable only when you integrate s2Member with Stripe. In all other cases, the %%subscr_cid%% is simply set to the %%subscr_id%% value; i.e. it is a duplicate of %%subscr_id%% when running anything other than Stripe.\\n\\nEach Stripe Customer has a Customer ID; and also a Subscription and/or Transaction ID. See %%subscr_id%% for further details.\'); return false;">?</a> ]</li>'."\n";
743
+ echo '<li><code>%%parent_txn_id%%</code> = The Parent Transaction ID, associated with the original payment being refunded/reversed.</li>'."\n";
744
+ echo '<li><code>%%currency%%</code> = Three-character currency code (uppercase); e.g. <code>USD</code></li>'."\n";
745
+ echo '<li><code>%%currency_symbol%%</code> = Currency code symbol; e.g. <code>$</code></li>'."\n";
746
+ echo '<li><code>%%-amount%%</code> = The Negative Amount of the payment, that was refunded or reversed back to the Customer.</li>'."\n";
747
+ echo '<li><code>%%-fee%%</code> = The Negative Payment Gateway fee, that was refunded back to you as the Merchant/Seller.</li>'."\n";
748
+ echo '<li><code>%%first_name%%</code> = The First Name of the Customer who purchased the Membership Subscription.</li>'."\n";
749
+ echo '<li><code>%%last_name%%</code> = The Last Name of the Customer who purchased the Membership Subscription.</li>'."\n";
750
+ echo '<li><code>%%full_name%%</code> = The Full Name (First &amp; Last) of the Customer who purchased the Membership Subscription.</li>'."\n";
751
+ echo '<li><code>%%payer_email%%</code> = The Email Address of the Customer who purchased the Membership Subscription.</li>'."\n";
752
+ echo '<li><code>%%item_number%%</code> = The Item Number (colon separated <em>level:custom_capabilities:fixed term</em>) that the payment was for.</li>'."\n";
753
+ echo '<li><code>%%item_name%%</code> = The Item Name (as provided by the <code>desc=""</code> attribute in your Shortcode, which briefly describes the Item Number).</li>'."\n";
754
+ echo '<li><code>%%user_ip%%</code> = The Customer\'s original IP Address, during checkout/registration via <code>$_SERVER["REMOTE_ADDR"]</code>.</li>'."\n";
755
+ echo '<li><code>%%user_id%%</code> = A unique WordPress User ID that references this account in the WordPress database.</li>'."\n";
756
+ echo '</ul>'."\n";
757
+
758
+ echo '<strong>Custom Registration/Profile Fields are also supported in this Notification:</strong>'."\n";
759
+ echo '<ul class="ws-menu-page-li-margins">'."\n";
760
+ echo '<li><code>%%date_of_birth%%</code> would be valid; if you have a Custom Registration/Profile Field with the ID <code>date_of_birth</code>.</li>'."\n";
761
+ echo '<li><code>%%street_address%%</code> would be valid; if you have a Custom Registration/Profile Field with the ID <code>street_address</code>.</li>'."\n";
762
+ echo '<li><code>%%country%%</code> would be valid; if you have a Custom Registration/Profile Field with the ID <code>country</code>.</li>'."\n";
763
+ echo '<li><em><code>%%etc, etc...%%</code> <strong>see:</strong> s2Member -› General Options -› Registration/Profile Fields</em>.</li>'."\n";
764
+ echo '</ul>'."\n";
765
+
766
+ echo '<strong>Custom Replacement Codes can also be inserted using these instructions:</strong>'."\n";
767
+ echo '<ul class="ws-menu-page-li-margins">'."\n";
768
+ echo '<li><code>%%cv0%%</code> = The domain of your site, which is passed through the `custom` attribute in your Shortcode.</li>'."\n";
769
+ echo '<li><code>%%cv1%%</code> = If you need to track additional custom variables, you can pipe delimit them into the `custom` attribute; inside your Shortcode, like this: <code>custom="'.esc_html($_SERVER["HTTP_HOST"]).'|cv1|cv2|cv3"</code>. You can have an unlimited number of custom variables. Obviously, this is for advanced webmasters; but the functionality has been made available for those who need it.</li>'."\n";
770
+ echo '</ul>'."\n";
771
+ echo '<strong>This example uses cv1 to record a special marketing campaign:</strong><br />'."\n";
772
+ echo '<em>(The campaign (i.e. christmas-promo) could be referenced using <code>%%cv1%%</code>)</em><br />'."\n";
773
+ echo '<code>custom="'.esc_html($_SERVER["HTTP_HOST"]).'|christmas-promo"</code>'."\n";
774
+
775
+ echo '</td>'."\n";
776
+
777
+ echo '</tr>'."\n";
778
+ echo '</tbody>'."\n";
779
+ echo '</table>'."\n";
780
+
781
+ echo '<div class="ws-menu-page-hr"></div>'."\n";
782
+
783
+ echo '<table class="form-table" style="margin-top:0;">'."\n";
784
+ echo '<tbody>'."\n";
785
+ echo '<tr>'."\n";
786
+
787
+ echo '<th style="padding-top:0;">'."\n";
788
+ echo '<label for="ws-plugin--s2member-ref-rev-notification-recipients">'."\n";
789
+ echo 'Send An Email Transaction Log Of This Event?'."\n";
790
+ echo '</label>'."\n";
791
+ echo '</th>'."\n";
792
+
793
+ echo '</tr>'."\n";
794
+ echo '<tr>'."\n";
795
+
796
+ echo '<td>'."\n";
797
+ echo '<input type="text" autocomplete="off" name="ws_plugin__s2member_ref_rev_notification_recipients" id="ws-plugin--s2member-ref-rev-notification-recipients" value="'.format_to_edit($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["ref_rev_notification_recipients"]).'" /><br />'."\n";
798
+ echo 'This is a semicolon ( ; ) delimited list of Recipients. Here is an example:<br />'."\n";
799
+ echo '<code>"John" &lt;john@example.com&gt;; admin@example.com; "Webmaster" &lt;webmaster@example.com&gt;</code>'."\n";
800
+ echo '</td>'."\n";
801
+
802
+ echo '</tr>'."\n";
803
+ echo '</tbody>'."\n";
804
+ echo '</table>'."\n";
805
+ echo '</div>'."\n";
806
+
807
+ echo '</div>'."\n";
808
+
809
+ do_action("ws_plugin__s2member_during_api_ops_page_during_left_sections_after_refund_reversal_notifications", get_defined_vars());
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
810
  }
811
+
812
+ if(apply_filters("ws_plugin__s2member_during_api_ops_page_during_left_sections_display_sp_sale_notifications", TRUE, get_defined_vars()))
813
+ {
814
+ do_action("ws_plugin__s2member_during_api_ops_page_during_left_sections_before_sp_sale_notifications", get_defined_vars());
815
+
816
+ echo '<div class="ws-menu-page-group" title="Specific Post/Page ~ Sale Notifications">'."\n";
817
+
818
+ echo '<div class="ws-menu-page-section ws-plugin--s2member-sp-sale-notifications-section">'."\n";
819
+ echo '<h3>Specific Post/Page ~ Sale Notification URLs (optional)</h3>'."\n";
820
+ echo '<p>If you use affiliate software, or have back-office routines that need to be notified whenever Specific Post/Page sales take place, you\'ll want to read this section. This is marked `Specific Post/Page`, because the URLs that you list below, will be notified each time a payment occurs, on a sale providing access to a Specific Post/Page.</p>'."\n";
821
+ echo '<p>This is one of only two API Notifications that are sent for Specific Post/Page Access <em>(i.e. this one, and another below, for Refunds/Reversals)</em>. All of the other API Notifications are designed for Membership Level Access'.((is_multisite() && c_ws_plugin__s2member_utils_conds::is_multisite_farm() && !is_main_site()) ? '' : ' and Independent Custom Capabilities').'. None of the other API Notifications will ever be processed for Specific Post/Page Access. If you intend to respond to events related to Specific Post/Page Access, you MUST use one of the two API Notifications specifically geared to Post/Page Access.</p>'."\n";
822
+ echo '<p>Please note, this feature is not to be confused with the PayPal IPN service. PayPal IPN <em>(and other service integrations)</em> are already built into s2Member. They remain active at all times. These Sale Notifications are an added layer of functionality, and they are completely optional.</p>'."\n";
823
+ echo '<p><strong>See also:</strong> This KB article: <a href="http://www.s2member.com/kb/building-an-api-notification-handler/" target="_blank" rel="external">Building An API Notification Handler</a>.</p>'."\n";
824
+ do_action("ws_plugin__s2member_during_api_ops_page_during_left_sections_during_sp_sale_notifications", get_defined_vars());
825
+
826
+ echo '<table class="form-table">'."\n";
827
+ echo '<tbody>'."\n";
828
+ echo '<tr>'."\n";
829
+
830
+ echo '<th>'."\n";
831
+ echo '<label for="ws-plugin--s2member-sp-sale-notification-urls">'."\n";
832
+ echo 'Specific Post/Page ~ Sale Notification URLs:'."\n";
833
+ echo '</label>'."\n";
834
+ echo '</th>'."\n";
835
+
836
+ echo '</tr>'."\n";
837
+ echo '<tr>'."\n";
838
+
839
+ echo '<td>'."\n";
840
+ echo 'You can input multiple Notification URLs by inserting one per line.<br />'."\n";
841
+ echo '<textarea name="ws_plugin__s2member_sp_sale_notification_urls" id="ws-plugin--s2member-sp-sale-notification-urls" rows="3" wrap="off">'.format_to_edit($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["sp_sale_notification_urls"]).'</textarea><br />'."\n";
842
+ echo 'Specific Post/Page ~ Sale Notifications take place silently behind-the-scene, using an HTTP connection.<br /><br />'."\n";
843
+ echo '<strong>You can also use these special Replacement Codes if you need them:</strong>'."\n";
844
+ echo '<ul class="ws-menu-page-li-margins">'."\n";
845
+ echo '<li><code>%%sp_access_url%%</code> = The full URL (generated by s2Member) where the Customer can gain access.</li>'."\n";
846
+ echo '<li><code>%%sp_access_exp%%</code> = Human readable expiration for <code>%%sp_access_url%%</code>. Ex: <em>(link expires in <code>%%sp_access_exp%%</code>)</em>.</li>'."\n";
847
+ echo '<li><code>%%txn_id%%</code> = The Paid Transaction ID. Payment Gateways assign a unique identifier for every purchase.</li>'."\n";
848
+ echo '<li><code>%%txn_cid%%</code> = Applicable only with Stripe integration. This is the Customer\'s ID in Stripe. Each Stripe Customer has this Customer ID; and also a Transaction ID associated with their purchase of the Specific Post/Page [ <a href="#" onclick="alert(\'Applicable only when you integrate s2Member with Stripe. In all other cases, the %%txn_cid%% is simply set to the %%txn_id%% value; i.e. it is a duplicate of %%txn_id%% when running anything other than Stripe.\\n\\nEach Stripe Customer has a Customer ID; and also a Transaction ID. See %%txn_id%% for further details.\'); return false;">?</a> ]</li>'."\n";
849
+ echo '<li><code>%%currency%%</code> = Three-character currency code (uppercase); e.g. <code>USD</code></li>'."\n";
850
+ echo '<li><code>%%currency_symbol%%</code> = Currency code symbol; e.g. <code>$</code></li>'."\n";
851
+ echo '<li><code>%%amount%%</code> = The full Amount of the sale. If you offer something 100% free, this will be <code>0</code>.</li>'."\n";
852
+ echo '<li><code>%%first_name%%</code> = The First Name of the Customer who purchased Specific Post/Page Access.</li>'."\n";
853
+ echo '<li><code>%%last_name%%</code> = The Last Name of the Customer who purchased Specific Post/Page Access.</li>'."\n";
854
+ echo '<li><code>%%full_name%%</code> = The Full Name (First &amp; Last) of the Customer who purchased Specific Post/Page Access.</li>'."\n";
855
+ echo '<li><code>%%payer_email%%</code> = The Email Address of the Customer who purchased Specific Post/Page Access.</li>'."\n";
856
+ echo '<li><code>%%user_ip%%</code> = The Customers\'s IP Address, during checkout via <code>$_SERVER["REMOTE_ADDR"]</code>.</li>'."\n";
857
+ echo '<li><code>%%item_number%%</code> = The Item Number. Ex: <code><em>sp:13,24,36:72</em></code> (translates to: <code><em>sp:comma-delimited IDs:expiration hours</em></code>).</li>'."\n";
858
+ echo '<li><code>%%item_name%%</code> = The Item Name (as provided by the <code>desc=""</code> attribute in your Shortcode, which briefly describes the Item Number).</li>'."\n";
859
+ echo '</ul>'."\n";
860
+
861
+ if(c_ws_plugin__s2member_utils_conds::pro_is_installed())
862
+ {
863
+ echo '<strong>Coupon Replacement Codes (applicable only w/ s2Member Pro Forms):</strong>'."\n";
864
+ echo '<ul class="ws-menu-page-li-margins">'."\n";
865
+ echo '<li><code>%%full_coupon_code%%</code> = A full Coupon Code — if one is accepted by your configuration of s2Member. This may indicate an Affiliate Coupon Code, which will include your Affiliate Suffix Chars too (i.e. the full Coupon Code).</li>'."\n";
866
+ echo '<li><code>%%coupon_code%%</code> = A Coupon Code — if one is accepted by your configuration of s2Member. This will NOT include any Affiliate Suffix Chars. This indicates the actual Coupon Code accepted by your configuration of s2Member (excluding any Affiliate ID).</li>'."\n";
867
+ echo '<li><code>%%coupon_affiliate_id%%</code> = This is the end of an Affiliate Coupon Code <em>(i.e. the referring affiliate\'s ID)</em>. This is only applicable if an Affiliate Coupon Code is accepted by your configuration of s2Member.</li>'."\n";
868
+ echo '</ul>'."\n";
869
+ }
870
+
871
+ echo '<strong>Custom Replacement Codes can also be inserted using these instructions:</strong>'."\n";
872
+ echo '<ul class="ws-menu-page-li-margins">'."\n";
873
+ echo '<li><code>%%cv0%%</code> = The domain of your site, which is passed through the `custom` attribute in your Shortcode.</li>'."\n";
874
+ echo '<li><code>%%cv1%%</code> = If you need to track additional custom variables, you can pipe delimit them into the `custom` attribute; inside your Shortcode, like this: <code>custom="'.esc_html($_SERVER["HTTP_HOST"]).'|cv1|cv2|cv3"</code>. You can have an unlimited number of custom variables. Obviously, this is for advanced webmasters; but the functionality has been made available for those who need it.</li>'."\n";
875
+ echo '</ul>'."\n";
876
+ echo '<strong>This example uses cv1 to record a special marketing campaign:</strong><br />'."\n";
877
+ echo '<em>(The campaign (i.e. christmas-promo) could be referenced using <code>%%cv1%%</code>)</em><br />'."\n";
878
+ echo '<code>custom="'.esc_html($_SERVER["HTTP_HOST"]).'|christmas-promo"</code>'."\n";
879
+
880
+ echo '</td>'."\n";
881
+
882
+ echo '</tr>'."\n";
883
+ echo '</tbody>'."\n";
884
+ echo '</table>'."\n";
885
+
886
+ echo '<div class="ws-menu-page-hr"></div>'."\n";
887
+
888
+ echo '<table class="form-table" style="margin-top:0;">'."\n";
889
+ echo '<tbody>'."\n";
890
+ echo '<tr>'."\n";
891
+
892
+ echo '<th style="padding-top:0;">'."\n";
893
+ echo '<label for="ws-plugin--s2member-sp-sale-notification-recipients">'."\n";
894
+ echo 'Send An Email Transaction Log Of This Event?'."\n";
895
+ echo '</label>'."\n";
896
+ echo '</th>'."\n";
897
+
898
+ echo '</tr>'."\n";
899
+ echo '<tr>'."\n";
900
+
901
+ echo '<td>'."\n";
902
+ echo '<input type="text" autocomplete="off" name="ws_plugin__s2member_sp_sale_notification_recipients" id="ws-plugin--s2member-sp-sale-notification-recipients" value="'.format_to_edit($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["sp_sale_notification_recipients"]).'" /><br />'."\n";
903
+ echo 'This is a semicolon ( ; ) delimited list of Recipients. Here is an example:<br />'."\n";
904
+ echo '<code>"John" &lt;john@example.com&gt;; admin@example.com; "Webmaster" &lt;webmaster@example.com&gt;</code>'."\n";
905
+ echo '</td>'."\n";
906
+
907
+ echo '</tr>'."\n";
908
+ echo '</tbody>'."\n";
909
+ echo '</table>'."\n";
910
+ echo '</div>'."\n";
911
+
912
+ echo '</div>'."\n";
913
+
914
+ do_action("ws_plugin__s2member_during_api_ops_page_during_left_sections_after_sp_sale_notifications", get_defined_vars());
915
+ }
916
+
917
+ if(apply_filters("ws_plugin__s2member_during_api_ops_page_during_left_sections_display_sp_refund_reversal_notifications", TRUE, get_defined_vars()))
918
+ {
919
+ do_action("ws_plugin__s2member_during_api_ops_page_during_left_sections_before_sp_refund_reversal_notifications", get_defined_vars());
920
+
921
+ echo '<div class="ws-menu-page-group" title="Specific Post/Page ~ Refund/Reversal Notifications">'."\n";
922
+
923
+ echo '<div class="ws-menu-page-section ws-plugin--s2member-sp-refund-reversal-notifications-section">'."\n";
924
+ echo '<h3>Specific Post/Page ~ Refund/Reversal Notification URLs (optional)</h3>'."\n";
925
+ echo '<p>If you use affiliate software, or have back-office routines that need to be notified whenever sales have been refunded or reversed <em>(i.e. charged back to you)</em>, you\'ll want to read this section. This is marked `Specific Post/Page`, because the URLs that you list below, will be notified each time a Refund or Reversal occurs, on a sale that provided access to a Specific Post/Page.</p>'."\n";
926
+ echo '<p>This is one of only two Notifications that are sent for Specific Post/Page Access <em>(i.e. this one, and another above, for Sales)</em>. All of the other API Notifications are designed for Membership Level Access'.((is_multisite() && c_ws_plugin__s2member_utils_conds::is_multisite_farm() && !is_main_site()) ? '' : ' and Independent Custom Capabilities').'. None of the other API Notifications will ever be processed for Specific Post/Page Access. If you intend to respond to events related to Specific Post/Page Access, you MUST use one of the two API Notifications specifically geared to Post/Page Access.</p>'."\n";
927
+ echo '<p>Please note, this feature is not to be confused with the PayPal IPN service. PayPal IPN <em>(and other service integrations)</em> are already built into s2Member. They remain active at all times. These Refund/Reversal Notifications are an added layer of functionality, and they are completely optional.</p>'."\n";
928
+ echo '<p><strong>See also:</strong> This KB article: <a href="http://www.s2member.com/kb/building-an-api-notification-handler/" target="_blank" rel="external">Building An API Notification Handler</a>.</p>'."\n";
929
+ do_action("ws_plugin__s2member_during_api_ops_page_during_left_sections_during_sp_refund_reversal_notifications", get_defined_vars());
930
+
931
+ echo '<table class="form-table">'."\n";
932
+ echo '<tbody>'."\n";
933
+ echo '<tr>'."\n";
934
+
935
+ echo '<th>'."\n";
936
+ echo '<label for="ws-plugin--s2member-sp-ref-rev-notification-urls">'."\n";
937
+ echo 'Specific Post/Page ~ Refund/Reversal Notification URLs:'."\n";
938
+ echo '</label>'."\n";
939
+ echo '</th>'."\n";
940
+
941
+ echo '</tr>'."\n";
942
+ echo '<tr>'."\n";
943
+
944
+ echo '<td>'."\n";
945
+ echo 'You can input multiple Notification URLs by inserting one per line.<br />'."\n";
946
+ echo '<textarea name="ws_plugin__s2member_sp_ref_rev_notification_urls" id="ws-plugin--s2member-sp-ref-rev-notification-urls" rows="3" wrap="off">'.format_to_edit($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["sp_ref_rev_notification_urls"]).'</textarea><br />'."\n";
947
+ echo 'Specific Post/Page ~ Refund/Reversal Notifications take place silently behind-the-scene, using an HTTP connection.<br /><br />'."\n";
948
+ echo '<strong>You can also use these special Replacement Codes if you need them:</strong>'."\n";
949
+ echo '<ul class="ws-menu-page-li-margins">'."\n";
950
+ echo '<li><code>%%parent_txn_id%%</code> = The Parent Transaction ID, associated with the original payment being refunded/reversed.</li>'."\n";
951
+ echo '<li><code>%%parent_txn_cid%%</code> = Applicable only with Stripe integration. This is the Customer\'s ID in Stripe. Each Stripe Customer has this Customer ID; and also a Transaction ID associated with their purchase of the Specific Post/Page [ <a href="#" onclick="alert(\'Applicable only when you integrate s2Member with Stripe. In all other cases, the %%parent_txn_cid%% is simply set to the %%parent_txn_id%% value; i.e. it is a duplicate of %%parent_txn_id%% when running anything other than Stripe.\\n\\nEach Stripe Customer has a Customer ID; and also a Transaction ID. See %%parent_txn_id%% for further details.\'); return false;">?</a> ]</li>'."\n";
952
+ echo '<li><code>%%currency%%</code> = Three-character currency code (uppercase); e.g. <code>USD</code></li>'."\n";
953
+ echo '<li><code>%%currency_symbol%%</code> = Currency code symbol; e.g. <code>$</code></li>'."\n";
954
+ echo '<li><code>%%-amount%%</code> = The Negative Amount of the payment, that was refunded or reversed back to the Customer.</li>'."\n";
955
+ echo '<li><code>%%-fee%%</code> = The Negative Payment Gateway fee, that was refunded back to you as the Merchant/Seller.</li>'."\n";
956
+ echo '<li><code>%%first_name%%</code> = The First Name of the Customer who purchased access to a Specific Post/Page.</li>'."\n";
957
+ echo '<li><code>%%last_name%%</code> = The Last Name of the Customer who purchased access to a Specific Post/Page.</li>'."\n";
958
+ echo '<li><code>%%full_name%%</code> = The Full Name (First &amp; Last) of the Customer who purchased access to a Specific Post/Page.</li>'."\n";
959
+ echo '<li><code>%%payer_email%%</code> = The Email Address of the Customer who purchased access to a Specific Post/Page.</li>'."\n";
960
+ echo '<li><code>%%user_ip%%</code> = The Customer\'s original IP Address, during checkout via <code>$_SERVER["REMOTE_ADDR"]</code>.</li>'."\n";
961
+ echo '<li><code>%%item_number%%</code> = The Item Number. Ex: <code><em>sp:13,24,36:72</em></code> (translates to: <code><em>sp:comma-delimited IDs:expiration hours</em></code>).</li>'."\n";
962
+ echo '<li><code>%%item_name%%</code> = The Item Name (as provided by the <code>desc=""</code> attribute in your Shortcode, which briefly describes the Item Number).</li>'."\n";
963
+ echo '</ul>'."\n";
964
+
965
+ echo '<strong>Custom Replacement Codes can also be inserted using these instructions:</strong>'."\n";
966
+ echo '<ul class="ws-menu-page-li-margins">'."\n";
967
+ echo '<li><code>%%cv0%%</code> = The domain of your site, which is passed through the `custom` attribute in your Shortcode.</li>'."\n";
968
+ echo '<li><code>%%cv1%%</code> = If you need to track additional custom variables, you can pipe delimit them into the `custom` attribute; inside your Shortcode, like this: <code>custom="'.esc_html($_SERVER["HTTP_HOST"]).'|cv1|cv2|cv3"</code>. You can have an unlimited number of custom variables. Obviously, this is for advanced webmasters; but the functionality has been made available for those who need it.</li>'."\n";
969
+ echo '</ul>'."\n";
970
+ echo '<strong>This example uses cv1 to record a special marketing campaign:</strong><br />'."\n";
971
+ echo '<em>(The campaign (i.e. christmas-promo) could be referenced using <code>%%cv1%%</code>)</em><br />'."\n";
972
+ echo '<code>custom="'.esc_html($_SERVER["HTTP_HOST"]).'|christmas-promo"</code>'."\n";
973
+
974
+ echo '</td>'."\n";
975
+
976
+ echo '</tr>'."\n";
977
+ echo '</tbody>'."\n";
978
+ echo '</table>'."\n";
979
+
980
+ echo '<div class="ws-menu-page-hr"></div>'."\n";
981
+
982
+ echo '<table class="form-table" style="margin-top:0;">'."\n";
983
+ echo '<tbody>'."\n";
984
+ echo '<tr>'."\n";
985
+
986
+ echo '<th style="padding-top:0;">'."\n";
987
+ echo '<label for="ws-plugin--s2member-sp-ref-rev-notification-recipients">'."\n";
988
+ echo 'Send An Email Transaction Log Of This Event?'."\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 '<input type="text" autocomplete="off" name="ws_plugin__s2member_sp_ref_rev_notification_recipients" id="ws-plugin--s2member-sp-ref-rev-notification-recipients" value="'.format_to_edit($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["sp_ref_rev_notification_recipients"]).'" /><br />'."\n";
997
+ echo 'This is a semicolon ( ; ) delimited list of Recipients. Here is an example:<br />'."\n";
998
+ echo '<code>"John" &lt;john@example.com&gt;; admin@example.com; "Webmaster" &lt;webmaster@example.com&gt;</code>'."\n";
999
+ echo '</td>'."\n";
1000
+
1001
+ echo '</tr>'."\n";
1002
+ echo '</tbody>'."\n";
1003
+ echo '</table>'."\n";
1004
+ echo '</div>'."\n";
1005
+
1006
+ echo '</div>'."\n";
1007
+
1008
+ do_action("ws_plugin__s2member_during_api_ops_page_during_left_sections_after_sp_refund_reversal_notifications", get_defined_vars());
1009
+ }
1010
+
1011
+ do_action("ws_plugin__s2member_during_api_ops_page_after_left_sections", get_defined_vars());
1012
+
1013
+ echo '<div class="ws-menu-page-hr"></div>'."\n";
1014
+
1015
+ echo '<p class="submit"><input type="submit" value="Save All Changes" /></p>'."\n";
1016
+
1017
+ echo '</form>'."\n";
1018
+
1019
+ echo '</td>'."\n";
1020
+
1021
+ echo '<td class="ws-menu-page-table-r">'."\n";
1022
+ c_ws_plugin__s2member_menu_pages_rs::display();
1023
+ echo '</td>'."\n";
1024
+
1025
+ echo '</tr>'."\n";
1026
+ echo '</tbody>'."\n";
1027
+ echo '</table>'."\n";
1028
+
1029
+ echo '</div>'."\n";
1030
+ }
1031
  }
1032
+ }
1033
 
1034
+ new c_ws_plugin__s2member_menu_page_api_ops ();
 
includes/menu-pages/down-ops.inc.php CHANGED
@@ -84,7 +84,7 @@ if(!class_exists("c_ws_plugin__s2member_menu_page_down_ops"))
84
 
85
  echo '<th style="padding-top:0;">'."\n";
86
  echo '<label for="ws-plugin--s2member-level'.$n.'-file-downloads-allowed">'."\n";
87
- echo ($n === $GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["levels"]) ? 'File Downloads ( Highest Level #'.$n.' ):'."\n" : 'File Downloads (Level #'.$n.' Or Higher):'."\n";
88
  echo '</label>'."\n";
89
  echo '</th>'."\n";
90
 
@@ -493,6 +493,97 @@ if(!class_exists("c_ws_plugin__s2member_menu_page_down_ops"))
493
 
494
  do_action("ws_plugin__s2member_during_down_ops_page_during_left_sections_after_amazon_cf", get_defined_vars());
495
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
496
  if(apply_filters("ws_plugin__s2member_during_down_ops_page_during_left_sections_display_rtmp_streaming", TRUE, get_defined_vars()))
497
  {
498
  do_action("ws_plugin__s2member_during_down_ops_page_during_left_sections_before_rtmp_streaming", get_defined_vars());
84
 
85
  echo '<th style="padding-top:0;">'."\n";
86
  echo '<label for="ws-plugin--s2member-level'.$n.'-file-downloads-allowed">'."\n";
87
+ echo ($n === $GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["levels"]) ? 'File Downloads (Highest Level #'.$n.'):'."\n" : 'File Downloads (Level #'.$n.' Or Higher):'."\n";
88
  echo '</label>'."\n";
89
  echo '</th>'."\n";
90
 
493
 
494
  do_action("ws_plugin__s2member_during_down_ops_page_during_left_sections_after_amazon_cf", get_defined_vars());
495
  }
496
+ /* if(apply_filters("ws_plugin__s2member_during_down_ops_page_during_left_sections_display_amazon_s3_comp", TRUE, get_defined_vars()))
497
+ {
498
+ do_action("ws_plugin__s2member_during_down_ops_page_during_left_sections_before_amazon_s3_comp", get_defined_vars());
499
+
500
+ echo '<div class="ws-menu-page-group" title="S3-Compatible Content Delivery (e.g. DreamObjects, etc.)">'."\n";
501
+
502
+ echo '<div class="ws-menu-page-section ws-plugin--s2member-amazon-s3-comp-section">'."\n";
503
+ echo '<h3>S3-Compatible Content Delivery (optional)</h3>'."\n";
504
+ echo '<p>[Documentation goes here.]</p>'."\n";
505
+
506
+ echo '<div class="ws-menu-page-hr"></div>'."\n";
507
+
508
+ echo '<table class="form-table" style="margin-top:0;">'."\n";
509
+ echo '<tbody>'."\n";
510
+ echo '<tr>'."\n";
511
+
512
+ echo '<th style="padding-top:0;">'."\n";
513
+ echo '<label for="ws-plugin--s2member-amazon-s3-comp-files-bucket">'."\n";
514
+ echo 'API Endpoint URL:'."\n";
515
+ echo '</label>'."\n";
516
+ echo '</th>'."\n";
517
+
518
+ echo '</tr>'."\n";
519
+ echo '<tr>'."\n";
520
+
521
+ echo '<td>'."\n";
522
+ echo '<input type="text" autocomplete="off" name="ws_plugin__s2member_amazon_s3_comp_api_endpoint" id="ws-plugin--s2member-amazon-s3-comp-api-endpoint" value="'.format_to_edit($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["amazon_s3_comp_api_endpoint"]).'" /><br />'."\n";
523
+ echo 'Please type the S3-Compatible API Endpoint URL'."\n";
524
+ echo '</td>'."\n";
525
+
526
+ echo '</tr>'."\n";
527
+ echo '<tr>'."\n";
528
+
529
+ echo '<th style="padding-top:0;">'."\n";
530
+ echo '<label for="ws-plugin--s2member-amazon-s3-comp-files-bucket">'."\n";
531
+ echo 'S3-Compatible Bucket Name (where protected files are):'."\n";
532
+ echo '</label>'."\n";
533
+ echo '</th>'."\n";
534
+
535
+ echo '</tr>'."\n";
536
+ echo '<tr>'."\n";
537
+
538
+ echo '<td>'."\n";
539
+ echo '<input type="text" autocomplete="off" name="ws_plugin__s2member_amazon_s3_comp_files_bucket" id="ws-plugin--s2member-amazon-s3-comp-files-bucket" value="'.format_to_edit($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["amazon_s3_comp_files_bucket"]).'" /><br />'."\n";
540
+ echo 'Your S3-Compatible Bucket will be used, instead of the <code>/'.esc_html(c_ws_plugin__s2member_utils_dirs::basename_dir_app_data($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["files_dir"])).'/</code> directory.<br />'."\n";
541
+ echo 'Please type the name of your Bucket. Ex: <code>mys3compbucket</code>'."\n";
542
+ echo '</td>'."\n";
543
+
544
+ echo '</tr>'."\n";
545
+ echo '<tr>'."\n";
546
+
547
+ echo '<th>'."\n";
548
+ echo '<label for="ws-plugin--s2member-amazon-s3-comp-files-access-key">'."\n";
549
+ echo 'Access Key (Access Key ID):'."\n";
550
+ echo '</label>'."\n";
551
+ echo '</th>'."\n";
552
+
553
+ echo '</tr>'."\n";
554
+ echo '<tr>'."\n";
555
+
556
+ echo '<td>'."\n";
557
+ echo '<input type="password" autocomplete="off" name="ws_plugin__s2member_amazon_s3_comp_files_access_key" id="ws-plugin--s2member-amazon-s3-comp-files-access-key" value="'.format_to_edit($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["amazon_s3_comp_files_access_key"]).'" /><br />'."\n";
558
+ echo 'Please type the Access Key.'."\n";
559
+ echo '</td>'."\n";
560
+
561
+ echo '</tr>'."\n";
562
+ echo '<tr>'."\n";
563
+
564
+ echo '<th>'."\n";
565
+ echo '<label for="ws-plugin--s2member-amazon-s3-comp-files-secret-key">'."\n";
566
+ echo 'Secret Key (Secret Access Key):'."\n";
567
+ echo '</label>'."\n";
568
+ echo '</th>'."\n";
569
+
570
+ echo '</tr>'."\n";
571
+ echo '<tr>'."\n";
572
+
573
+ echo '<td>'."\n";
574
+ echo '<input type="password" autocomplete="off" name="ws_plugin__s2member_amazon_s3_comp_files_secret_key" id="ws-plugin--s2member-amazon-s3-comp-files-secret-key" value="'.format_to_edit($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["amazon_s3_comp_files_secret_key"]).'" /><br />'."\n";
575
+ echo 'Please type the Secret Key.'."\n";
576
+ echo '</td>'."\n";
577
+
578
+ echo '</tr>'."\n";
579
+ echo '</tbody>'."\n";
580
+ echo '</table>'."\n";
581
+ echo '</div>'."\n";
582
+
583
+ echo '</div>'."\n";
584
+
585
+ do_action("ws_plugin__s2member_during_down_ops_page_during_left_sections_after_amazon_s3_comp", get_defined_vars());
586
+ }*/
587
  if(apply_filters("ws_plugin__s2member_during_down_ops_page_during_left_sections_display_rtmp_streaming", TRUE, get_defined_vars()))
588
  {
589
  do_action("ws_plugin__s2member_during_down_ops_page_during_left_sections_before_rtmp_streaming", get_defined_vars());
includes/menu-pages/els-ops.inc.php CHANGED
@@ -234,7 +234,7 @@ if(!class_exists("c_ws_plugin__s2member_menu_page_els_ops"))
234
  echo '<option value="api"'.(($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["aweber_api_type"] === "api") ? ' selected="selected"' : '').'>API (recommended for a more robust integration)</option>'."\n";
235
  echo '<option value="email"'.(($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["aweber_api_type"] === "email") ? ' selected="selected"' : '').'>Email (less reliable; requires an Email Parser)</option>'."\n";
236
  echo '</select><br />'."\n";
237
- echo 'Starting w/ s2Member™ v141005+, you can now integrate with AWeber\'s API (recommended) instead of through an Email Parser.'."\n";
238
  echo '</td>'."\n";
239
 
240
  echo '</tr>'."\n";
234
  echo '<option value="api"'.(($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["aweber_api_type"] === "api") ? ' selected="selected"' : '').'>API (recommended for a more robust integration)</option>'."\n";
235
  echo '<option value="email"'.(($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["aweber_api_type"] === "email") ? ' selected="selected"' : '').'>Email (less reliable; requires an Email Parser)</option>'."\n";
236
  echo '</select><br />'."\n";
237
+ echo 'Starting w/ s2Member™ v141007+, you can now integrate with AWeber\'s API (recommended) instead of through an Email Parser.'."\n";
238
  echo '</td>'."\n";
239
 
240
  echo '</tr>'."\n";
includes/menu-pages/paypal-ops.inc.php CHANGED
@@ -1,1078 +1,1103 @@
1
  <?php
2
  /**
3
- * Menu page for the s2Member plugin (PayPal Options page).
4
- *
5
- * Copyright: © 2009-2011
6
- * {@link http://www.websharks-inc.com/ WebSharks, Inc.}
7
- * (coded in the USA)
8
- *
9
- * Released under the terms of the GNU General Public License.
10
- * You should have received a copy of the GNU General Public License,
11
- * along with this software. In the main directory, see: /licensing/
12
- * If not, see: {@link http://www.gnu.org/licenses/}.
13
- *
14
- * @package s2Member\Menu_Pages
15
- * @since 3.0
16
- */
17
  if(realpath(__FILE__) === realpath($_SERVER["SCRIPT_FILENAME"]))
18
  exit("Do not access this file directly.");
19
 
20
  if(!class_exists("c_ws_plugin__s2member_menu_page_paypal_ops"))
 
 
 
 
 
 
 
 
21
  {
22
- /**
23
- * Menu page for the s2Member plugin (PayPal Options page).
24
- *
25
- * @package s2Member\Menu_Pages
26
- * @since 110531
27
- */
28
- class c_ws_plugin__s2member_menu_page_paypal_ops
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
29
  {
30
- public function __construct()
31
- {
32
- echo '<div class="wrap ws-menu-page">'."\n";
33
-
34
- echo '<div class="ws-menu-page-toolbox">'."\n";
35
- c_ws_plugin__s2member_menu_pages_tb::display ();
36
- echo '</div>'."\n";
37
-
38
- echo '<h2>PayPal Options</h2>'."\n";
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
39
 
40
- echo '<table class="ws-menu-page-table">'."\n";
41
- echo '<tbody class="ws-menu-page-table-tbody">'."\n";
42
- echo '<tr class="ws-menu-page-table-tr">'."\n";
43
- echo '<td class="ws-menu-page-table-l">'."\n";
 
 
 
 
 
 
 
44
 
45
- echo '<form method="post" name="ws_plugin__s2member_options_form" id="ws-plugin--s2member-options-form">'."\n";
46
- 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";
47
- echo '<input type="hidden" name="ws_plugin__s2member_configured" id="ws-plugin--s2member-configured" value="1" />'."\n";
 
 
 
 
48
 
49
- do_action("ws_plugin__s2member_during_paypal_ops_page_before_left_sections", get_defined_vars());
50
-
51
- if(apply_filters("ws_plugin__s2member_during_paypal_ops_page_during_left_sections_display_paypal_account_details", true, get_defined_vars()))
52
- {
53
- do_action("ws_plugin__s2member_during_paypal_ops_page_during_left_sections_before_paypal_account_details", get_defined_vars());
54
-
55
- echo '<div class="ws-menu-page-group" title="PayPal Account Details">'."\n";
 
56
 
57
- echo '<div class="ws-menu-page-section ws-plugin--s2member-paypal-account-details-section">'."\n";
58
- echo '<a href="http://www.s2member.com/paypal" target="_blank"><img src="'.esc_attr($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["dir_url"]).'/images/paypal-logo.png" class="ws-menu-page-right" style="width:125px; height:125px; border:0;" alt="." /></a>'."\n";
59
- echo '<h3>PayPal Account Details (required, if using PayPal)</h3>'."\n";
60
- echo '<p>This plugin works in conjunction with <a href="http://www.s2member.com/paypal" target="_blank" rel="external">PayPal Website Payments Standard</a>, for businesses. You do NOT need a PayPal Pro account. You just need to upgrade your Personal PayPal account to a Business status, which is free. A PayPal account can be <a href="http://pages.ebay.com/help/buy/questions/upgrade-paypal-account.html" target="_blank" rel="external">upgraded</a> from a Personal account to a Business account, simply by going to the `Profile` button under the `My Account` tab, selecting the `Personal Business Information` button, and then clicking the `Upgrade Your Account` button. <strong>See also:</strong> This KB article: <a href="http://www.s2member.com/kb/paypal-account-types/" target="_blank" rel="external">PayPal Compatibility (Account Types)</a>.</p>'."\n";
61
- echo '<p><em><strong>*PayPal API Credentials*</strong> Once you have a PayPal Business account, you\'ll need access to your <a href="http://www.s2member.com/paypal-profile-api-access" target="_blank" rel="external">PayPal API Credentials</a>. Log into your PayPal account, and navigate to <code>Profile -› API Access (or Request API Credentials)</code>. You\'ll choose <code>(PayPal / Request API Signature)</code>.</em></p>'."\n";
62
- do_action("ws_plugin__s2member_during_paypal_ops_page_during_left_sections_during_paypal_account_details", get_defined_vars());
63
 
64
- echo '<table class="form-table">'."\n";
65
- echo '<tbody>'."\n";
66
- echo '<tr>'."\n";
 
67
 
68
- echo '<th>'."\n";
69
- echo '<label for="ws-plugin--s2member-paypal-merchant-id">'."\n";
70
- echo 'Your PayPal Merchant ID:'."\n";
71
- echo '</label>'."\n";
72
- echo '</th>'."\n";
73
-
74
- echo '</tr>'."\n";
75
- echo '<tr>'."\n";
76
 
77
- echo '<td>'."\n";
78
- echo '<input type="text" autocomplete="off" name="ws_plugin__s2member_paypal_merchant_id" id="ws-plugin--s2member-paypal-merchant-id" value="'.format_to_edit($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["paypal_merchant_id"]).'" /><br />'."\n";
79
- echo 'At PayPal, see: <code>Profile -› Secure Merchant ID</code>.'."\n";
80
- echo '</td>'."\n";
81
-
82
- echo '</tr>'."\n";
83
- echo '<tr>'."\n";
 
 
84
 
85
- echo '<th>'."\n";
86
- echo '<label for="ws-plugin--s2member-paypal-business">'."\n";
87
- echo 'Your PayPal EMail Address:'."\n";
88
- echo '</label>'."\n";
89
- echo '</th>'."\n";
90
-
91
- echo '</tr>'."\n";
92
- echo '<tr>'."\n";
93
-
94
- echo '<td>'."\n";
95
- echo '<input type="text" autocomplete="off" name="ws_plugin__s2member_paypal_business" id="ws-plugin--s2member-paypal-business" value="'.format_to_edit($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["paypal_business"]).'" /><br />'."\n";
96
- echo 'At PayPal, see: <code>Profile -› Email Accounts</code>.'."\n";
97
- echo '</td>'."\n";
98
-
99
- echo '</tr>'."\n";
100
- echo '</tbody>'."\n";
101
- echo '</table>'."\n";
102
 
103
- echo '<div class="ws-menu-page-hr"></div>'."\n";
 
 
 
 
104
 
105
- echo '<table class="form-table">'."\n";
106
- echo '<tbody>'."\n";
107
- echo '<tr>'."\n";
108
 
109
- echo '<th>'."\n";
110
- echo '<label for="ws-plugin--s2member-paypal-api-username">'."\n";
111
- echo 'Your PayPal API Username:'."\n";
112
- echo '</label>'."\n";
113
- echo '</th>'."\n";
 
114
 
115
- echo '</tr>'."\n";
116
- echo '<tr>'."\n";
117
-
118
- echo '<td>'."\n";
119
- echo '<input type="text" autocomplete="off" name="ws_plugin__s2member_paypal_api_username" id="ws-plugin--s2member-paypal-api-username" value="'.format_to_edit($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["paypal_api_username"]).'" /><br />'."\n";
120
- echo 'At PayPal, see: <code>Profile -› API Access (or Request API Credentials)</code>.'."\n";
121
- echo '</td>'."\n";
122
-
123
- echo '</tr>'."\n";
124
- echo '<tr>'."\n";
125
-
126
- echo '<th>'."\n";
127
- echo '<label for="ws-plugin--s2member-paypal-api-password">'."\n";
128
- echo 'Your PayPal API Password:'."\n";
129
- echo '</label>'."\n";
130
- echo '</th>'."\n";
131
-
132
- echo '</tr>'."\n";
133
- echo '<tr>'."\n";
134
-
135
- echo '<td>'."\n";
136
- echo '<input type="password" autocomplete="off" name="ws_plugin__s2member_paypal_api_password" id="ws-plugin--s2member-paypal-api-password" value="'.format_to_edit($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["paypal_api_password"]).'" /><br />'."\n";
137
- echo 'At PayPal, see: <code>Profile -› API Access (or Request API Credentials)</code>.'."\n";
138
- echo '</td>'."\n";
139
-
140
- echo '</tr>'."\n";
141
- echo '<tr>'."\n";
142
-
143
- echo '<th>'."\n";
144
- echo '<label for="ws-plugin--s2member-paypal-api-signature">'."\n";
145
- echo 'Your PayPal API Signature:'."\n";
146
- echo '</label>'."\n";
147
- echo '</th>'."\n";
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
148
 
149
- echo '</tr>'."\n";
150
- echo '<tr>'."\n";
151
-
152
- echo '<td>'."\n";
153
- echo '<input type="password" autocomplete="off" name="ws_plugin__s2member_paypal_api_signature" id="ws-plugin--s2member-paypal-api-signature" value="'.format_to_edit($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["paypal_api_signature"]).'" /><br />'."\n";
154
- echo 'At PayPal, see: <code>Profile -› API Access (or Request API Credentials)</code>.'."\n";
155
- echo '</td>'."\n";
156
-
157
- echo '</tr>'."\n";
158
- do_action("ws_plugin__s2member_during_paypal_ops_page_during_left_sections_during_paypal_account_detail_rows", get_defined_vars());
159
-
160
- echo '</tbody>'."\n";
161
- echo '</table>'."\n";
162
-
163
- echo '<div class="ws-menu-page-hr"></div>'."\n";
164
-
165
- echo '<table class="form-table" style="margin:0;">'."\n";
166
- echo '<tbody>'."\n";
167
- echo '<tr>'."\n";
168
-
169
- echo '<th style="padding-top:0;">'."\n";
170
- echo '<label for="ws-plugin--s2member-paypal-sandbox">'."\n";
171
- echo 'Developer/Sandbox Testing?'."\n";
172
- echo '</label>'."\n";
173
- echo '</th>'."\n";
174
-
175
- echo '</tr>'."\n";
176
- echo '<tr>'."\n";
177
-
178
- echo '<td>'."\n";
179
- 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";
180
- echo '<em>Only enable this if you\'ve provided Sandbox credentials above.<br />This puts the API, IPN, PDT and Form/Button Generators all into Sandbox mode.<br />See: <a href="http://www.s2member.com/paypal-developers" target="_blank" rel="external">PayPal Developers</a></em>'."\n";
181
- echo '</td>'."\n";
182
-
183
- echo '</tr>'."\n";
184
- echo '<tr>'."\n";
185
-
186
- echo '<th>'."\n";
187
- echo '<label for="ws-plugin--s2member-paypal-btn-encryption">'."\n";
188
- echo 'Enable Button Encryption?'."\n";
189
- echo '</label>'."\n";
190
- echo '</th>'."\n";
191
-
192
- echo '</tr>'."\n";
193
- echo '<tr>'."\n";
194
-
195
- echo '<td>'."\n";
196
- echo '<input type="radio" name="ws_plugin__s2member_paypal_btn_encryption" id="ws-plugin--s2member-paypal-btn-encryption-0" value="0"'.((!$GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["paypal_btn_encryption"]) ? ' checked="checked"' : '').' /> <label for="ws-plugin--s2member-paypal-btn-encryption-0">No</label> &nbsp;&nbsp;&nbsp; <input type="radio" name="ws_plugin__s2member_paypal_btn_encryption" id="ws-plugin--s2member-paypal-btn-encryption-1" value="1"'.(($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["paypal_btn_encryption"]) ? ' checked="checked"' : '').' /> <label for="ws-plugin--s2member-paypal-btn-encryption-1">Yes, enable PayPal Button encryption.</label><br />'."\n";
197
- echo '<em>If enabled, all of your PayPal Button Shortcodes will produce *encrypted* PayPal Buttons. This improves security against fraudulent transactions. For extra security, you should update your PayPal account too, under: <code>My Profile -› Website Payment Preferences</code>. You\'ll want to block all non-encrypted payments. <strong>*Note*</strong> this will NOT work until you\'ve supplied s2Member with your PayPal Email Address, and also with your API Username/Password/Signature.</em>'."\n";
198
- echo '</td>'."\n";
199
-
200
- echo '</tr>'."\n";
201
-
202
- if(!is_multisite() || !c_ws_plugin__s2member_utils_conds::is_multisite_farm() || is_main_site())
203
- {
204
- echo '<tr>'."\n";
205
-
206
- echo '<th>'."\n";
207
- echo '<label for="ws-plugin--s2member-gateway-debug-logs">'."\n";
208
- echo 'Enable Logging Routines?'."\n";
209
- echo '</label>'."\n";
210
- echo '</th>'."\n";
211
-
212
- echo '</tr>'."\n";
213
- echo '<tr>'."\n";
214
-
215
- echo '<td>'."\n";
216
- echo '<input type="radio" name="ws_plugin__s2member_gateway_debug_logs" id="ws-plugin--s2member-gateway-debug-logs-0" value="0"'.((!$GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["gateway_debug_logs"]) ? ' checked="checked"' : '').' /> <label for="ws-plugin--s2member-gateway-debug-logs-0">No</label> &nbsp;&nbsp;&nbsp; <input type="radio" name="ws_plugin__s2member_gateway_debug_logs" id="ws-plugin--s2member-gateway-debug-logs-1" value="1"'.(($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["gateway_debug_logs"]) ? ' checked="checked"' : '').' /> <label for="ws-plugin--s2member-gateway-debug-logs-1">Yes, enable debugging, with API, IPN &amp; Return Page logging.</label><br />'."\n";
217
- echo '<em>This enables API, IPN and Return Page logging. The log files are stored here: <code>'.esc_html(c_ws_plugin__s2member_utils_dirs::doc_root_path($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["logs_dir"])).'</code></em><br />'."\n";
218
- echo '<em class="ws-menu-page-hilite">If you have any trouble, please review your s2Member log files for problems. See: <a href="'.esc_attr(admin_url("/admin.php?page=ws-plugin--s2member-logs")).'">Log Viewer</a></em>'."\n";
219
- echo '</td>'."\n";
220
-
221
- echo '</tr>'."\n";
222
- echo '<tr>'."\n";
223
-
224
- echo '<td>'."\n";
225
- echo '<div class="info" style="margin-bottom:0;">'."\n";
226
- echo '<p style="font-size:110%; margin-top:0;"><span>We HIGHLY recommend that you enable logging during your initial testing phase. Logs produce lots of useful details that can help in debugging. Logs can help you find issues in your configuration and/or problems during payment processing. See: <a href="'.esc_attr(admin_url("/admin.php?page=ws-plugin--s2member-logs")).'">Log Files (Debug)</a>.</span></p>'."\n";
227
- echo '<p style="font-size:110%; margin-bottom:0;"><span class="ws-menu-page-error">However, it is VERY IMPORTANT to disable logging once you go live. Log files may contain personally identifiable information, credit card numbers, secret API credentials, passwords and/or other sensitive information. We STRONGLY suggest that logging be disabled on a live site (for security reasons).</span></p>'."\n";
228
- echo '</div>'."\n";
229
- echo '</td>'."\n";
230
-
231
- echo '</tr>'."\n";
232
- }
233
- echo '</tbody>'."\n";
234
- echo '</table>'."\n";
235
-
236
- echo '<div class="ws-menu-page-hr"></div>'."\n";
237
-
238
- echo '<p><em><strong>*Sandbox Tip*</strong> If you\'re testing your site through a PayPal Sandbox account, please remember that Email Confirmations from s2Member will NOT be received after a test purchase. s2Member sends its Confirmation Emails to the PayPal Email Address of the Customer. Since PayPal Sandbox addresses are usually bogus (for testing), you will have to run live transactions before Email Confirmations from s2Member are received. That being said, all other s2Member functionality CAN be tested through a PayPal Sandbox account. Email Confirmations are the only hang-up.</em></p>'."\n";
239
- do_action("ws_plugin__s2member_during_paypal_ops_page_during_left_sections_during_paypal_account_details_after_sandbox_tip", get_defined_vars());
240
- echo '</div>'."\n";
241
-
242
- echo '</div>'."\n";
243
-
244
- do_action("ws_plugin__s2member_during_paypal_ops_page_during_left_sections_after_paypal_account_details", get_defined_vars());
245
- }
246
-
247
- if(apply_filters("ws_plugin__s2member_during_paypal_ops_page_during_left_sections_display_paypal_payflow_account_details", c_ws_plugin__s2member_utils_conds::pro_is_installed(), get_defined_vars()))
248
- {
249
- do_action("ws_plugin__s2member_during_paypal_ops_page_during_left_sections_before_paypal_payflow_account_details", get_defined_vars());
250
-
251
- echo '<div class="ws-menu-page-group" title="Payflow Account Details">'."\n";
252
-
253
- echo '<div class="ws-menu-page-section ws-plugin--s2member-paypal-payflow-account-details-section">'."\n";
254
- echo '<a href="http://www.s2member.com/paypal" target="_blank"><img src="'.esc_attr($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["dir_url"]).'/images/paypal-logo.png" class="ws-menu-page-right" style="width:125px; height:125px; border:0;" alt="." /></a>'."\n";
255
- echo '<h3>Payflow Account Details (required, if using Payflow)</h3>'."\n";
256
- echo '<p>Newer PayPal Pro accounts come with the Payflow API for Recurring Billing service. If you have a newer PayPal Pro account, and you wish to integrate PayPal\'s Recurring Billing service with s2Member Pro Forms, you will need to fill in the details here. Providing Payflow API Credentials here, automatically puts s2Member\'s Recurring Billing integration through Pro Forms, into Payflow mode. Just fill in the details below, and you\'re ready to generate Pro Forms that charge customers on a recurring basis. s2Member will use the Payflow API instead of the standard PayPal Pro API, which is being slowly phased out in favor of Payflow.</p>'."\n";
257
- echo '<p><em><strong>*Payflow API Credentials*</strong> Once you have a PayPal Pro account, you\'ll need access to your <a href="http://www.s2member.com/paypal-profile-api-access" target="_blank" rel="external">Payflow API Credentials</a>. Log into your PayPal account, and navigate to <code>Profile -› API Access (or Request API Credentials)</code>. You\'ll choose <code>(Payflow / API Access)</code>.</em></p>'."\n";
258
- echo '<p><em><strong>*Important Note*</strong> s2Member always uses the PayPal Pro API. It can also use the Payflow API (if details are supplied here). But please note... supplying Payflow API Credentials here, does NOT mean you can bypass other sections. Please supply s2Member with ALL of your PayPal account details.</em></p>'."\n";
259
- echo '<p><strong>See also:</strong> This KB article: <a href="http://www.s2member.com/kb/paypal-pro-payflow-edition/" target="_blank" rel="external">PayPal Pro (PayFlow Edition)</a>.</p>'."\n";
260
- do_action("ws_plugin__s2member_during_paypal_ops_page_during_left_sections_during_paypal_payflow_account_details", get_defined_vars());
261
-
262
- echo '<table class="form-table">'."\n";
263
- echo '<tbody>'."\n";
264
- echo '<tr>'."\n";
265
-
266
- echo '<th>'."\n";
267
- echo '<label for="ws-plugin--s2member-paypal-payflow-api-username">'."\n";
268
- echo 'Your Payflow API Username:'."\n";
269
- echo '</label>'."\n";
270
- echo '</th>'."\n";
271
-
272
- echo '</tr>'."\n";
273
- echo '<tr>'."\n";
274
-
275
- echo '<td>'."\n";
276
- echo '<input type="text" autocomplete="off" name="ws_plugin__s2member_paypal_payflow_api_username" id="ws-plugin--s2member-paypal-payflow-api-username" value="'.format_to_edit($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["paypal_payflow_api_username"]).'" /><br />'."\n";
277
- echo 'At PayPal, see: <code>Profile -› API Access (or Request API Credentials) -› Payflow API Access</code>.'."\n";
278
- echo '</td>'."\n";
279
-
280
- echo '</tr>'."\n";
281
- echo '<tr>'."\n";
282
-
283
- echo '<th>'."\n";
284
- echo '<label for="ws-plugin--s2member-paypal-payflow-api-password">'."\n";
285
- echo 'Your Payflow API Password:'."\n";
286
- echo '</label>'."\n";
287
- echo '</th>'."\n";
288
-
289
- echo '</tr>'."\n";
290
- echo '<tr>'."\n";
291
-
292
- echo '<td>'."\n";
293
- echo '<input type="password" autocomplete="off" name="ws_plugin__s2member_paypal_payflow_api_password" id="ws-plugin--s2member-paypal-payflow-api-password" value="'.format_to_edit($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["paypal_payflow_api_password"]).'" /><br />'."\n";
294
- echo 'At PayPal, see: <code>Profile -› API Access (or Request API Credentials) -› Payflow API Access</code>.'."\n";
295
- echo '</td>'."\n";
296
-
297
- echo '</tr>'."\n";
298
- echo '<tr>'."\n";
299
-
300
- echo '<th>'."\n";
301
- echo '<label for="ws-plugin--s2member-paypal-payflow-api-partner">'."\n";
302
- echo 'Your Payflow API Partner:'."\n";
303
- echo '</label>'."\n";
304
- echo '</th>'."\n";
305
-
306
- echo '</tr>'."\n";
307
- echo '<tr>'."\n";
308
-
309
- echo '<td>'."\n";
310
- echo '<input type="text" name="ws_plugin__s2member_paypal_payflow_api_partner" id="ws-plugin--s2member-paypal-payflow-api-partner" value="'.format_to_edit($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["paypal_payflow_api_partner"]).'" /><br />'."\n";
311
- echo 'At PayPal, see: <code>Profile -› API Access (or Request API Credentials) -› Payflow API Access</code>.'."\n";
312
- echo '</td>'."\n";
313
-
314
- echo '</tr>'."\n";
315
- echo '<tr>'."\n";
316
-
317
- echo '<th>'."\n";
318
- echo '<label for="ws-plugin--s2member-paypal-payflow-api-vendor">'."\n";
319
- echo 'Your Payflow API Vendor:'."\n";
320
- echo '</label>'."\n";
321
- echo '</th>'."\n";
322
-
323
- echo '</tr>'."\n";
324
- echo '<tr>'."\n";
325
-
326
- echo '<td>'."\n";
327
- echo '<input type="text" name="ws_plugin__s2member_paypal_payflow_api_vendor" id="ws-plugin--s2member-paypal-payflow-api-vendor" value="'.format_to_edit($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["paypal_payflow_api_vendor"]).'" /><br />'."\n";
328
- echo 'At PayPal, see: <code>Profile -› API Access (or Request API Credentials) -› Payflow API Access</code>.'."\n";
329
- echo '</td>'."\n";
330
 
331
- echo '</tr>'."\n";
332
- do_action("ws_plugin__s2member_during_paypal_ops_page_during_left_sections_during_paypal_payflow_account_detail_rows", get_defined_vars());
333
- echo '</tbody>'."\n";
334
- echo '</table>'."\n";
335
- echo '</div>'."\n";
336
 
337
- echo '</div>'."\n";
338
-
339
- do_action("ws_plugin__s2member_during_paypal_ops_page_during_left_sections_after_paypal_payflow_account_details", get_defined_vars());
340
- }
 
 
 
341
 
342
- if(apply_filters("ws_plugin__s2member_during_paypal_ops_page_during_left_sections_display_paypal_ipn", true, get_defined_vars()))
343
- {
344
- do_action("ws_plugin__s2member_during_paypal_ops_page_during_left_sections_before_paypal_ipn", get_defined_vars());
345
-
346
- echo '<div class="ws-menu-page-group" title="PayPal IPN Integration">'."\n";
347
-
348
- echo '<div class="ws-menu-page-section ws-plugin--s2member-paypal-ipn-section">'."\n";
349
- echo '<h3>PayPal IPN / Instant Payment Notifications (required, please enable)</h3>'."\n";
350
- echo '<p>Log into your PayPal account and navigate to this section:<br /><code>Account Profile -› Instant Payment Notification Preferences</code></p>'."\n";
351
- echo '<p>Edit your IPN settings &amp; turn IPN Notifications: <strong><code>On</code></strong></p>'."\n";
352
- echo '<p>You\'ll need your IPN URL, which is:<br /><code>'.esc_html(home_url("/?s2member_paypal_notify=1")).'</code></p>'."\n";
353
- do_action("ws_plugin__s2member_during_paypal_ops_page_during_left_sections_during_paypal_ipn", get_defined_vars());
354
-
355
- echo '<h3 style="margin:0;">More Information (<a href="#" onclick="jQuery(\'div#ws-plugin--s2member-paypal-ipn-details\').toggle(); return false;" class="ws-dotted-link">click here</a>)</h3>'."\n";
356
- echo '<div id="ws-plugin--s2member-paypal-ipn-details" style="display:none;">'."\n";
357
- echo '<p><em><strong>*Quick Tip*</strong> In addition to the <a href="http://www.s2member.com/paypal-ipn-setup" target="_blank" rel="external">default IPN settings inside your PayPal account</a>, the IPN URL is also set on a per-transaction basis by the special PayPal Button Code that s2Member provides you with. In other words, if you have multiple sites operating on one PayPal account, that\'s OK. s2Member dynamically sets the IPN URL for each transaction. The result is that the IPN URL configured from within your PayPal account, becomes the default, which is then overwritten on a per-transaction basis. In fact, PayPal recently updated their system to support IPN URL preservation. One PayPal account can handle multiple sites, all using different IPN URLs.</em></p>'."\n";
358
- do_action("ws_plugin__s2member_during_paypal_ops_page_during_left_sections_during_paypal_ipn_after_quick_tip", get_defined_vars());
359
- echo '<p><em><strong>*IPN Communications*</strong> You\'ll be happy to know that s2Member handles cancellations, expirations, failed payments, terminations (e.g. refunds &amp; chargebacks) for you automatically. If you log into your PayPal account and cancel a Member\'s Subscription, or, if the Member logs into their PayPal account and cancels their own Subscription, s2Member will be notified of these important changes and react accordingly through the PayPal IPN service that runs silently behind-the-scene. The PayPal IPN service will notify s2Member whenever a Member\'s payments have been failing, and/or whenever a Member\'s Subscription has expired for any reason. Even refunds &amp; chargeback reversals are supported through the IPN service. If you issue a refund to an unhappy Customer through PayPal, s2Member will be notified, and the account for that Customer will either be demoted to a Free Subscriber, or deleted automatically (based on your configuration). The communication from PayPal -› s2Member is seamless.</em></p>'."\n";
360
- echo '</div>'."\n";
361
-
362
- echo '<div class="ws-menu-page-hr"></div>'."\n";
363
-
364
- echo '<h3 style="margin:0;">IPN w/ Proxy Key (<a href="#" onclick="jQuery(\'div#ws-plugin--s2member-paypal-ipn-proxy-details\').toggle(); return false;" class="ws-dotted-link">optional, for 3rd-party integrations</a>)</h3>'."\n";
365
- echo '<div id="ws-plugin--s2member-paypal-ipn-proxy-details" style="display:none;">'."\n";
366
- echo '<p>If you\'re using a 3rd-party application that needs to POST simulated IPN transactions to your s2Member installation, you can use this alternate IPN URL, which includes a Proxy Key. This encrypted Proxy Key verifies incoming data being received by s2Member\'s IPN processor. You can change <em>[proxy-gateway]</em> to whatever you like. The <em>[proxy-gateway]</em> value is required. It will be stored by s2Member as the Customer\'s Paid Subscr. Gateway. Your [proxy-gateway] value will also be reflected in s2Member\'s IPN log.</p>'."\n";
367
- echo '<input type="text" autocomplete="off" value="'.format_to_edit(home_url("/?s2member_paypal_notify=1&s2member_paypal_proxy=[proxy-gateway]&s2member_paypal_proxy_verification=".urlencode(c_ws_plugin__s2member_paypal_utilities::paypal_proxy_key_gen()))).'" style="width:99%;" />'."\n";
368
- echo '<p><em>Any 3rd-party application that is sending IPN transactions to your s2Member installation, must ALWAYS include the <code>custom</code> POST variable, and that variable must always start with your installation domain (i.e. custom=<code>'.esc_html($_SERVER["HTTP_HOST"]).'</code>). In addition, the <code>item_number</code> variable, must always match a format that s2Member looks for. Generally speaking, the <code>item_number</code> should be <code>1, 2, 3, or 4</code>, indicating a specific s2Member Level #. However, s2Member also uses some advanced formats in this field. Just to be sure, we suggest creating a PayPal Button with the s2Member Button Generator, and then taking a look at the Full Button Code to see how s2Member expects <code>item_number</code> to be formatted. Other than the aforementioned exceptions; all other POST variables should follow PayPal standards. Please see: <a href="http://www.s2member.com/paypal-ipn-pdt-vars" target="_blank" rel="external">PayPal\'s IPN/PDT reference guide</a> for full documentation.</em></p>'."\n";
369
- do_action("ws_plugin__s2member_during_paypal_ops_page_during_left_sections_during_paypal_ipn_after_proxy", get_defined_vars());
370
- echo '</div>'."\n";
371
- echo '</div>'."\n";
372
-
373
- echo '</div>'."\n";
374
-
375
- do_action("ws_plugin__s2member_during_paypal_ops_page_during_left_sections_after_paypal_ipn", get_defined_vars());
376
- }
377
-
378
- if(apply_filters("ws_plugin__s2member_during_paypal_ops_page_during_left_sections_display_paypal_pdt", true, get_defined_vars()))
379
- {
380
- do_action("ws_plugin__s2member_during_paypal_ops_page_during_left_sections_before_paypal_pdt", get_defined_vars());
381
-
382
- echo '<div class="ws-menu-page-group" title="PayPal PDT/Auto-Return Integration">'."\n";
383
-
384
- echo '<div class="ws-menu-page-section ws-plugin--s2member-paypal-pdt-section">'."\n";
385
- echo '<h3>PayPal PDT Identity Token (required, please enable)</h3>'."\n";
386
- echo '<p>Log into your PayPal account and navigate to this section:<br /><code>Account Profile -› Website Payment Preferences</code></p>'."\n";
387
- echo '<p>Turn the Auto-Return feature: <strong><code>On</code></strong></p>'."\n";
388
- echo '<p>You\'ll need your <a href="'.esc_attr(home_url("/?s2member_paypal_return=1&s2member_paypal_proxy=paypal&s2member_paypal_proxy_use=x-preview")).'" target="_blank" rel="external">Auto-Return URL</a>, which is:<br /><code>'.esc_html(home_url("/?s2member_paypal_return=1")).'</code></p>'."\n";
389
- 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";
390
- do_action("ws_plugin__s2member_during_paypal_ops_page_during_left_sections_during_paypal_pdt", get_defined_vars());
391
-
392
- echo '<table class="form-table">'."\n";
393
- echo '<tbody>'."\n";
394
- echo '<tr>'."\n";
395
-
396
- echo '<th>'."\n";
397
- echo '<label for="ws-plugin--s2member-paypal-identity-token">'."\n";
398
- echo 'PayPal PDT Identity Token:'."\n";
399
- echo '</label>'."\n";
400
- echo '</th>'."\n";
401
-
402
- echo '</tr>'."\n";
403
- echo '<tr>'."\n";
404
-
405
- echo '<td>'."\n";
406
- echo '<input type="password" autocomplete="off" 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";
407
- echo 'Your PDT Identity Token will appear under <em>Profile -› Website Payment Preferences</em> in your PayPal account.'."\n";
408
- echo '</td>'."\n";
409
-
410
- echo '</tr>'."\n";
411
- echo '</tbody>'."\n";
412
- echo '</table>'."\n";
413
-
414
- echo '<div class="ws-menu-page-hr"></div>'."\n";
415
-
416
- echo '<h3 style="margin:0;">More Information (<a href="#" onclick="jQuery(\'div#ws-plugin--s2member-paypal-pdt-details\').toggle(); return false;" class="ws-dotted-link">click here</a>)</h3>'."\n";
417
- echo '<div id="ws-plugin--s2member-paypal-pdt-details" style="display:none;">'."\n";
418
- echo '<p><em><strong>*Quick Tip*</strong> In addition to the <a href="http://www.s2member.com/paypal-pdt-setup" target="_blank" rel="external">default Auto-Return/PDT configuration inside your PayPal account</a>, the Auto-Return URL is also set on a per-transaction basis from within the special PayPal Button Code that s2Member provides you with. In other words, if you have multiple sites operating on one PayPal account, that\'s OK. s2Member dynamically sets the Auto-Return URL for each transaction. The result is that the Auto-Return URL configured from within your PayPal account, becomes the default, which is then overwritten on a per-transaction basis.</em></p>'."\n";
419
- do_action("ws_plugin__s2member_during_paypal_ops_page_during_left_sections_during_paypal_pdt_after_quick_tip", get_defined_vars());
420
- echo '</div>'."\n";
421
-
422
- do_action("ws_plugin__s2member_during_paypal_ops_page_during_left_sections_during_paypal_pdt_after_more_info", get_defined_vars());
423
-
424
- echo '</div>'."\n";
425
-
426
- echo '</div>'."\n";
427
-
428
- do_action("ws_plugin__s2member_during_paypal_ops_page_during_left_sections_after_paypal_pdt", get_defined_vars());
429
- }
430
-
431
- if(apply_filters("ws_plugin__s2member_during_paypal_ops_page_during_left_sections_display_signup_confirmation_email", true, get_defined_vars()))
432
- {
433
- do_action("ws_plugin__s2member_during_paypal_ops_page_during_left_sections_before_signup_confirmation_email", get_defined_vars());
434
-
435
- echo '<div class="ws-menu-page-group" title="Signup Confirmation Email (Standard)">'."\n";
436
-
437
- echo '<div class="ws-menu-page-section ws-plugin--s2member-signup-confirmation-email-section">'."\n";
438
- echo '<h3>Signup Confirmation Email (required, but the default works fine)</h3>'."\n";
439
- 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";
440
- do_action("ws_plugin__s2member_during_paypal_ops_page_during_left_sections_during_signup_confirmation_email", get_defined_vars());
441
-
442
- echo '<table class="form-table">'."\n";
443
- echo '<tbody>'."\n";
444
- echo '<tr>'."\n";
445
-
446
- echo '<th>'."\n";
447
- echo '<label for="ws-plugin--s2member-signup-email-recipients">'."\n";
448
- echo 'Signup Confirmation Recipients:'."\n";
449
- echo '</label>'."\n";
450
- echo '</th>'."\n";
451
-
452
- echo '</tr>'."\n";
453
- echo '<tr>'."\n";
454
-
455
- echo '<td>'."\n";
456
- echo '<input type="text" autocomplete="off" name="ws_plugin__s2member_signup_email_recipients" id="ws-plugin--s2member-signup-email-recipients" value="'.format_to_edit($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["signup_email_recipients"]).'" /><br />'."\n";
457
- echo 'This is a semicolon ( ; ) delimited list of Recipients. Here is an example:<br />'."\n";
458
- echo '<code>"%%full_name%%" &lt;%%payer_email%%&gt;; admin@example.com; "Webmaster" &lt;webmaster@example.com&gt;</code>'."\n";
459
- echo '</td>'."\n";
460
-
461
- echo '</tr>'."\n";
462
- echo '<tr>'."\n";
463
-
464
- echo '<th>'."\n";
465
- echo '<label for="ws-plugin--s2member-signup-email-subject">'."\n";
466
- echo 'Signup Confirmation Email Subject:'."\n";
467
- echo '</label>'."\n";
468
- echo '</th>'."\n";
469
-
470
- echo '</tr>'."\n";
471
- echo '<tr>'."\n";
472
-
473
- echo '<td>'."\n";
474
- echo '<input type="text" autocomplete="off" name="ws_plugin__s2member_signup_email_subject" id="ws-plugin--s2member-signup-email-subject" value="'.format_to_edit($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["signup_email_subject"]).'" /><br />'."\n";
475
- echo 'Subject Line used in the email sent to a Customer after a successful signup has occurred through PayPal.'."\n";
476
- echo '</td>'."\n";
477
-
478
- echo '</tr>'."\n";
479
- echo '<tr>'."\n";
480
-
481
- echo '<th>'."\n";
482
- echo '<label for="ws-plugin--s2member-signup-email-message">'."\n";
483
- echo 'Signup Confirmation Email Message:'."\n";
484
- echo '</label>'."\n";
485
- echo '</th>'."\n";
486
-
487
- echo '</tr>'."\n";
488
- echo '<tr>'."\n";
489
-
490
- echo '<td>'."\n";
491
- echo '<textarea name="ws_plugin__s2member_signup_email_message" id="ws-plugin--s2member-signup-email-message" rows="10">'.format_to_edit($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["signup_email_message"]).'</textarea><br />'."\n";
492
- echo 'Message Body used in the email sent to a Customer after a successful signup has occurred through PayPal.<br /><br />'."\n";
493
- echo '<strong>You can also use these special Replacement Codes if you need them:</strong>'."\n";
494
- echo '<ul class="ws-menu-page-li-margins">'."\n";
495
- echo '<li><code>%%registration_url%%</code> = The full URL (generated by s2Member) where the Customer can get registered.</li>'."\n";
496
- echo '<li><code>%%subscr_id%%</code> = The PayPal Subscription ID, which remains constant throughout any &amp; all future payments. [ <a href="#" onclick="alert(\'There is one exception. If you are selling Lifetime or Fixed-Term (non-recurring) access, using Buy Now functionality; the %%subscr_id%% is actually set to the Transaction ID for the purchase. PayPal does not provide a specific Subscription ID for Buy Now purchases. Since Lifetime &amp; Fixed-Term Subscriptions are NOT recurring (i.e. there is only ONE payment), using the Transaction ID as the Subscription ID is a graceful way to deal with this minor conflict.\'); return false;">?</a> ]</li>'."\n";
497
- echo '<li><code>%%initial%%</code> = The Initial Fee charged during signup. If you offered a 100% Free Trial, this will be <code>0</code>. [ <a href="#" onclick="alert(\'This will always represent the amount of money the Customer spent, whenever they initially signed up, no matter what. If a Customer signs up, under the terms of a 100% Free Trial Period, this will be 0.\'); return false;">?</a> ]</li>'."\n";
498
- echo '<li><code>%%regular%%</code> = The Regular Amount of the Subscription. If you offer something 100% free, this will be <code>0</code>. [ <a href="#" onclick="alert(\'This is how much the Subscription costs after an Initial Period expires. If you did NOT offer an Initial Period at a different price, %%initial%% and %%regular%% will be equal to the same thing.\'); return false;">?</a> ]</li>'."\n";
499
- echo '<li><code>%%recurring%%</code> = This is the amount that will be charged on a recurring basis, or <code>0</code> if non-recurring. [ <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.\'); return false;">?</a> ]</li>'."\n";
500
- echo '<li><code>%%first_name%%</code> = The First Name of the Customer who purchased the Membership Subscription.</li>'."\n";
501
- echo '<li><code>%%last_name%%</code> = The Last Name of the Customer who purchased the Membership Subscription.</li>'."\n";
502
- echo '<li><code>%%full_name%%</code> = The Full Name (First &amp; Last) of the Customer who purchased the Membership Subscription.</li>'."\n";
503
- echo '<li><code>%%payer_email%%</code> = The Email Address of the Customer who purchased the Membership Subscription.</li>'."\n";
504
- echo '<li><code>%%user_ip%%</code> = The Customer\'s IP Address, detected during checkout via <code>$_SERVER["REMOTE_ADDR"]</code>.</li>'."\n";
505
- echo '<li><code>%%item_number%%</code> = The Item Number (colon separated <code><em>level:custom_capabilities:fixed term</em></code>) that the Subscription is for.</li>'."\n";
506
- echo '<li><code>%%item_name%%</code> = The Item Name (as provided by the <code>desc=""</code> attribute in your Shortcode, which briefly describes the Item Number).</li>'."\n";
507
- echo '<li><code>%%initial_term%%</code> = This is the term length of the Initial Period. This will be a numeric value, followed by a space, then a single letter. [ <a href="#" onclick="alert(\'Here are some examples:\\n\\n%%initial_term%% = 1 D (this means 1 Day)\\n%%initial_term%% = 1 W (this means 1 Week)\\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.\'); return false;">?</a> ]</li>'."\n";
508
- echo '<li><code>%%initial_cycle%%</code> = This is the <code>%%initial_term%%</code> from above, converted to a cycle representation of: <code><em>X days/weeks/months/years</em></code>.</li>'."\n";
509
- echo '<li><code>%%regular_term%%</code> = This is the term length of the Regular Period. This will be a numeric value, followed by a space, then a single letter. [ <a href="#" onclick="alert(\'Here are some examples:\\n\\n%%regular_term%% = 1 D (this means 1 Day)\\n%%regular_term%% = 1 W (this means 1 Week)\\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";
510
- echo '<li><code>%%regular_cycle%%</code> = This is the <code>%%regular_term%%</code> from above, converted to a cycle representation of: <code><em>[every] X days/weeks/months/years — OR daily, weekly, bi-weekly, monthly, bi-monthly, quarterly, yearly, or lifetime</em></code>. This is a very useful Replacment Code. Its value is dynamic; depending on term length, recurring status, and period/term lengths configured.</li>'."\n";
511
- echo '<li><code>%%recurring/regular_cycle%%</code> = Example (<code>14.95 / Monthly</code>), or ... (<code>0 / non-recurring</code>); depending on the value of <code>%%recurring%%</code>.</li>'."\n";
512
- echo '</ul>'."\n";
513
-
514
- echo '<strong>Custom Replacement Codes can also be inserted using these instructions:</strong>'."\n";
515
- echo '<ul class="ws-menu-page-li-margins">'."\n";
516
- echo '<li><code>%%cv0%%</code> = The domain of your site, which is passed through the `custom` attribute in your Shortcode.</li>'."\n";
517
- echo '<li><code>%%cv1%%</code> = If you need to track additional custom variables, you can pipe delimit them into the `custom` attribute; inside your Shortcode, like this: <code>custom="'.esc_html($_SERVER["HTTP_HOST"]).'|cv1|cv2|cv3"</code>. You can have an unlimited number of custom variables. Obviously, this is for advanced webmasters; but the functionality has been made available for those who need it.</li>'."\n";
518
- echo '</ul>'."\n";
519
- echo '<strong>This example uses cv1 to record a special marketing campaign:</strong><br />'."\n";
520
- echo '<em>(The campaign (i.e. christmas-promo) could be referenced using <code>%%cv1%%</code>)</em><br />'."\n";
521
- echo '<code>custom="'.esc_html($_SERVER["HTTP_HOST"]).'|christmas-promo"</code>'."\n";
522
-
523
- echo (!is_multisite () || !c_ws_plugin__s2member_utils_conds::is_multisite_farm () || is_main_site ()) ?
524
- '<div class="ws-menu-page-hr"></div>' . "\n".
525
- '<p style="margin:0;"><strong>PHP Code:</strong> It is also possible to use PHP tags — optional (for developers). If you use PHP tags, please run a test email with <code>&lt;?php print_r(get_defined_vars()); ?&gt;</code>. This will give you a full list of all PHP variables available to you in this email. The <code>$paypal</code> variable is the most important one. It contains all of the <code>$_POST</code> variables received from PayPal\'s IPN service — or from an s2Member Pro Form integration (e.g. <code>$paypal["item_number"]</code>, <code>$paypal["item_name"]</code>, etc). Please note that all Replacement Codes will be parsed first, and then any PHP tags that you\'ve included. Also, please remember that emails are sent in plain text format.</p>'."\n"
526
- : '';
527
- echo '</td>'."\n";
528
-
529
- echo '</tr>'."\n";
530
- echo '</tbody>'."\n";
531
- echo '</table>'."\n";
532
- echo '</div>'."\n";
533
-
534
- echo '</div>'."\n";
535
-
536
- do_action("ws_plugin__s2member_during_paypal_ops_page_during_left_sections_after_signup_confirmation_email", get_defined_vars());
537
- }
538
-
539
- if(apply_filters("ws_plugin__s2member_during_paypal_ops_page_during_left_sections_display_modification_confirmation_email", c_ws_plugin__s2member_utils_conds::pro_is_installed(), get_defined_vars()))
540
- {
541
- do_action("ws_plugin__s2member_during_paypal_ops_page_during_left_sections_before_modification_confirmation_email", get_defined_vars());
542
-
543
- echo '<div class="ws-menu-page-group" title="Modification Confirmation Email '.((c_ws_plugin__s2member_utils_conds::pro_is_installed()) ? '(Standard/Pro Form)' : '(Standard)').'">'."\n";
544
-
545
- echo '<div class="ws-menu-page-section ws-plugin--s2member-modification-confirmation-email-section">'."\n";
546
- echo '<h3>Modification Confirmation Email (required, but the default works fine)</h3>'."\n";
547
- echo '<p>This email is sent to existing Users after they complete an upgrade/downgrade (if and when you make this possible). For instance, if a Free Subscriber upgrades to a paid Membership Level, s2Member considers this a Modification (NOT a Signup; a Signup is associated only with someone completely new). The <strong>primary</strong> purpose of this email is to provide the Customer with a confirmation that their account was updated. You may also customize this further by providing details that are specifically geared to your site.</p>'."\n";
548
- do_action("ws_plugin__s2member_during_paypal_ops_page_during_left_sections_during_modification_confirmation_email", get_defined_vars());
549
-
550
- echo '<table class="form-table">'."\n";
551
- echo '<tbody>'."\n";
552
- echo '<tr>'."\n";
553
-
554
- echo '<th>'."\n";
555
- echo '<label for="ws-plugin--s2member-modification-email-recipients">'."\n";
556
- echo 'Modification Confirmation Recipients:'."\n";
557
- echo '</label>'."\n";
558
- echo '</th>'."\n";
559
-
560
- echo '</tr>'."\n";
561
- echo '<tr>'."\n";
562
-
563
- echo '<td>'."\n";
564
- echo '<input type="text" autocomplete="off" name="ws_plugin__s2member_modification_email_recipients" id="ws-plugin--s2member-modification-email-recipients" value="'.format_to_edit($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["modification_email_recipients"]).'" /><br />'."\n";
565
- echo 'This is a semicolon ( ; ) delimited list of Recipients. Here is an example:<br />'."\n";
566
- echo '<code>"%%full_name%%" &lt;%%payer_email%%&gt;; admin@example.com; "Webmaster" &lt;webmaster@example.com&gt;</code>'."\n";
567
- echo '</td>'."\n";
568
-
569
- echo '</tr>'."\n";
570
- echo '<tr>'."\n";
571
-
572
- echo '<th>'."\n";
573
- echo '<label for="ws-plugin--s2member-modification-email-subject">'."\n";
574
- echo 'Modification Confirmation Email Subject:'."\n";
575
- echo '</label>'."\n";
576
- echo '</th>'."\n";
577
-
578
- echo '</tr>'."\n";
579
- echo '<tr>'."\n";
580
-
581
- echo '<td>'."\n";
582
- echo '<input type="text" autocomplete="off" name="ws_plugin__s2member_modification_email_subject" id="ws-plugin--s2member-modification-email-subject" value="'.format_to_edit($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["modification_email_subject"]).'" /><br />'."\n";
583
- echo 'Subject Line used in the email sent to a Customer after a successful modification has occurred through PayPal.'."\n";
584
- echo '</td>'."\n";
585
-
586
- echo '</tr>'."\n";
587
- echo '<tr>'."\n";
588
-
589
- echo '<th>'."\n";
590
- echo '<label for="ws-plugin--s2member-modification-email-message">'."\n";
591
- echo 'Modification Confirmation Email Message:'."\n";
592
- echo '</label>'."\n";
593
- echo '</th>'."\n";
594
-
595
- echo '</tr>'."\n";
596
- echo '<tr>'."\n";
597
-
598
- echo '<td>'."\n";
599
- echo '<textarea name="ws_plugin__s2member_modification_email_message" id="ws-plugin--s2member-modification-email-message" rows="10">'.format_to_edit($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["modification_email_message"]).'</textarea><br />'."\n";
600
- echo 'Message Body used in the email sent to a Customer after a successful modification has occurred through PayPal.<br /><br />'."\n";
601
- echo '<strong>You can also use these special Replacement Codes if you need them:</strong>'."\n";
602
- echo '<ul class="ws-menu-page-li-margins">'."\n";
603
- echo '<li><code>%%subscr_id%%</code> = The PayPal Subscription I
1
  <?php
2
  /**
3
+ * Menu page for the s2Member plugin (PayPal Options page).
4
+ *
5
+ * Copyright: © 2009-2011
6
+ * {@link http://www.websharks-inc.com/ WebSharks, Inc.}
7
+ * (coded in the USA)
8
+ *
9
+ * Released under the terms of the GNU General Public License.
10
+ * You should have received a copy of the GNU General Public License,
11
+ * along with this software. In the main directory, see: /licensing/
12
+ * If not, see: {@link http://www.gnu.org/licenses/}.
13
+ *
14
+ * @package s2Member\Menu_Pages
15
+ * @since 3.0
16
+ */
17
  if(realpath(__FILE__) === realpath($_SERVER["SCRIPT_FILENAME"]))
18
  exit("Do not access this file directly.");
19
 
20
  if(!class_exists("c_ws_plugin__s2member_menu_page_paypal_ops"))
21
+ {
22
+ /**
23
+ * Menu page for the s2Member plugin (PayPal Options page).
24
+ *
25
+ * @package s2Member\Menu_Pages
26
+ * @since 110531
27
+ */
28
+ class c_ws_plugin__s2member_menu_page_paypal_ops
29
  {
30
+ public function __construct()
31
+ {
32
+ echo '<div class="wrap ws-menu-page">'."\n";
33
+
34
+ echo '<div class="ws-menu-page-toolbox">'."\n";
35
+ c_ws_plugin__s2member_menu_pages_tb::display();
36
+ echo '</div>'."\n";
37
+
38
+ echo '<h2>PayPal Options</h2>'."\n";
39
+
40
+ echo '<table class="ws-menu-page-table">'."\n";
41
+ echo '<tbody class="ws-menu-page-table-tbody">'."\n";
42
+ echo '<tr class="ws-menu-page-table-tr">'."\n";
43
+ echo '<td class="ws-menu-page-table-l">'."\n";
44
+
45
+ echo '<form method="post" name="ws_plugin__s2member_options_form" id="ws-plugin--s2member-options-form">'."\n";
46
+ 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";
47
+ echo '<input type="hidden" name="ws_plugin__s2member_configured" id="ws-plugin--s2member-configured" value="1" />'."\n";
48
+
49
+ do_action("ws_plugin__s2member_during_paypal_ops_page_before_left_sections", get_defined_vars());
50
+
51
+ if(apply_filters("ws_plugin__s2member_during_paypal_ops_page_during_left_sections_display_paypal_account_details", TRUE, get_defined_vars()))
52
  {
53
+ do_action("ws_plugin__s2member_during_paypal_ops_page_during_left_sections_before_paypal_account_details", get_defined_vars());
54
+
55
+ echo '<div class="ws-menu-page-group" title="PayPal Account Details">'."\n";
56
+
57
+ echo '<div class="ws-menu-page-section ws-plugin--s2member-paypal-account-details-section">'."\n";
58
+ echo '<a href="http://www.s2member.com/paypal" target="_blank"><img src="'.esc_attr($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["dir_url"]).'/images/paypal-logo.png" class="ws-menu-page-right" style="width:125px; height:125px; border:0;" alt="." /></a>'."\n";
59
+ echo '<h3>PayPal Account Details (required, if using PayPal)</h3>'."\n";
60
+ echo '<p>This plugin works in conjunction with <a href="http://www.s2member.com/paypal" target="_blank" rel="external">PayPal Website Payments Standard</a>, for businesses. You do NOT need a PayPal Pro account. You just need to upgrade your Personal PayPal account to a Business status, which is free. A PayPal account can be <a href="http://pages.ebay.com/help/buy/questions/upgrade-paypal-account.html" target="_blank" rel="external">upgraded</a> from a Personal account to a Business account, simply by going to the `Profile` button under the `My Account` tab, selecting the `Personal Business Information` button, and then clicking the `Upgrade Your Account` button. <strong>See also:</strong> This KB article: <a href="http://www.s2member.com/kb/paypal-account-types/" target="_blank" rel="external">PayPal Compatibility (Account Types)</a>.</p>'."\n";
61
+ echo '<p><em><strong>*PayPal API Credentials*</strong> Once you have a PayPal Business account, you\'ll need access to your <a href="http://www.s2member.com/paypal-profile-api-access" target="_blank" rel="external">PayPal API Credentials</a>. Log into your PayPal account, and navigate to <code>Profile -› API Access (or Request API Credentials)</code>. You\'ll choose <code>(PayPal / Request API Signature)</code>.</em></p>'."\n";
62
+ do_action("ws_plugin__s2member_during_paypal_ops_page_during_left_sections_during_paypal_account_details", get_defined_vars());
63
+
64
+ echo '<table class="form-table">'."\n";
65
+ echo '<tbody>'."\n";
66
+ echo '<tr>'."\n";
67
+
68
+ echo '<th>'."\n";
69
+ echo '<label for="ws-plugin--s2member-paypal-merchant-id">'."\n";
70
+ echo 'Your PayPal Merchant ID:'."\n";
71
+ echo '</label>'."\n";
72
+ echo '</th>'."\n";
73
+
74
+ echo '</tr>'."\n";
75
+ echo '<tr>'."\n";
76
+
77
+ echo '<td>'."\n";
78
+ echo '<input type="text" autocomplete="off" name="ws_plugin__s2member_paypal_merchant_id" id="ws-plugin--s2member-paypal-merchant-id" value="'.format_to_edit($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["paypal_merchant_id"]).'" /><br />'."\n";
79
+ echo 'At PayPal, see: <code>Profile -› Secure Merchant ID</code>.'."\n";
80
+ echo '</td>'."\n";
81
+
82
+ echo '</tr>'."\n";
83
+ echo '<tr>'."\n";
84
+
85
+ echo '<th>'."\n";
86
+ echo '<label for="ws-plugin--s2member-paypal-business">'."\n";
87
+ echo 'Your PayPal EMail Address:'."\n";
88
+ echo '</label>'."\n";
89
+ echo '</th>'."\n";
90
+
91
+ echo '</tr>'."\n";
92
+ echo '<tr>'."\n";
93
+
94
+ echo '<td>'."\n";
95
+ echo '<input type="text" autocomplete="off" name="ws_plugin__s2member_paypal_business" id="ws-plugin--s2member-paypal-business" value="'.format_to_edit($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["paypal_business"]).'" /><br />'."\n";
96
+ echo 'At PayPal, see: <code>Profile -› Email Accounts</code>.'."\n";
97
+ echo '</td>'."\n";
98
+
99
+ echo '</tr>'."\n";
100
+ echo '</tbody>'."\n";
101
+ echo '</table>'."\n";
102
+
103
+ echo '<div class="ws-menu-page-hr"></div>'."\n";
104
+
105
+ echo '<table class="form-table">'."\n";
106
+ echo '<tbody>'."\n";
107
+ echo '<tr>'."\n";
108
+
109
+ echo '<th>'."\n";
110
+ echo '<label for="ws-plugin--s2member-paypal-api-username">'."\n";
111
+ echo 'Your PayPal API Username:'."\n";
112
+ echo '</label>'."\n";
113
+ echo '</th>'."\n";
114
+
115
+ echo '</tr>'."\n";
116
+ echo '<tr>'."\n";
117
+
118
+ echo '<td>'."\n";
119
+ echo '<input type="text" autocomplete="off" name="ws_plugin__s2member_paypal_api_username" id="ws-plugin--s2member-paypal-api-username" value="'.format_to_edit($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["paypal_api_username"]).'" /><br />'."\n";
120
+ echo 'At PayPal, see: <code>Profile -› API Access (or Request API Credentials)</code>.'."\n";
121
+ echo '</td>'."\n";
122
+
123
+ echo '</tr>'."\n";
124
+ echo '<tr>'."\n";
125
+
126
+ echo '<th>'."\n";
127
+ echo '<label for="ws-plugin--s2member-paypal-api-password">'."\n";
128
+ echo 'Your PayPal API Password:'."\n";
129
+ echo '</label>'."\n";
130
+ echo '</th>'."\n";
131
+
132
+ echo '</tr>'."\n";
133
+ echo '<tr>'."\n";
134
+
135
+ echo '<td>'."\n";
136
+ echo '<input type="password" autocomplete="off" name="ws_plugin__s2member_paypal_api_password" id="ws-plugin--s2member-paypal-api-password" value="'.format_to_edit($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["paypal_api_password"]).'" /><br />'."\n";
137
+ echo 'At PayPal, see: <code>Profile -› API Access (or Request API Credentials)</code>.'."\n";
138
+ echo '</td>'."\n";
139
+
140
+ echo '</tr>'."\n";
141
+ echo '<tr>'."\n";
142
+
143
+ echo '<th>'."\n";
144
+ echo '<label for="ws-plugin--s2member-paypal-api-signature">'."\n";
145
+ echo 'Your PayPal API Signature:'."\n";
146
+ echo '</label>'."\n";
147
+ echo '</th>'."\n";
148
+
149
+ echo '</tr>'."\n";
150
+ echo '<tr>'."\n";
151
+
152
+ echo '<td>'."\n";
153
+ echo '<input type="password" autocomplete="off" name="ws_plugin__s2member_paypal_api_signature" id="ws-plugin--s2member-paypal-api-signature" value="'.format_to_edit($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["paypal_api_signature"]).'" /><br />'."\n";
154
+ echo 'At PayPal, see: <code>Profile -› API Access (or Request API Credentials)</code>.'."\n";
155
+ echo '</td>'."\n";
156
+
157
+ echo '</tr>'."\n";
158
+ do_action("ws_plugin__s2member_during_paypal_ops_page_during_left_sections_during_paypal_account_detail_rows", get_defined_vars());
159
+
160
+ echo '</tbody>'."\n";
161
+ echo '</table>'."\n";
162
 
163
+ echo '<div class="ws-menu-page-hr"></div>'."\n";
164
+
165
+ echo '<table class="form-table" style="margin:0;">'."\n";
166
+ echo '<tbody>'."\n";
167
+ echo '<tr>'."\n";
168
+
169
+ echo '<th style="padding-top:0;">'."\n";
170
+ echo '<label for="ws-plugin--s2member-paypal-sandbox">'."\n";
171
+ echo 'Developer/Sandbox Testing?'."\n";
172
+ echo '</label>'."\n";
173
+ echo '</th>'."\n";
174
 
175
+ echo '</tr>'."\n";
176
+ echo '<tr>'."\n";
177
+
178
+ echo '<td>'."\n";
179
+ 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";
180
+ echo '<em>Only enable this if you\'ve provided Sandbox credentials above.<br />This puts the API, IPN, PDT and Form/Button Generators all into Sandbox mode.<br />See: <a href="http://www.s2member.com/paypal-developers" target="_blank" rel="external">PayPal Developers</a></em>'."\n";
181
+ echo '</td>'."\n";
182
 
183
+ echo '</tr>'."\n";
184
+ echo '<tr>'."\n";
185
+
186
+ echo '<th>'."\n";
187
+ echo '<label for="ws-plugin--s2member-paypal-btn-encryption">'."\n";
188
+ echo 'Enable Button Encryption?'."\n";
189
+ echo '</label>'."\n";
190
+ echo '</th>'."\n";
191
 
192
+ echo '</tr>'."\n";
193
+ echo '<tr>'."\n";
 
 
 
 
194
 
195
+ echo '<td>'."\n";
196
+ echo '<input type="radio" name="ws_plugin__s2member_paypal_btn_encryption" id="ws-plugin--s2member-paypal-btn-encryption-0" value="0"'.((!$GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["paypal_btn_encryption"]) ? ' checked="checked"' : '').' /> <label for="ws-plugin--s2member-paypal-btn-encryption-0">No</label> &nbsp;&nbsp;&nbsp; <input type="radio" name="ws_plugin__s2member_paypal_btn_encryption" id="ws-plugin--s2member-paypal-btn-encryption-1" value="1"'.(($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["paypal_btn_encryption"]) ? ' checked="checked"' : '').' /> <label for="ws-plugin--s2member-paypal-btn-encryption-1">Yes, enable PayPal Button encryption.</label><br />'."\n";
197
+ echo '<em>If enabled, all of your PayPal Button Shortcodes will produce *encrypted* PayPal Buttons. This improves security against fraudulent transactions. For extra security, you should update your PayPal account too, under: <code>My Profile -› Website Payment Preferences</code>. You\'ll want to block all non-encrypted payments. <strong>*Note*</strong> this will NOT work until you\'ve supplied s2Member with your PayPal Email Address, and also with your API Username/Password/Signature.</em>'."\n";
198
+ echo '</td>'."\n";
199
 
200
+ echo '</tr>'."\n";
 
 
 
 
 
 
 
201
 
202
+ if(!is_multisite() || !c_ws_plugin__s2member_utils_conds::is_multisite_farm() || is_main_site())
203
+ {
204
+ echo '<tr>'."\n";
205
+
206
+ echo '<th>'."\n";
207
+ echo '<label for="ws-plugin--s2member-gateway-debug-logs">'."\n";
208
+ echo 'Enable Logging Routines?'."\n";
209
+ echo '</label>'."\n";
210
+ echo '</th>'."\n";
211
 
212
+ echo '</tr>'."\n";
213
+ echo '<tr>'."\n";
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
214
 
215
+ echo '<td>'."\n";
216
+ echo '<input type="radio" name="ws_plugin__s2member_gateway_debug_logs" id="ws-plugin--s2member-gateway-debug-logs-0" value="0"'.((!$GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["gateway_debug_logs"]) ? ' checked="checked"' : '').' /> <label for="ws-plugin--s2member-gateway-debug-logs-0">No</label> &nbsp;&nbsp;&nbsp; <input type="radio" name="ws_plugin__s2member_gateway_debug_logs" id="ws-plugin--s2member-gateway-debug-logs-1" value="1"'.(($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["gateway_debug_logs"]) ? ' checked="checked"' : '').' /> <label for="ws-plugin--s2member-gateway-debug-logs-1">Yes, enable debugging, with API, IPN &amp; Return Page logging.</label><br />'."\n";
217
+ echo '<em>This enables API, IPN and Return Page logging. The log files are stored here: <code>'.esc_html(c_ws_plugin__s2member_utils_dirs::doc_root_path($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["logs_dir"])).'</code></em><br />'."\n";
218
+ echo '<em class="ws-menu-page-hilite">If you have any trouble, please review your s2Member log files for problems. See: <a href="'.esc_attr(admin_url("/admin.php?page=ws-plugin--s2member-logs")).'">Log Viewer</a></em>'."\n";
219
+ echo '</td>'."\n";
220
 
221
+ echo '</tr>'."\n";
222
+ echo '<tr>'."\n";
 
223
 
224
+ echo '<td>'."\n";
225
+ echo '<div class="info" style="margin-bottom:0;">'."\n";
226
+ echo '<p style="font-size:110%; margin-top:0;"><span>We HIGHLY recommend that you enable logging during your initial testing phase. Logs produce lots of useful details that can help in debugging. Logs can help you find issues in your configuration and/or problems during payment processing. See: <a href="'.esc_attr(admin_url("/admin.php?page=ws-plugin--s2member-logs")).'">Log Files (Debug)</a>.</span></p>'."\n";
227
+ echo '<p style="font-size:110%; margin-bottom:0;"><span class="ws-menu-page-error">However, it is VERY IMPORTANT to disable logging once you go live. Log files may contain personally identifiable information, credit card numbers, secret API credentials, passwords and/or other sensitive information. We STRONGLY suggest that logging be disabled on a live site (for security reasons).</span></p>'."\n";
228
+ echo '</div>'."\n";
229
+ echo '</td>'."\n";
230
 
231
+ echo '</tr>'."\n";
232
+ }
233
+ echo '</tbody>'."\n";
234
+ echo '</table>'."\n";
235
+
236
+ echo '<div class="ws-menu-page-hr"></div>'."\n";
237
+
238
+ echo '<p><em><strong>*Sandbox Tip*</strong> If you\'re testing your site through a PayPal Sandbox account, please remember that Email Confirmations from s2Member will NOT be received after a test purchase. s2Member sends its Confirmation Emails to the PayPal Email Address of the Customer. Since PayPal Sandbox addresses are usually bogus (for testing), you will have to run live transactions before Email Confirmations from s2Member are received. That being said, all other s2Member functionality CAN be tested through a PayPal Sandbox account. Email Confirmations are the only hang-up.</em></p>'."\n";
239
+ do_action("ws_plugin__s2member_during_paypal_ops_page_during_left_sections_during_paypal_account_details_after_sandbox_tip", get_defined_vars());
240
+ echo '</div>'."\n";
241
+
242
+ echo '</div>'."\n";
243
+
244
+ do_action("ws_plugin__s2member_during_paypal_ops_page_during_left_sections_after_paypal_account_details", get_defined_vars());
245
+ }
246
+
247
+ if(apply_filters("ws_plugin__s2member_during_paypal_ops_page_during_left_sections_display_paypal_payflow_account_details", c_ws_plugin__s2member_utils_conds::pro_is_installed(), get_defined_vars()))
248
+ {
249
+ do_action("ws_plugin__s2member_during_paypal_ops_page_during_left_sections_before_paypal_payflow_account_details", get_defined_vars());
250
+
251
+ echo '<div class="ws-menu-page-group" title="Payflow Account Details">'."\n";
252
+
253
+ echo '<div class="ws-menu-page-section ws-plugin--s2member-paypal-payflow-account-details-section">'."\n";
254
+ echo '<a href="http://www.s2member.com/paypal" target="_blank"><img src="'.esc_attr($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["dir_url"]).'/images/paypal-logo.png" class="ws-menu-page-right" style="width:125px; height:125px; border:0;" alt="." /></a>'."\n";
255
+ echo '<h3>Payflow Account Details (required, if using Payflow)</h3>'."\n";
256
+ echo '<p>Newer PayPal Pro accounts come with the Payflow API for Recurring Billing service. If you have a newer PayPal Pro account, and you wish to integrate PayPal\'s Recurring Billing service with s2Member Pro Forms, you will need to fill in the details here. Providing Payflow API Credentials here, automatically puts s2Member\'s Recurring Billing integration through Pro Forms, into Payflow mode. Just fill in the details below, and you\'re ready to generate Pro Forms that charge customers on a recurring basis. s2Member will use the Payflow API instead of the standard PayPal Pro API, which is being slowly phased out in favor of Payflow.</p>'."\n";
257
+ echo '<p><em><strong>*Payflow API Credentials*</strong> Once you have a PayPal Pro account, you\'ll need access to your <a href="http://www.s2member.com/paypal-profile-api-access" target="_blank" rel="external">Payflow API Credentials</a>. Log into your PayPal account, and navigate to <code>Profile -› API Access (or Request API Credentials)</code>. You\'ll choose <code>(Payflow / API Access)</code>.</em></p>'."\n";
258
+ echo '<p><em><strong>*Important Note*</strong> s2Member always uses the PayPal Pro API. It can also use the Payflow API (if details are supplied here). But please note... supplying Payflow API Credentials here, does NOT mean you can bypass other sections. Please supply s2Member with ALL of your PayPal account details.</em></p>'."\n";
259
+ echo '<p><strong>See also:</strong> This KB article: <a href="http://www.s2member.com/kb/paypal-pro-payflow-edition/" target="_blank" rel="external">PayPal Pro (PayFlow Edition)</a>.</p>'."\n";
260
+ do_action("ws_plugin__s2member_during_paypal_ops_page_during_left_sections_during_paypal_payflow_account_details", get_defined_vars());
261
+
262
+ echo '<table class="form-table">'."\n";
263
+ echo '<tbody>'."\n";
264
+ echo '<tr>'."\n";
265
+
266
+ echo '<th>'."\n";
267
+ echo '<label for="ws-plugin--s2member-paypal-payflow-api-username">'."\n";
268
+ echo 'Your Payflow API Username:'."\n";
269
+ echo '</label>'."\n";
270
+ echo '</th>'."\n";
271
+
272
+ echo '</tr>'."\n";
273
+ echo '<tr>'."\n";
274
+
275
+ echo '<td>'."\n";
276
+ echo '<input type="text" autocomplete="off" name="ws_plugin__s2member_paypal_payflow_api_username" id="ws-plugin--s2member-paypal-payflow-api-username" value="'.format_to_edit($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["paypal_payflow_api_username"]).'" /><br />'."\n";
277
+ echo 'At PayPal, see: <code>Profile -› API Access (or Request API Credentials) -› Payflow API Access</code>.'."\n";
278
+ echo '</td>'."\n";
279
+
280
+ echo '</tr>'."\n";
281
+ echo '<tr>'."\n";
282
+
283
+ echo '<th>'."\n";
284
+ echo '<label for="ws-plugin--s2member-paypal-payflow-api-password">'."\n";
285
+ echo 'Your Payflow API Password:'."\n";
286
+ echo '</label>'."\n";
287
+ echo '</th>'."\n";
288
+
289
+ echo '</tr>'."\n";
290
+ echo '<tr>'."\n";
291
+
292
+ echo '<td>'."\n";
293
+ echo '<input type="password" autocomplete="off" name="ws_plugin__s2member_paypal_payflow_api_password" id="ws-plugin--s2member-paypal-payflow-api-password" value="'.format_to_edit($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["paypal_payflow_api_password"]).'" /><br />'."\n";
294
+ echo 'At PayPal, see: <code>Profile -› API Access (or Request API Credentials) -› Payflow API Access</code>.'."\n";
295
+ echo '</td>'."\n";
296
+
297
+ echo '</tr>'."\n";
298
+ echo '<tr>'."\n";
299
+
300
+ echo '<th>'."\n";
301
+ echo '<label for="ws-plugin--s2member-paypal-payflow-api-partner">'."\n";
302
+ echo 'Your Payflow API Partner:'."\n";
303
+ echo '</label>'."\n";
304
+ echo '</th>'."\n";
305
+
306
+ echo '</tr>'."\n";
307
+ echo '<tr>'."\n";
308
+
309
+ echo '<td>'."\n";
310
+ echo '<input type="text" name="ws_plugin__s2member_paypal_payflow_api_partner" id="ws-plugin--s2member-paypal-payflow-api-partner" value="'.format_to_edit($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["paypal_payflow_api_partner"]).'" /><br />'."\n";
311
+ echo 'At PayPal, see: <code>Profile -› API Access (or Request API Credentials) -› Payflow API Access</code>.'."\n";
312
+ echo '</td>'."\n";
313
+
314
+ echo '</tr>'."\n";
315
+ echo '<tr>'."\n";
316
+
317
+ echo '<th>'."\n";
318
+ echo '<label for="ws-plugin--s2member-paypal-payflow-api-vendor">'."\n";
319
+ echo 'Your Payflow API Vendor:'."\n";
320
+ echo '</label>'."\n";
321
+ echo '</th>'."\n";
322
+
323
+ echo '</tr>'."\n";
324
+ echo '<tr>'."\n";
325
+
326
+ echo '<td>'."\n";
327
+ echo '<input type="text" name="ws_plugin__s2member_paypal_payflow_api_vendor" id="ws-plugin--s2member-paypal-payflow-api-vendor" value="'.format_to_edit($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["paypal_payflow_api_vendor"]).'" /><br />'."\n";
328
+ echo 'At PayPal, see: <code>Profile -› API Access (or Request API Credentials) -› Payflow API Access</code>.'."\n";
329
+ echo '</td>'."\n";
330
+
331
+ echo '</tr>'."\n";
332
+ do_action("ws_plugin__s2member_during_paypal_ops_page_during_left_sections_during_paypal_payflow_account_detail_rows", get_defined_vars());
333
+ echo '</tbody>'."\n";
334
+ echo '</table>'."\n";
335
+ echo '</div>'."\n";
336
+
337
+ echo '</div>'."\n";
338
+
339
+ do_action("ws_plugin__s2member_during_paypal_ops_page_during_left_sections_after_paypal_payflow_account_details", get_defined_vars());
340
+ }
341
+
342
+ if(apply_filters("ws_plugin__s2member_during_paypal_ops_page_during_left_sections_display_paypal_ipn", TRUE, get_defined_vars()))
343
+ {
344
+ do_action("ws_plugin__s2member_during_paypal_ops_page_during_left_sections_before_paypal_ipn", get_defined_vars());
345
+
346
+ echo '<div class="ws-menu-page-group" title="PayPal IPN Integration">'."\n";
347
+
348
+ echo '<div class="ws-menu-page-section ws-plugin--s2member-paypal-ipn-section">'."\n";
349
+ echo '<h3>PayPal IPN / Instant Payment Notifications (required, please enable)</h3>'."\n";
350
+ echo '<p>Log into your PayPal account and navigate to this section:<br /><code>Account Profile -› Instant Payment Notification Preferences</code></p>'."\n";
351
+ echo '<p>Edit your IPN settings &amp; turn IPN Notifications: <strong><code>On</code></strong></p>'."\n";
352
+ echo '<p>You\'ll need your IPN URL, which is:<br /><code>'.esc_html(home_url("/?s2member_paypal_notify=1")).'</code></p>'."\n";
353
+ do_action("ws_plugin__s2member_during_paypal_ops_page_during_left_sections_during_paypal_ipn", get_defined_vars());
354
+
355
+ echo '<h3 style="margin:0;">More Information (<a href="#" onclick="jQuery(\'div#ws-plugin--s2member-paypal-ipn-details\').toggle(); return false;" class="ws-dotted-link">click here</a>)</h3>'."\n";
356
+ echo '<div id="ws-plugin--s2member-paypal-ipn-details" style="display:none;">'."\n";
357
+ echo '<p><em><strong>*Quick Tip*</strong> In addition to the <a href="http://www.s2member.com/paypal-ipn-setup" target="_blank" rel="external">default IPN settings inside your PayPal account</a>, the IPN URL is also set on a per-transaction basis by the special PayPal Button Code that s2Member provides you with. In other words, if you have multiple sites operating on one PayPal account, that\'s OK. s2Member dynamically sets the IPN URL for each transaction. The result is that the IPN URL configured from within your PayPal account, becomes the default, which is then overwritten on a per-transaction basis. In fact, PayPal recently updated their system to support IPN URL preservation. One PayPal account can handle multiple sites, all using different IPN URLs.</em></p>'."\n";
358
+ do_action("ws_plugin__s2member_during_paypal_ops_page_during_left_sections_during_paypal_ipn_after_quick_tip", get_defined_vars());
359
+ echo '<p><em><strong>*IPN Communications*</strong> You\'ll be happy to know that s2Member handles cancellations, expirations, failed payments, terminations (e.g. refunds &amp; chargebacks) for you automatically. If you log into your PayPal account and cancel a Member\'s Subscription, or, if the Member logs into their PayPal account and cancels their own Subscription, s2Member will be notified of these important changes and react accordingly through the PayPal IPN service that runs silently behind-the-scene. The PayPal IPN service will notify s2Member whenever a Member\'s payments have been failing, and/or whenever a Member\'s Subscription has expired for any reason. Even refunds &amp; chargeback reversals are supported through the IPN service. If you issue a refund to an unhappy Customer through PayPal, s2Member will be notified, and the account for that Customer will either be demoted to a Free Subscriber, or deleted automatically (based on your configuration). The communication from PayPal -› s2Member is seamless.</em></p>'."\n";
360
+ echo '</div>'."\n";
361
+
362
+ echo '<div class="ws-menu-page-hr"></div>'."\n";
363
+
364
+ echo '<h3 style="margin:0;">IPN w/ Proxy Key (<a href="#" onclick="jQuery(\'div#ws-plugin--s2member-paypal-ipn-proxy-details\').toggle(); return false;" class="ws-dotted-link">optional, for 3rd-party integrations</a>)</h3>'."\n";
365
+ echo '<div id="ws-plugin--s2member-paypal-ipn-proxy-details" style="display:none;">'."\n";
366
+ echo '<p>If you\'re using a 3rd-party application that needs to POST simulated IPN transactions to your s2Member installation, you can use this alternate IPN URL, which includes a Proxy Key. This encrypted Proxy Key verifies incoming data being received by s2Member\'s IPN processor. You can change <em>[proxy-gateway]</em> to whatever you like. The <em>[proxy-gateway]</em> value is required. It will be stored by s2Member as the Customer\'s Paid Subscr. Gateway. Your [proxy-gateway] value will also be reflected in s2Member\'s IPN log.</p>'."\n";
367
+ echo '<input type="text" autocomplete="off" value="'.format_to_edit(home_url("/?s2member_paypal_notify=1&s2member_paypal_proxy=[proxy-gateway]&s2member_paypal_proxy_verification=".urlencode(c_ws_plugin__s2member_paypal_utilities::paypal_proxy_key_gen()))).'" style="width:99%;" />'."\n";
368
+ echo '<p><em>Any 3rd-party application that is sending IPN transactions to your s2Member installation, must ALWAYS include the <code>custom</code> POST variable, and that variable must always start with your installation domain (i.e. custom=<code>'.esc_html($_SERVER["HTTP_HOST"]).'</code>). In addition, the <code>item_number</code> variable, must always match a format that s2Member looks for. Generally speaking, the <code>item_number</code> should be <code>1, 2, 3, or 4</code>, indicating a specific s2Member Level #. However, s2Member also uses some advanced formats in this field. Just to be sure, we suggest creating a PayPal Button with the s2Member Button Generator, and then taking a look at the Full Button Code to see how s2Member expects <code>item_number</code> to be formatted. Other than the aforementioned exceptions; all other POST variables should follow PayPal standards. Please see: <a href="http://www.s2member.com/paypal-ipn-pdt-vars" target="_blank" rel="external">PayPal\'s IPN/PDT reference guide</a> for full documentation.</em></p>'."\n";
369
+ do_action("ws_plugin__s2member_during_paypal_ops_page_during_left_sections_during_paypal_ipn_after_proxy", get_defined_vars());
370
+ echo '</div>'."\n";
371
+ echo '</div>'."\n";
372
+
373
+ echo '</div>'."\n";
374
+
375
+ do_action("ws_plugin__s2member_during_paypal_ops_page_during_left_sections_after_paypal_ipn", get_defined_vars());
376
+ }
377
 
378
+ if(apply_filters("ws_plugin__s2member_during_paypal_ops_page_during_left_sections_display_paypal_pdt", TRUE, get_defined_vars()))
379
+ {
380
+ do_action("ws_plugin__s2member_during_paypal_ops_page_during_left_sections_before_paypal_pdt", get_defined_vars());
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
381
 
382
+ echo '<div class="ws-menu-page-group" title="PayPal PDT/Auto-Return Integration">'."\n";
 
 
 
 
383
 
384
+ echo '<div class="ws-menu-page-section ws-plugin--s2member-paypal-pdt-section">'."\n";
385
+ echo '<h3>PayPal PDT Identity Token (required, please enable)</h3>'."\n";
386
+ echo '<p>Log into your PayPal account and navigate to this section:<br /><code>Account Profile -› Website Payment Preferences</code></p>'."\n";
387
+ echo '<p>Turn the Auto-Return feature: <strong><code>On</code></strong></p>'."\n";
388
+ echo '<p>You\'ll need your <a href="'.esc_attr(home_url("/?s2member_paypal_return=1&s2member_paypal_proxy=paypal&s2member_paypal_proxy_use=x-preview")).'" target="_blank" rel="external">Auto-Return URL</a>, which is:<br /><code>'.esc_html(home_url("/?s2member_paypal_return=1")).'</code></p>'."\n";
389
+ 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";
390
+ do_action("ws_plugin__s2member_during_paypal_ops_page_during_left_sections_during_paypal_pdt", get_defined_vars());
391